Changes touching this path

  • day 0: loot hosts loot f4c30e75 · dbf3dbe6…
  • evidence: crew minted and verified (#86) 1fada823 · dbf3dbe6…diff
  • normalize working tree to LF: byte-stable co-located bridge (.gitattributes -text) e58fdda6 · dbf3dbe6…diff
  • Reconcile CONTEXT.md + ADR statuses to shipped reality (#124) (#131) The build ran ahead of the prose. Flip the CONTEXT.md glossary: Harbor "proposed" -> "CA2 shipped, 2026-07-07" (588762d); Buoy "proposed" -> "CA4 shipped, 2026-07-09" (097cb25); and the Verdict entry's "dock merge once CA2 lands" -> the actual shipped verb set (apply/conflicts/status/dock merge/pull/ ferry). Set ADR 0022 status to implemented (CA1-CA3 on main; convergence proven by the map #119 evidence, which fixed #128/#126) and ADR 0025 to implemented (CA4, 097cb25, PR #70). Git-Author: Connor Miller <53197564+Connor-Miller@users.noreply.github.com> a8cafda5diff
  • loot dock rm: remove a dock, dropping parked unsigned WIP; undoable (ADR 0022 amendment, #212) c14695b4 · 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
  • an ingest pins the primary line before a sibling head can land, so a capture stops forking from the union of both heads and silently dropping the un-surfaced side out of the recorded tree (#1197) fc6b0b7c · dbf3dbe6…diff
  • an ingest records which paths it did not write, because that is the last moment absence and deletion are different facts, so a capture after --no-surface stops recording the content it just fetched as removed (#1227) cbf4a65f · dbf3dbe6…diff
  • the tree writers no longer remove the file they just wrote on a recorded case-only rename: materialize_target and materialize_promoted wrote the target tree and then removed each old path the new tree no longer holds by name, so where the filesystem folds case, as this windows machine and a default macos volume do, the removal took off disk what the write had just put there, and loot undo over such a rename reported pruned 1 path off disk, left the directory empty and made the next status read the recorded path as deleted, which loot move and converge did too, each reproduced by hand with the pre-change binary. both writers now prune through loot_core::disk_entry::prune_unwritten, the one home for the file and directory-entry rule apply-patch has taken since #2007 and #2014: an old path that is the directory entry of a path just written is renamed onto the written spelling, which keeps the bytes and gives the last name component the recorded case, the old name of a hard link is still removed by name, NotFound is a path that was not on disk rather than a path pruned, and any other removal failure is an error naming the path, where materialize_promoted discarded the error and materialize_target counted a failed removal as pruned either way. the identity helpers move out of apply_patch.rs into the new module, drop_empty_parents is shared with the view prune, and the prune makes no filesystem call beyond its removals unless an old path and a written path fold alike. the new pins went red with the entry rule removed (cli 1 passed, 3 failed; core 4 passed, 1 failed), with the old path kept and not renamed (cli 1 passed, 3 failed; core 4 passed, 1 failed) and with the removal error discarded and counted anyway (core 3 passed, 2 failed; the cli pins stay green, since none of them fails a removal). the perf gate dry run reads every counter the same before and after and says no move, ADR 0022 carries the amendment, ADR 0082 section 4 says where the rule lives, CONTEXT.md names it beside the apply-patch rule and in the re-pointing entry, and the workspace suite is green (#2011) de9fb5b0 · dbf3dbe6…diff
  • cherry-pick, revert and a surface that settles a stale-disk debt no longer destroy a case-only rename where the filesystem folds case, and the first no longer records the loss: #2011 routed two tree writers through loot_core::disk_entry and wrote that every writer which removes a path it may just have written asks that module, while two that did not were sitting in the tree as the sentence was written. Workspace::apply_change_delta, the one core cherry-pick and revert share, walked the merged actions as a BTreeMap and so wrote A.txt and then removed a.txt by name, which where case folds is the file it had just written, and it snapshots, so loot revert over a recorded case-only rename reported both paths converged over an empty directory and minted a change recording 1 deletion. Workspace::stale_debt_the_surface_left, the one scoped deletion a surface is allowed, compared the written set by name, and a case-only rename preserves the bytes, so the digest guard that exists to protect the operator matched the file the surface had just written: loot surface printed the path it had surfaced, left the directory empty, and the next loot status read it as deleted, which is the reproduction #2011 declined on the false reading that a surface prunes nothing. Each was reproduced by hand through the spawned binary first and then as a new spawned pin, and the pair went red over an empty listing before the change (4 passed, 2 failed) and is green after (6 passed); with the delta writer put back to removing by name they go red again (5 passed, 1 failed) and so does the new census (0 passed, 1 failed), and the stale-debt prune put back reddens the same two with the same counts. Both writers prune through prune_unwritten now. Which working-tree removals are weighed stops being a sentence: workspace.rs carries a census that reads every removal joined onto a working-tree root out of loot-cli/src and loot-core/src, names what each one removes and what the walk cannot see, and it named the offending function under each of those two mutations, went red at its own classifier control with ROOTS emptied and went red with a name dropped from its expected set (0 passed, 1 failed each). one_entry refuses a path that is or passes through a symbolic link now, since file_id follows links and on Windows two paths with one id were otherwise one entry, so fs::rename would have moved a link over the file it points at; the check is the symlink_on apply-patch already made, moved into the module, pinned with a junction here and red without it (5 passed, 1 failed). The hard-link pin names its links A.txt and a.txt so the fold map reaches the entry rule at all, where old.txt and new.txt never called it, and it skips a filesystem that folds case with a note; it stays unix-only and its red-first has not run here, though the body type-checks and runs on windows with the cfg lifted (7 passed). The four case probes become one loot_core::disk_entry::folds_case, and with it answering no the entry pin and two apply-patch case pins go red (5 passed, 1 failed; 18 passed, 2 failed). enclosing_fn moves into source_walk beside the #1929 census that asked it first and strips any visibility, after pub(super) made the new census name the wrong function. ADR 0022 carries the correction and its prunes-nothing claim is gone, ADR 0082 section 4 states where the probe and the link refusal live, CONTEXT.md names both writers and the census, the surface.rs and materialize_target notes stop claiming the two prunes answer the same set of failures, and the rewrap leftovers in ADR 0022, CONTEXT.md and the account page are fixed. The perf gate dry run reads every counter the same before and after and says no move both times, the site gate is green, and the workspace suite is green (3824 passed) (#2018) baec4112 · 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.