A transfer whose idle key ended while the holder's bundle was down had its marker seen by no watch, so it
stayed open for good. FollowIdle now hands every open transfer (IDs) to Expired once the watch is taken:
one past its bound is dropped, one within it armed again for the rest.
Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
distribution and gitea each carried the same idle bound (one expiring key per open transfer, its end
dropping a transfer idle for 24 hours or arming it again for the rest) and the same read of incoming's
cap from its binding: the second instance of the kind, so it moves to the Receiver every holder shares.
Arm is called on each open that leaves a transfer open, a key not written failing it loudly; Expired
handles a key's end; Bound reads the binding's cap over Cap. BusArm, BusCap and FollowIdle bind them to
the holder's own state and objects.
Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
Brings A3's parts receiver and bus adapters, the shared caller lists and builder versions question, a transfer read
back from bus state (0424e87) and catalogue.SeatReference (c10ef07). c974a11 adds nothing: its version_numbered.go
and BuildAnswer.OutOfStep are the join's own. publish stays out (ADR 0627, 1a149d4): packages_list_test keeps the
join's form. TestAHolderTakesAFileInParts is a subtest of TestAFileTravelsInTheParts, so unit tests stay at 476.
Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
A transfer is kept in a key-value state as JSON, and its empty Chunks map is omitted, so the one
read back for the first chunk had none and Take panicked: every publish in parts through
BusTransfers. The unit tests' transfers now round-trip JSON as the bus does. Found by the forge
module's whole test (CAT-G3).
Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
A holder raises a finding when it refuses a file for want of room; that finding is the holder's, not the file's,
and clears once it takes a file again. AtCap and RefusedAtCap let it tell that refusal apart without its own copy
of the reason's words.
Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
parts.Receiver takes a transfer's chunks into the holder's own objects under the caller's prefix, checks each whole
part's hash, drops a transfer left idle and tells the caller the objects' fill; the opening's shape, the check before
storing, the storing and the saying of a refusal are the caller's, so it names no seat, verb or seat type and
distribution and the forge's two package seats bind it to the seats they hold.
Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
parts takes the open and the chunk calls from its caller and names no seat, verb or seat type; each registry
seat's client in mesh-contracts binds it to its own seat (ADR 0627 §1).
Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig