Changes touching this path

  • a lineage catch-up brings the objects and keys its nodes reference, and a ferry that dies mid-projection names the oid in hex and the recovery (#778) The filed hypothesis was that a change node can become visible before the objects it references are durable. It is wrong: save_to already writes objects before the graph that names them, and that order is deliberate and commented. The real defect needs no race at all. The object store and the keyring are loaded exactly once, at load_from, while the shared graph is deliberately re-read mid-process by ingest_shared_lineage (the 265 catch-up primitive). So any peer that finalizes after this process opened contributes a node whose bytes and keys this process will never hold. A land guarantees a long window there: it opens the workspace, runs the pre-land tests, and only then ferries, so the ferry aborts mid-projection while holding the harbor lock. ingest_shared_lineage now refreshes objects and custody after it re-reads the graph, and load_from reads in the reverse of save_to write order, so a reader never blends a newer graph with an older object scan. Also: an Oid renders as hex instead of a 32-element decimal byte array (Debug full width, error strings short), and a mid-ferry abort now names its recovery with flags checked against the verbs that parse them. hex moved from loot-core to loot-codec because RepoError is defined in loot-codec and the dependency runs one way only; loot-core re-exports it, so every call site is unchanged. 0ba6d577 · dbf3dbe6…
  • loot propose --show resolves the whole change id loot propose --list prints for a proposal whose stack this position never pulled: --list prints the id as k-z letters, and --show matched letters only against the local graph, so the handle copied off --list refused unless the stack was held. a whole change id, in hex digits or in letters, now decodes on its own through hex::decode_letters_array, the inverse of hex::letters, before the local resolver, which still takes a shorter prefix or a selector; the resolver doc said --list prints the hex id and now states the property it relies on. nothing is fetched or pulled as a side effect, and propose has no porcelain or json output, so no machine shape moves. pinned through the spawned binary: a fresh repo with its own key reads a metadata-public repo, copies the handle off --list, loot evolog refuses that handle, so this position holds no change by it, and --show reads the proposal. red first (0 passed and 1 failed), and red with each piece undone, counts read each time, each restored green: the letters arm dropped (0 and 1), the decoder nibbles swapped (0 and 1 on the codec pin, and 0 and 1 through the binary, where the forge answers that no such proposal is visible). the workspace suite is green (4521 passed over 139 binaries, 13 ignored). client-only, so it owes no deploy and is live once the CLI is released (#2339) 01737140 · 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.