The tasks build the inference path: emsha-backed SHA-256, inferproxy, config, a hand-written HTTP and SSE client, request building, delta assembly, the chat state machine, the thinking cap, the slot gate with retry, the startup self-test and on-device verification. Everything the tasks copy in was checked against a private reference implementation: the gate passes after each task in order, the timing tests pass repeatedly under CPU load, and the reference passes the self-test and all four device checks on straylight. Expected results for the recorded streams were derived by a separate script. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
3.9 KiB
M2a task 01: SHA-256 in proto
Branch: m2a (create it from master: git switch master && git switch -c m2a)
Commit subject: Add SHA-256 to proto, wrapping the emsha crate
Goal
Give the workspace one SHA-256 function. It wraps the emsha crate, which the project's owner
wrote. Nothing else in the workspace may use emsha directly, so that the choice of implementation
stays in one file.
Context
The hash is used to check that the inference server runs the chat template we expect, and later
for the audit log. An earlier release of emsha hashed every message of 63, 127, 191, … bytes
wrongly, because of a mistake at a padding boundary. That is fixed in 1.0.4, and it is why the test
file checks lengths on both sides of every boundary and feeds each message in two pieces.
Files
- Copy:
crates/proto/tests/hash.rs - Create:
crates/proto/src/hash.rs - Modify:
Cargo.toml,crates/proto/Cargo.toml,crates/proto/src/lib.rs,docs/dependencies.md,docs/implementer-log.md,Cargo.lock(generated)
Interfaces
Consumes: proto::Hash32 (Hash32::from_bytes([u8; 32])).
Produces, in crates/proto/src/hash.rs, re-exported from the crate root:
pub struct HashError; // Debug, Clone, Copy, PartialEq, Eq; Display; std::error::Error
pub struct Sha256(/* private */);
impl Sha256 {
pub fn new() -> Self;
pub fn update(&mut self, data: &[u8]) -> Result<(), HashError>; // may be called many times
pub fn finish(self) -> Result<Hash32, HashError>;
}
impl Default for Sha256 { /* same as new() */ }
pub fn sha256(data: &[u8]) -> Result<Hash32, HashError>; // new, update, finish
Every emsha error becomes HashError. No unwrap or expect.
API notes (emsha 1.0.4, read from its source on 2026-09-17)
use emsha::Hash; // the trait that has update and finalize
let mut h = emsha::sha256::SHA256::new();
h.update(b"bytes")?; // fn update(&mut self, msg: &[u8]) -> emsha::Result<()>
let mut out = [0u8; emsha::sha256::SIZE]; // SIZE is 32
h.finalize(&mut out)?; // fn finalize(&mut self, digest: &mut [u8]) -> emsha::Result<()>
emsha::Result<T> is Result<T, emsha::Error>. The crate has no dependencies and is no_std.
Steps
- 1. Branch, copy the test, add the dependency.
git switch master && git switch -c m2a
cp docs/plans/M2a/files/crates/proto/tests/hash.rs crates/proto/tests/
Add to [workspace.dependencies] in the root Cargo.toml: emsha = "1.0.4".
Add to [dependencies] in crates/proto/Cargo.toml: emsha.workspace = true.
Add this row to docs/dependencies.md:
| `emsha` | 1.0.4 | `proto` | SHA-256. Written by the owner; no dependencies, no `unsafe`. Checked against `sha256sum` on 3,204 inputs. |
-
2. See the test fail.
cargo test -p proto --test hash. Expected: it does not compile. -
3. Write
hash.rs, and inlib.rsaddpub mod hash;andpub use hash::{HashError, Sha256, sha256};. Runcargo fmt --all. -
4. See the test pass.
cargo test -p proto --test hash. Expected:4 passed. -
5. Run the gate.
cargo build, thenmake gate. Expected last line:gate: ok.cargo denyprints ano-license-fieldwarning foremsha; that is expected, because the crate's licence is a file and not an SPDX name. Do not editdeny.toml. -
6. Log and commit.
git add Cargo.toml Cargo.lock crates/proto docs/dependencies.md docs/implementer-log.md
git commit
Done when
cargo test -p proto --test hashreports 4 passed;make gateprintsgate: ok.grep -rn emsha crates/*/srcshowscrates/proto/src/hash.rsonly.
Stop and report if
- A vector in
hash.rsfails. Do not change the vector: it would meanemshais wrong again. cargo denyreports an error, not a warning, foremsha.