Changes touching this path

  • Spawn DevX (#232): loot lanes observability, --ticket lane spawn, wayfinder claim-to-lane f0a885c2 · dbf3dbe6…
  • #244: loot adopt <version> — settle a dock onto a landed change The re-baseline primitive #243 needs and could not do safely. A dock can end up on a divergent local line that must be *discarded* in favour of a landed change (the #243 state: the primary main dock on a stale fork while origin/main moved on). apply/converge MERGES the lines — against a stale fork that resurrects files deleted upstream; abandon --head drops a signed fork tip but not the working-change head. adopt <version> fills the gap: take the target wholesale, abandon every competing head, no merge. Composition of shipped parts (no new engine machinery), per the committed spec docs/specs/loot-adopt-target.md: - Workspace::adopt: resolve the target among live finalized changes, fence it to the harbor/main lineage (reachable from the change the mirror's main projects, read from the local ferry spine — no network, no git process), WIP-gate (refuse a dirty dock unless --discard-wip), then abandon every competing head to a fixpoint (dropping a transient ferry merge resurfaces its parents, so the whole divergent line is walked into the abandoned set), settle tip on the target, and materialize its tree via the existing resurface checkout — one undoable op (ADR 0031). - loot adopt <version-id> [--discard-wip] CLI wiring (COMMANDS + USAGE). - Amend ADR 0034 (the <version> take-wholesale arm + discard-vs-merge table) and the CONTEXT.md Adopt entry. Seven tests: settle+abandon+undo, dirty-refuse, discard-wip drop, off- lineage refuse, unsigned-target refuse, a merge-over-stale-fork fixpoint walk, and an end-to-end adopt-then-ferry asserting nothing projects (§6.5). Verified live through the CLI: rolled a drifted dock back onto a landed change, undo restored it, and the lineage guard refused an ahead-of-main target. Deliverable 3 (the §6 live reconcile that finishes #243) is an operator-run repair of live .loot state and stays a follow-up per execution order §9 (it runs after this branch lands). 01bae608 · dbf3dbe6…diff
  • feat(loot-cli): no-arg `loot adopt` — harbor catch-up merge (#250, ADR 0034) 22524137 · dbf3dbe6…diff
  • Catch up to git main 809ddfe: #260 smoke default, #271 arm64 build, loot diff (#1), ADR 0034 dock retirement (#253) 587684dd · dbf3dbe6…diff
  • Fix pr-map ledger lost-update: serialize writes under pr-map.lock (#336) review and land both did read -> mutate -> whole-file rewrite of .loot/git-mirror/pr-map with no lock, and land's read happens minutes before its write (tests, ferry, push) - a land clobbered all three rows sibling reviews recorded mid-flight (live, 2026-07-18). Every ledger write now funnels through one door, update_pr_map: take git-mirror/pr-map.lock, re-read fresh, apply only this operation's own row add/remove, replace atomically. Early reads in review/land are lookups only, never written back. The ledger lock is deliberately separate from the harbor lock: reviews must not queue behind a land's git-main section, and land's ledger close-out runs after harbor release anyway. The write is store::atomic_write like every replaced git-mirror spine file (#307), and readers (orchestrator + loot lanes) use store::read_replaced so the Windows rename-replace window (#293 tail) cannot read as an empty ledger. HarborLock::acquire_contending carries a caller-supplied contended message so a wedged ledger never claims to be a wedged harbor. ADR 0034 amended; concurrent.md ownership note refined. 11addd8f · dbf3dbe6…diff
  • the ledger reap gains an authoritative half, so a row whose change id stopped being the work's id can still be cleared (#793) #624 made the pr-map self-heal on discovery, and it does — but its proof is "a version carrying this row's durable change id is published on origin/main", and that question can become unanswerable for work that plainly landed. Ask 1 was to pin why, and the answer is neither candidate the ticket named. It is not gc and it is not the resolutions minting their own ids: the reviewed change landed as ff89d2c, its version IS in the graph, and it carries durable change id f7d93995 while its row still named aec9021d. The row is written once, in review(), and thereafter only ever removed. Nothing re-keys it. A durable change id is stable across re-SNAPSHOTS, but a bounce recovery that re-creates the working change rather than amending it hands the same work a fresh one -- and the ledger never hears about it. That row was then unreapable forever. The obvious repair is unavailable, and change_published_on_origin's own doc already says why: a live sibling lane's unsigned WIP never enters the shared graph either, so "absent from the graph" is the normal state of a row that is genuinely in flight, and reaping on it would eat every concurrent agent's row at once. Nothing local separates a stranded row from a live one. So the second half is authoritative and online: closed_rows asks the forge whether the row's PR is still open. Merged counts as over -- it is what GitHub calls the zero-diff collapse that IS the landing signal here. It is spent in review and land, which already hold a forge, rather than in status, the constantly-run verb #624 deliberately kept offline. Both sweeps run BEFORE their verb's own work. The operator most likely to be looking at a phantom row is the one with nothing to project, and a sweep behind review's `nothing to review.` return would be unreachable for exactly them. land sweeps too, because land is what strands rows in the first place -- it clears its own row as its last act, so a land that dies after publishing leaves one behind -- which makes the re-run the pass most likely to meet one. land excludes its own PR: a land that died after the collapse leaves the row with the PR already reading Merged, which is precisely what this reaps, so without the exclusion the retry would delete the row it needs and then fail to find it. A row nothing can be proven about is still always kept, so a forge that will not answer changes nothing. Rows are not aged out on a guess (ask 3): over-reaping costs a land that cannot find its own PR, under-reaping costs a line of output. Ask 4 is answered as far as it honestly can be: status cannot say which of its surviving rows is stranded (it cannot see the difference), so instead of guessing it says where the answer lives. Both reap bodies now share one door (reap_rows), so the local and authoritative passes cannot drift apart on the two things that matter -- going through the ledger's locked write door, and being best-effort. ADR 0034's #336 amendment and docs/agents/concurrent.md said every ledger write "applies only its own row"; the reap passes have removed other positions' rows since #624, so both now record the exception and why it is safe. 5cdfa18c · dbf3dbe6…diff
  • a lane carries its own hold, and custody crosses back whole at finalize (#811) 941cafb9 · dbf3dbe6…diff
  • a verb that could only publish to main unreviewed is retired: lane merge goes, its fold machinery stays where adopt needs it, and the mirror-free fold that genuinely leaves with it is named rather than glossed (#1048) 3f7635a9 · dbf3dbe6…diff
  • the docs gate themselves: a land refuses a link that resolves to nothing, five rotted ADR cross-links are fixed, every amended ADR warns in its status, and the artifact sweep retires with its producer 586e3260 · dbf3dbe6…diff
  • the store stops threading a dock nothing can ever produce through 43 signatures, because a store instance is already the position ADR 0034 retired named docks in favor of, and the sixteen path getters no caller outside loot-core reaches stop being public while the one main reservation that guards a git ref name stays (#1413) 23ab3abd · dbf3dbe6…diff
  • a locked pull stops leaving a stale copy for the next verb to capture: the ingest parks the claim it cannot check, and the first open holding the key finishes it. #1256 recorded nothing when it could not open the pre-ingest content, on the ground that loot rehome materializes and moots the question, which it does not do when it refuses, and in that state it refuses: the untouched pre-pull copy read as an edit no change had recorded, so rehome declined it and loot converge, the next step the pull note names, captured it silently, one change below the version that had just arrived. the claim, being the path, the pre-ingest oid and the digest of the bytes on disk, now goes to .loot/stale-disk-unverified, a position-owned artifact of the same shape and codec that nothing in force ever reads, and Workspace::settle_unverified_stale_disk makes the same comparison at the first unlocked open that was given a graph, beside heal_hold and under its gate: bytes that match move into the record in force, bytes that do not are the operator own work and the claim dies, an open that cannot answer leaves it parked, and a write that disposes of the bytes a claim is about retires it, whether it wrote over them or pruned them. rehome refusal stops asserting the arrival guard would refuse a capture where no guard stands: it asks Workspace::arrived_unmaterialized, keeps the circle where the guard does stand, and elsewhere says what recording those bytes actually does and that a verb capturing on entry records them whatever rehome refused. the locked pull note says to stop if rehome refuses. review fixes: the pin for the printed order now runs the three printed commands and nothing else, since any extra verb opens the repo and an open is what settles the claim, with the record own story moved to a second test; and the three malformed-record refusals stop offering a first remedy the refusal itself prevents, because they refuse at the open, so the file has to go before any verb can run. the Known Issues entry stays, wearing FIXED_IN_MAIN, because v0.4.20 is the binary a reader can install, and pin 5 comes back over it as its own retirement note instructed. red first: the note recipe, run in order, left the arrived version on disk only after the fix (0 passed, 1 failed). red under mutation, each 0 passed and 1 failed unless noted: the claim dropped rather than parked, the open never settling, the settle promoting without the check, dropping rather than keeping what it could not check, leaving a checked claim parked, and running on an open given no history; the surface, the whole-tree write and the one-path write each keeping a refuted claim (that last two 6 passed and 1 or 2 failed); the disposed set naming only what a surface wrote and not what it pruned; rehome claiming the guard everywhere and rehome never claiming it at all; the note without its stop clause; the page deleting the held entry, the page dropping the marker, and the held row witnessing a fix the tree does not carry. no migration, no wire or format byte moves, since the new file is local to a position and never bundled, and no forge or relay byte moves, so this owes no deploy; the CLI change owes a release, and the Known Issues entry leaves with it. the workspace suite is green (3962 passed over 122 binaries, 7 ignored) (#1963) f7b7e533 · 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.