Changes touching this path

  • the capture chokepoint becomes workspace/capture.rs: the snapshot pipeline, the three consent gates and the finalize seam share one module, and the next allow flag costs one Allowances field and one arm (#1291) 16c998d0 · dbf3dbe6…
  • a visibility spec loot cannot read stops being dropped in silence: the parser records the malformed line and seal_gate refuses to capture over it, naming the line, the spec and the legal forms, so a typo can no longer ship the path it was written to seal at the tier a relay reads 28ff6a3e · dbf3dbe6…diff
  • the four consents become one owned Consents parsed and rebased at a single argv door, so allow-demote stops travelling a route of its own and the transposition Allowances was built to prevent has one place left that could still make it instead of eight ffb85a76 · dbf3dbe6…diff
  • the land reads its position once and hands that one corpus to three gates that still run in ADR 0065's order, undoing the two-and-a-half-fold read the previous change caused by leaving a walk inside each gate while claiming there was only one ec75201e · dbf3dbe6…diff
  • a signing seam reads the working tree once and walks it once, so describe and land stop buying two whole-tree byte reads to look at file names, and loot-perf grows the capture timing that can see it (#1383) 31995cb5 · dbf3dbe6…diff
  • the implicit capture in front of every bare mutating verb reads the working tree once, so the tree it judges clean is the tree it records, and the doors already committed to capturing ask their refusals before paying for a read (#1395) 7f1fb453 · dbf3dbe6…diff
  • loot converge stops buying a second whole-tree read for the note it prints, because the implicit capture one seam below has already read that tree, and the series added to catch exactly this learns to fail: its fixture had neither the co-located checkout nor the standing fork the branch needs, so it could not reach the cost it was watching (#1401) 12c1207a · dbf3dbe6…diff
  • deleting a named read on Workspace stops being free, because the 377 places that reached past it into the engine and the store now go through those faces instead — repo() no longer exists, store() is module-private, and the three extracted children share their fixtures by name rather than through the parent's private test module (#1411) c454db04 · 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 test can no longer mutate the engine past every named face, because with_repo_mut is deleted and the 27 fixtures that reached through it each name the state they fabricate, while the one that was re-deriving load_shared_lineage by hand calls it (#1447) 9c3573f6 · dbf3dbe6…diff
  • content whose embargo has already lifted stops reading as sealed, because promoting due keys out of escrow is now the construction of the reader every content read hangs off instead of a doc-comment obligation six callers hoisted by hand, and deleting four of those hoists left all 2438 tests green while loot surface told an author to request a grant from herself (#1464) e59e46b3 · dbf3dbe6…diff
  • a merge stops settling a tip whose tree the caller still owes on the next line, because the two sites that open-coded finalize plus materialize_tree now settle through SettleTree::Materialize, and converge's hand-written persist() is the settle tail its own write was spelled out beside, with the one of the three that no test in the crate ever entered now pinned (#1468) 15e33421 · dbf3dbe6…diff
  • loot status stops reading the whole working tree twice, because the working row and the pending delta now come from one walk taken through the door #1383 built for exactly this verb, and that walk's plaintext moves into the live side rather than being copied out of a tree nobody reads again, while the read-only door finally carries a number: a cli-tier status sample whose control refuses the two shapes that read the tree fewer times, and a test-only walk counter that pins the count at one (#1549) 8a9411f2 · dbf3dbe6…diff
  • a publication marker that could not be read stops being carried as an unpublished one, because the three re-seals that carry @world across a rewrite now ask a read that refuses instead of a predicate whose swallow was argued for the publish guard alone, and the refusal is a typed variant rather than prose so a corrupt seal reaches the run-loot-verify remedy a vanished one already did, while ADR 0012 table rows name their consumer and state the grep the census is the output of (#1582) 6ee38984 · dbf3dbe6…diff
  • a corrected census stops being replaced by a fresh one, because ADR 0012's table drops the completeness claim that had already missed a consumer on the day it landed and states its rule instead, the swallowing publication read that consumer used is deleted along with it so outside loot-core there is no route to one left to enumerate, and HUNT-PERF's list of which perf halves re-open their fixture per repetition, which refuted itself inside a single sentence, is deleted in favour of each half's own doc rather than pinned as prose, which is #1587's half of the same defect (#1593) 4995641a · dbf3dbe6…diff
  • the harness stops measuring only what a run produces and starts measuring what it does, because the three work counters this run built and threw away are now one family in loot-count that a single during region reads whole, with logical object opens and disk reads kept as separate numbers since 2,000 of the first can cost zero of the second, and the family ships compiled out rather than as cfg(test) one-offs because cfg(test) reaches neither an integration test nor loot-perf and would foreclose the gate #1602 exists to add, at a cost measured at zero bytes in the released binary (#1600) 482a72c1 · dbf3dbe6…diff
  • the dirty question stops reading every file to answer one boolean, and the two clocks it depends on are not the same clock: a stat cache lands at .loot/<position>/stat-cache as a PositionOwned artifact the store treats as opaque bytes, so nothing derived from it reaches the graph, a manifest, a bundle, the wire or any peer - its version header is a local self-check whose only failure mode is read as no cache, which is the opposite of a compatibility break since an older loot does the full read and gets the same answer. An entry is trusted only when size and mtime match AND mtime is older than the walk's own stamp, so a write inside the walk's tick is always re-read and no granularity is assumed on any platform. What that missed on the first attempt is that the stamp comes from the PROCESS clock and every mtime from the FILESYSTEM clock, which on Windows are the precise and coarse system times about 15.6 ms apart - warm scans hit nothing at all, because the cache file's own mtime read as older than the stamp it carried. A one-second margin fixes it in the safe direction and is self-healing, and gross skew is caught separately by discarding a table whose file is older than the stamp it declares. loot lanes reads a foreign lane's cache and deliberately never writes one: the write would have been correct, and it was refused on a different ground, that ticket-to-lane's runbook promises this verb is read-only and agents run it against live lanes to read the claim board. So TreeScan has two named doors, read for a position walking its own tree and peek for one walking someone else's, and which a seam takes is spelled at the call site rather than inferred from the store it was handed. The cost of that refusal is named rather than hidden: with lanes warm, which is the steady state since every lane's session runs status, it is 13.6 to 16.8 percent against the 16.1 the write bought, and with every lane cold it falls to 4.5, which is not the cache at all but the seam now hashing each plaintext once where it hashed twice. status --porcelain is 24.8 percent. And the pin that #1536 asked for cannot do the job it was asked for: delete the cache and get the same answer passes on every answer assertion even when the cache is never consulted, because an inert cache answers correctly by doing all the work - what distinguishes them is counting hits and reads, whose cold zero-and-N is its own positive control, and a poisoned row that keeps size and mtime, carries a wrong digest over a genuinely clean tree, and must answer dirty. Three of this ticket's premises were also wrong: the 46 ms status baseline was measured where status never walks the tree, since with no working change it returns at is_clean, so the gap over the control was never the tree read; the byte read is a quarter of what holds these verbs up rather than the whole of it; and human status on a dirty tree cannot benefit at all, because rendering a per-path delta needs the plaintext (#1669) 96d922e8 · dbf3dbe6…diff
  • loot lanes now reads the shared graph and scans the object directory once per board draw rather than once per registered lane: a new DagRepo::load_positions_from reads the position files of every lane first and the shared half once after them, so each row keeps the read order load_from_needing documents while every row reports against one moment of the shared store. that is the decision the ticket asked for, recorded on peek_lanes with its reasons, among them that option c cannot help because a row needs both the graph and the objects. a single load now reads the working change before the graph, the order that doc states. on a scratch repo with twelve lanes and a 4.9 MB graph the board went from 237 to 190 ms, paired in both orders with loot status flat as the control, and its porcelain and json output is unchanged apart from heartbeat age. a new board test relating the store file reads of the board to those of its rows built one at a time went red on the unchanged code and with per-row loads put back (0 passed, 1 failed each), and an engine test comparing a batch load with solo loads went red with the mixed-store refusal removed and with one position half reused (0 passed, 1 failed each). the perf gate reads no move, CONTEXT.md follows, and the workspace suite is green (#1782) caed7d82 · dbf3dbe6…diff
  • a .lootattributes rule whose pattern ends in a separator refuses the capture instead of sealing its subtree internal, and the decision is recorded with the widening it declines. the trailing-separator subtree affordance is .lootignore dialect - build/ prunes there, and #1859 repaired it there - while an attributes pattern is compared against the whole relative path, which never ends in a separator, so docs/ restricted=connor matched NO path and every path under docs/ fell through to Internal, the ANYONE-granted tier a relay reads by design. reproduced through the spawned binary first, which is what the ticket asked: loot new sealed docs/plan.md internal at exit 0 with one first-seal-summary line as the only signal, the #1108 shape exactly, and loot explain said the rule was tried and none matched. the ticket offered two answers and they are not equally safe, so the rejected one is measured rather than argued: reading the separator as .lootignore does MOVES what a path resolves to, and first-match-wins means not always narrower - with it honoured, docs/ internal above docs/secret/** restricted=connor resolves docs/secret/keys.md internal, and a_recorded_inert_pattern_moves_no_paths_tier goes red (27 passed, 4 failed over the file). silent exactly where the mis-seal gate is blind, a first seal of a basename that is not secret-shaped; an already-recorded path would trip the demotion guard instead, loud and just as unasked-for; either way the operator file would mean something new because the binary changed. so the line is RECORDED, not re-read: Attributes::parse keeps every rule exactly as it always parsed it, so no path changes tier and ferry ingest, which reads the rules and never the faults, is untouched, and the line becomes a MalformedRule that Workspace::malformed_attrs_gate already raises RepoError::MalformedAttrs over - one variant and one slug for both faults, because the taxonomy grows where a driver must act differently (#1582) and the tree one consumer of the slug does not, so each fault renders its own remedy beside its own line rather than one sentence teaching a reader the mistake they did not make. read off the compiled glob, so the docs-backslash spelling a Windows shell completes is the same fault and is quoted in the spelling it is compared in, the one loot explain prints for that line (#1859). scoped to the trailing separator and not to a pattern that matches nothing, since a bare docs internal is a fine rule for a file named docs. VISIBILITY blast radius measured rather than accepted: every .lootattributes in the estate - this repo and its lanes, scripts, millerbyte, the test and perf-scratch repos - plus every recorded revision of this repo own, holds no trailing-separator pattern, so no position next capture refuses and no repo changes tier, and the_shipped_attributes_holds_no_rule_the_gate_refuses keeps the shipped file that way. mutations: the recording dropped reddens the unit pins, the seam pin and the spawned pin (28 passed, 3 failed; 4 passed, 1 failed; 0 passed, 1 failed, the last naming the capture that succeeded); the separator honoured instead reddens four including the no-widening pin; a docs/ line added to the shipped .lootattributes reddens its census (0 passed, 1 failed). the path compared never ending in a separator is measured too, since the argv door rebase strips one and loot explain docs/ asks about docs. ADR 0038 carries the #2030 amendment and CONTEXT.md both halves, the attributes refusal and the .lootignore entry stating its affordance does not reach the other file. no migration, and no forge, relay or site byte moves, so this owes no deploy. the workspace suite is green (3859 passed over 119 binaries, 7 ignored) (#2030) 3e849712 · 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
  • a .env in the middle of a basename is secret-shaped too, and the backup written beside a sealed credential file is refused rather than sealed Internal: #1108 widened the mis-seal gate to the .env suffix and recorded one boundary as deliberately left open, that <name>.env.<suffix> answered to neither affix, on the argument that closing it with *.env.* would swallow the committed-template convention; that was an argument and not a measurement, so this measures it first. over every git-tracked basename in every git repo directly under this estate, 25 repos and 12,732 paths on 2026-09-20, the arm newly catches one path, the scripts repo .setup.env.example, and nothing else, which is the template class #1108 feared and also the one shape the arm cannot be narrowed away from by name, since a template and a backup differ only by the suffix the operator typed and a suffix allowlist would be a hand-maintained list of exactly the kind AGENTS.md names, guarding a credential. what bounds even that catch is the gate scoping rather than the pattern, first seal and Internal-by-fallthrough only, so a path already in the anchor or named by a rule of its own never trips and the template costs one .lootattributes line, once, against a false negative that loot burn can only bound. the case is this estate again: scripts seals .setup.env by exact basename, its gitignore covers the whole family since loot#1643, and a .setup.env.bak-v0420 sits in that working tree named by neither of the two loot policy files. reproduced through the spawned binary in a throwaway repo before and after, a .setup.env.bak-v0419 sibling beside a .setup.env restricted=connor rule captured and sealed internal with no refusal on 0.4.22 and refused by name on the lane binary, with one rule reaching the sibling sealing it restricted instead. ADR 0069 carries the measurement table and ADR 0038 section 1 closes the boundary it had recorded as open. red under mutation, counts read each time: the arm removed (0 passed and 2 failed, the gate handing back the old Ok with the sibling Internal), the arm widened to a boundary-free env substring (0 passed and 2 failed, on the negative controls both here and in the suffix pin), the refusal condition stripped of its tier and fallthrough halves so the sealed original is named beside the sibling (0 passed and 1 failed), and the arm narrowed to a suffix allowlist that spares the template (0 passed and 1 failed). the scripts .lootattributes half of the ticket is untouched and stays with the operator, being a visibility rule in another repo. no migration, no wire or format byte moves and no host behaviour moves, so this owes no deploy. the workspace suite is green (4051 passed over 128 binaries, 8 ignored) (#1930) 85479732 · dbf3dbe6…diff
  • the ingest check is refused and the census that would have judged it is what lands: a change tree entry records a visibility that sealed::seal leaves outside the address, that compute_change_id_raw discards on the way into the version id the finalize signature covers, and that ObjectStore::put keeps from whichever bundle arrived first, so on a tree that came from a peer that field is a claim under no signature. tree_entry_visibility_census.rs derives every two-identifier vis pair spelled under crates/*/src and carries per site what a lie in that field would change - rendered, acted on, re-recorded, or not a tree entry at all - keyed by file, enclosing fn, which declaration of that name and which binding under it, because bundle_codec and loot-wasm each declare a name this keys on more than once and a key on the name alone would hand two functions one ordinal run, the ambiguity store_rename_census holds out of reach with a guard instead. the class is a judgement and is not measured; what is measured is that a row cannot be written without one. the sites it turns up as acted on are what the ADR 0012 entry rests on: ride_entry reads the tree entry rather than the seal when it decides whether an anyone-granted content key rides a bundle, embargoed_paths hands a timed relay grant the reveal_at the entry records, and publish_gate refuses an embargoed publication on the anchor entry tier - each of them holding or reaching the object it could ask instead, which is why the repair is per site rather than a global refusal at apply_sync, where the check would be partial exactly where it is wanted (a change ships its whole tree, ciphertext rides only for the addresses a bundle carries), where disagrees is not is false once put_vis_redacted has stripped a holder list on the wire and same_seal exists because of it, and where one refusal rejects the whole bundle. the workspace walk moves into census_text under its own admission rule, now that a second workspace-scoped census wants it. red under mutation, counts read each time: a planted binding in maroon_inner (2 passed and 1 failed, naming maroon_inner@1#2), a named row deleted (2 passed and 1 failed, naming bundle_impl_within@1#1), the type exclusion dropped from the needle (1 passed and 2 failed, the fixture naming qualified@1#1 off an (Oid, Visibility) annotation), the declaration ordinal dropped from the key (2 passed and 1 failed, twice@1#2 where twice@2#1 belongs, the table green beside it) and the walk blinded (0 passed and 3 failed, the guard saying gone blind rather than clean). no migration, no wire or format byte moves and no host behaviour moves, so this owes no deploy. the workspace suite is green (4096 passed over 132 binaries, 8 ignored) (#1892) 2ece96df · dbf3dbe6…diff
  • the three sites that acted on a tree entry unsigned visibility ask the seal now, and the bundle key lane stops reading that field at all: #1892 censused who reads a change tree entry visibility, refused a blanket ingest check at apply_sync, and left these three deciding on a value that sits outside the content address, outside the change id and outside the finalize signature, so on a tree that came from a peer it is a claim under no signature. ride_entry read open off the manifest entry while reading anyone off the object a line above, so an entry recording Internal over an embargoed seal put that content key into a sync bundle any peer can hold; it reads the seal the same probe already returned, memoised per address beside anyone, and costs no store read the walk was not already paying. the same predicate on the batched path moves with it, since a transfer with a second batch would otherwise reach the old answer: the key rule comes out of wanted_finalized_entries, which answers presence alone now, and bundle_objects_only asks the object it is already holding. embargoed_paths takes the reveal_at a timed relay grant is withheld until from embargo_reveal_at, the door #1578 built for that number at loot grant --relay, and the entry number survives only where the seal cannot be produced, which is a state where grant_sealed cannot produce a deposit either. publish_gate asks seal_visibility beside the oid_is_published read it already makes of the same object, and refuses where the seal cannot be read rather than swallowing, because a swallowed published-ness read asks for consent already given while a swallowed embargo publishes content nothing could say was unsealed. each pin carries both directions, since a repair that only tightens is as wrong as one that only loosens, and none of them compares the two recordings, which ADR 0012 records as supposed to differ once put_vis_redacted has stripped a holder list on the wire. the rows for the sites that stopped binding the field left #1892 census rather than changing class, a discard being no row by its own definition. red under mutation, counts read each time: ride_entry open restored to the manifest entry (negotiation 34 passed and 3 failed, the byte-identity difference red beside both direction pins, and the census 2 passed and 1 failed naming bundle_impl_within@1#1 and @1#2), the batched key arm stopped from asking (35 passed and 2 failed, naming the follow-up batch arm), the deposit reveal time taken off the entry again (custody 65 passed and 1 failed, reading Some(0) where Some(9000) belongs), the publish gate embargo read taken off the anchor entry again (loot-cli 0 passed and 2 failed, red in both directions, and the census 2 passed and 1 failed naming publish_gate@1#1) and the unreadable seal swallowed (2 passed and 1 failed, naming ghost.txt). no migration and no wire or format byte moves, but the key lane decision moves on the client bundle builder and on the relay fetch path, so this rides the next release and owes a relay deploy. the workspace suite is green (4101 passed over 132 binaries, 8 ignored) (#2185) 0a33e5c4 · dbf3dbe6…diff
  • loot new prints each first-seal tier off the seal the path was sealed under, so a path the same finalize had just published no longer reads internal: the summary printed the .lootattributes resolution seal_gate hands back, a Visibility, which cannot spell published because a published object is Internal plus the @world marker (#481). the tier is now read back off the signed change, seal_visibility and published_marker_to_carry over the address the finalized tree holds at each path, rendered through a new render::tier_label that restore now shares. reading rather than folding the standing rule in, as with_publish_status does for surface, is what makes it right under --no-snapshot, where the finalize signs an earlier capture and the rules may have moved in either direction; a row the finalized tree does not hold is left out, and an unreadable seal prints as a refusal and never as a tier. both directions pinned red first (0 passed and 2 failed): every Tier plus published on a fresh capture, and under --no-snapshot a published seal whose rule was deleted, a restricted seal whose rule was deleted and an internal seal given a publish rule since. red under mutation, counts read each time, each restored green: the row printed again (0 and 2), the marker ignored (0 and 2), the marker taken from the standing rule (1 and 1), seal or standing rule, the overstating repair (1 and 1, late.txt read published), the Visibility taken from the row (1 and 1), internal spelled published (0 and 2), an unreadable seal falling back to the row (2 and 1), a path the change does not hold kept (2 and 1). reproduced through the 0.4.24 binary before and a lane build after. CONTEXT.md, the census row for new_with and the Workspace width move with it. no migration, format byte or wire byte moves, so this owes no deploy. the workspace suite is green (4407 passed over 139 binaries, 13 ignored) (#2219) a4254982 · dbf3dbe6…diff
  • the attestation ledger records what a remote is known to keep rather than what a push put on the wire, the review-sweep fix-up over #2251: a push records rows only for a host whose /info answered, as a relay or as a forge advertising late_attestations, and a host whose /info did not answer is still sent them but has nothing recorded; against a forge without the flag it records what rode with its change, so its left-behind warning counts the late ones and no longer grows; the ledger keeps per forge the tip generation the last recorded push committed at, and a push that reads a lower one sends every attestation over the changes that forge holds again and says it may have been restored, with deleting .loot/attestation-ledger documented as the recovery for a relay and for a restore hidden by later pushes; a ledger that will not read or write warns and never fails a push or skips its deposits, and a record over an unreadable one starts it afresh. the forge misread as a relay the sweep named fails at its unsigned /wants before sending, pinned; the rule stands without it. red first with each fix undone, counts read each time, each restored green: an unanswered /info read as keeping them (0 passed and 2 failed), a forge without the flag recording nothing (0 and 1, left behind 2 where 1), a restored forge unnoticed (0 and 1), an unreadable ledger fatal (0 and 1), an unwritable ledger fatal (0 and 1), the first-seal summary defaulting an unknown change to no rows (0 and 1). also stated: the privacy filter rests on the declared have, a forge holding a head without its ancestry drops a late attestation it is recorded as keeping, a ledger is one clone, late_attestations states the property rather than naming verbs, RemoteSync bound records nothing and its docs are current, the first-seal summary refuses an unknown change and names its tree clone, and the Route doc states where hosting is decided. the ledger stays push-only: store_file_reads is 24 on the gate workload with no move. no format constant, codec byte or migration moves. the workspace suite is green under bash ci/local.sh against Postgres 18 (4430 passed over 139 binaries, 13 ignored; site live suites 7 files passed) (#2355) 9511111e · dbf3dbe6…diff
  • loot apply-patch names each applied path by the tier its seal records, and loot new --no-snapshot lists the paths the signed change first seals: the apply-patch report printed the .lootattributes resolution, a Visibility, which cannot spell published, so a path this repo publishes read internal while loot show said published, and it now reads each row through Workspace::tiers_as_sealed, the #2219 read generalized from first_seals_as_sealed to any paths of a recorded change, rendered through render::tier_label. the first-seal summary took its set of paths from the disk walk of seal_gate, so under --no-snapshot a .lootattributes the earlier capture first sealed and the disk had since lost was left off; finalize_capturing_over now returns the paths the signed change holds and the anchor the gates judged does not (Workspace::first_seals_of), paths alone, since the tier is the seal. both pinned red first (0 passed and 1 failed each): published, internal and restricted rows through the apply-patch verb, and a --no-snapshot summary listing the lost rules file and neither a path the disk gained since nor one the anchor holds. red with each piece undone, counts read each time, each restored green: the marker ignored, published claimed for every row, the rule resolution printed (0 and 1 each on the apply-patch pin), the set taken from the disk gate, the anchor filter dropped, the anchor read after the finalize (0 and 1 each on the summary pin). reproduced through the 0.4.24 binary before and a lane build after. CONTEXT.md and the Workspace width move with it. no format, wire or migration byte moves, so this owes no deploy. the workspace suite is green (4532 passed over 139 binaries, 13 ignored) (#2353) 22faa0d6 · dbf3dbe6…diff
  • review sweep 16 fix-up over #2382, #2353 and #2358: the test scratch helper hands every path out inside one directory named for the process and claimed once before its first path, so a sibling a fixture derives, the <path>-lanes/ a lane spawns in, is inside what the claim cleared and a reused pid no longer hands a later run the lane an earlier run left, which stacked() in propose.rs took from read_dir; a retired key that wrote a proposal tip is refused the withdrawal in live_account_in words, decided by the retirement rule ADR 0075 already applies to an offer and ADR 0095 to a comment withdrawal, and recorded as an ADR 0075 amendment, with the account live key still withdrawing; the rows_of unread-seal branch is pinned through loot diff --json, which the doc said no verb reached; with_sealed_publish_status refuses a change this position does not hold, sharing held_tree with tiers_as_sealed, where it answered every row unpublished; the speaks_for, sees, rows_of, with_sealed_publish_status and scratch guard docs, CONTEXT.md and ADR 0095 say what the code does, the by-account property scoped to the forge routes. red with each undone, counts read each time and restored: only the handed path cleared (2 passed and 1 failed in scratch_dirs), no retired-key refusal on withdraw (2 passed and 1 failed over the three rotation pins), the decline gate by key through visible_to (0 passed and 1 failed), the rule fallback back in rows_of (0 and 1), and the empty-tree default back in with_sealed_publish_status (0 and 1). bash ci/local.sh is green against Postgres 18, 4606 passed over 142 binaries with 13 ignored and the site live suites at 78 passed. no migration; the withdraw route refuses a retired key now, so this owes a forge deploy (#2386) 6621b15f · 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.