SDK: extract deep WorkingOverlay both LootRepo backends compose (#429)
Both LootRepo adapters shared only the interface — the capture-first
pending-change behaviour (Pending type, overlay/message/guard fields, the
added/modified/removed ternary, the two push preconditions, the guard union)
was copied into RelayRepo and PhysicalRepo. Extract it once into a pure,
synchronous WorkingOverlay<P>: RelayRepo composes WorkingOverlay<Uint8Array>,
PhysicalRepo composes WorkingOverlay<string> (abs path). status/diff become
one-liners over classify + message; push walks entries() to compose its own
change. Relay's client-side visibility resolution + GuardError enforcement and
the private keyring stay in the relay adapter.
classify(committed) is pure and unit-tested with hand-built inputs (13 tests,
no relay, no binary). CONTEXT.md gains the SDK-tier Working overlay entry
linking [[Working change]]. SDK suite 45 green (32 pre-existing + 13 new). 82ee8e52 · dbf3dbe6…
Renames are not followed. loot's tree maps a path to an address, so a rename is a delete and an add. This list is the history of the name, not of the bytes.