Covers what the guarantees mean in practice, the two deliberate departures from architecture/generic.md §1, how to run it locally, the deployment topology, and how to run both test suites. CLAUDE.md records the invariants that are easy to break silently -- header replay, redirect handling, write ordering, and completing a response before its manifest write lands -- since each of those was a real bug rather than a hypothetical one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XZG2i4AmfSqE97EJGBVb64
2.6 KiB
rustingface — notes for agents
Read doc/spec.md first; it is the contract, not a sketch. Then
read ~/git/architecture/generic.md for the conventions this repo inherits
(workspace layout, deployment, systemd, firewalld, SELinux, commits) and
port-allocations.md for why the port is 20482.
What must not regress
The five guarantees in doc/spec.md §1 are contractual. In particular:
- Never normalise a replayed header.
ETag,X-Repo-Commit,X-Linked-EtagandX-Linked-Sizeare recorded as upstream sent them and emitted unchanged, quotes included. Client cache layouts are keyed on these. Do not compute a git blob SHA-1, derive an etag from content, or decide what a commit "should" be. - Never let a redirect eat the Hub's headers. The Hub answers a resolve
request with a redirect and puts the replayable metadata on that response;
the CDN it points at has none of it.
rustingface-data's upstream client follows redirects by hand for this reason. If you ever re-enable reqwest's own redirect policy, every recorded etag silently becomes wrong. - Never set
Content-Encodingon the resolve path. The client sendsAccept-Encoding: identityprecisely so the sizes it learns are real. - Never write a manifest entry before its blob upload has completed. The
ordering in
rustingface-core/src/fetch.rsis deliberate: a crash may leak an orphan blob, whichgcreclaims, but a manifest entry pointing at incomplete bytes is a silent correctness failure. - Never complete a client response before the manifest write lands. The tee runs one chunk behind for this reason. A file that was served but not recorded is invisible the moment the instance is sealed.
Testing
cargo test --workspace covers it, including tests/sovereignty.rs, which
runs the real service against a fake Hub speaking the real header protocol.
Add a case there for any behaviour a client depends on.
The conformance suite (test/conformance/) needs network and a pinned
huggingface_hub. Run it before claiming a change is safe for clients — most
of the real bugs in this repo's history were found by it and not by the unit
tests. It has also been run against the live MinIO on caveman; do that for
anything touching rustingface-data, because the local filesystem store hides
whole classes of problem (it has no multipart, no conditional update, and no
presigning).
Where things live
Types in entities, logic in core, I/O in data, HTTP in api, wiring in
the binary. core defines the Store and Upstream ports and must not gain a
direct dependency on object_store or reqwest.