Files
rustingface/CLAUDE.md
T
grenadeandClaude Opus 5 8578ca6e0d
deploy / build (push) Successful in 6m27s
deploy / deploy (push) Has been cancelled
docs: readme and agent notes
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
2026-08-31 10:58:54 +03:00

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-Etag and X-Linked-Size are 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-Encoding on the resolve path. The client sends Accept-Encoding: identity precisely 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.rs is deliberate: a crash may leak an orphan blob, which gc reclaims, 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.