Changes touching this path

  • 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…
  • SDK: restore OverlayEntry as a discriminated union (#429 follow-up) The #429 extraction flattened repo.ts's tight put|remove union into a single shape with optional payload, which regressed the fold site to a non-null assertion (builder.put(path, pending.payload!, …)). Make OverlayEntry<P> a discriminated union again so the push loop narrows on kind and reads payload without the `!`. Pure type change; tsc clean, 45 SDK tests green. 4e54101b · dbf3dbe6…diff

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.