Changes touching this path
- loot surface stops opening every object four times, and the instrument had to come first because the land's own gate is structurally blind to this: the gated fixture reaches the engine's Repo::surface, a different loop with no view filter, no report, no clobber guard and no CLI wrapper, and loot surface is in no cli tier sample, so a flat gate here says nothing either way and the named signal is a new loot_count::during region instead. The win is that the clobber guard has already resolved the exact Modified set and the materialize then rewrote every path anyway, so a SurfacePlan carrying at_risk, measured_at and already_on_disk hands that answer down: object_gets falls 4N to 3N at every one of the ticket's sizes (200 to 150, 800 to 600, 3,200 to 2,400) with object_disk_reads flat at N, which is the shape of an answer that got cheaper rather than one that changed. The dangerous part is not the speed but the authorization, because the third gate is inside the very step the set skips - sealed::open's embargo-then-visibility check is the one chokepoint and a trusted path is not re-authorized - so the trust is taken BELOW the view (#39) and grant-expiry (#20) gates rather than above them, and both orderings are pinned by tests that were proved red by moving the trust up: an expired grant materialized, and a path outside the view written. A plan measured against another change is refused by measured_at, and that breakage went red with disk holding the midpoint's bytes where the tip's were owed, which is content corruption rather than a slow path. Building the set by stat instead of a proven get went red twice, once on an embargo that has not lifted and once on --force restoring recorded content, so the set only ever names a path a Readable::get already returned Ok for - a precondition on the caller that the engine cannot re-derive, stated in the doc of the pub method rather than implied. The pin asserts the multiplier is identical at all three sizes rather than any literal, and its control refuses a store that cannot reach disk, which is #1576's --closure lesson made executable: the blind shape is the Workspace that authored the change, where put filed the plaintext and a surface decrypts from a map at object_disk_reads 0; the control is demonstrated refusing that, accepting a reopened one, and a separate non-vacuity guard is demonstrated firing on an empty fixture. One of this ticket's premises is wrong and is pinned rather than repeated: surface --json has always materialized once, not twice, because the machine arm returns before the human arm ever reaches surface_with_report - measured at 3N over a wiped tree - while rehome --json really did run two complete materialize passes and now reads the written it already had. The readable_at-per-path hoist is declined with the reason written into resolve_delta rather than left silent: on an empty escrow, which is every repo with no pending embargo including this ticket's own fixture, Escrow::flush is a map emptiness check collecting an empty iterator and contributes nothing to object_gets, so the hoist would measure flat in its own signal and wants an instrument that can see escrowed entries before it wants an edit. absent_paths_at keeps its N opens deliberately, because it walks the whole recorded tree including out-of-view paths the materialize loop never reaches and deriving it from that loop would silently narrow the listing. One TOCTOU window widens in kind and not in size: a file another process edits between the disk walk and the materialize is now left alone while still reported materialized, the same window the guard's answer already went stale in and in the operator-safe direction, so the type doc says surface's disk-mirrors-this-change promise is that much less absolute (#1703)
43a89f31 · dbf3dbe6… - bisect grows log, replay and terms, and the replay refuses WHOLE at a gap rather than replaying up to it, because a partial session is INDISTINGUISHABLE FROM A WHOLE ONE IN THE ARTIFACT: status renders both identically, the search then runs from a range missing a bound it was TOLD about, and the only evidence is a warning that has scrolled away. all-or-nothing has no partial result to mistake. the pre-flight resolves every id against the graph before writing anything and names EVERY missing change with the line that asked for it, and on a shallow position it says so and names --deepen rather than pull. SESSION_VERSION stays 1 and that is the shape of the preservation criterion rather than a promise about it: the terms pair is a TRAILING codec section written only when non-default, so a default session is byte identical to what the previous release wrote and a pre-1532 session still decodes. the transcript is an INPUT and what is frozen is its GRAMMAR rather than its emitted text - what the parser accepts today it accepts forever with the same meaning, and later work may add directives rather than re-read existing lines. an unparseable line refuses the whole file and points at the line, which is the rule 1516 set for an unreadable ignore file, and EMPTY or all-comment is refused TOO, because zero directives and a session with no marks are DIFFERENT FACTS and a truncated download is exactly how the first arrives looking like the second. ids are full 64 hex only, no prefixes and no HEAD, because a transcript is read on a machine where neither means what it meant there. the vocabulary TRAVELS with the transcript: a terms line rides ahead of the marks and replay resolves mark words against a RUNNING table, so it round trips, and a transcript written under old and new whose terms line is missing is REFUSED rather than re-read as good and bad - the one reading that would silently FLIP A VERDICT. the rename ADDS a spelling rather than retiring one, so bisect good keeps working afterwards, and that is safe ONLY because a term may not shadow a subcommand name, which is what makes the inversion terms bad good unspellable. two of its own assertions were not AIMED until they were fixed: the start assertion was vacuous because the fixture made start and the transcript bad the same id, repaired by finalizing a sixth change between the log and the replay, and a doc claimed its consequence one assertion earlier than the one that fires. and the tests produced a finding worth keeping: writing the transcript INSIDE the repo makes it an uncaptured edit, so replay refuses over work the operator did not knowingly make - the guard was deliberately NOT widened, since a replay checks a midpoint out and must refuse over the same work bisect start does, so instead the refusal names the likely culprit and the smoke test ASSERTS that refusal rather than arranging to avoid it (#1532)
05f9263e · dbf3dbe6…diff - the trait surface stops being a second materialize loop and becomes a one-line adapter over the walk loot surface runs, so a withheld object no longer fails it and the land gate counters fixture now measures that walk: the two promoted walks share one classifier deciding which failed reads are invisibility and which are faults, a burned read kept distinct because the surface walk labels it rather than counting it as sealed. a new test drives a withheld object through the trait and went red with object not found before the change, and red again when the adapter was reverted or the classifier arm broken. every gated counter reads the same before and after on the gated fixture, as expected for a fixture with no view and every object held. the 1703 sentence calling the gate a different loop is corrected to what it still cannot see, and the stale two-of-five counts in measure.rs, work_counters.rs and the ADR 0073 heading are replaced by what defines each set rather than a new number (#1927)
f930875a · dbf3dbe6…diff - loot show, the deletion rows of loot status and a surface listing name the published tier off the marker the object carries rather than off the .lootattributes on disk, so a published object whose rule was deleted no longer prints internal and a plain one given a rule since no longer prints published: the delta seam reads each row marker in Workspace::rows_of, off the side that carries the row, and keeps the rule for a live side (ADR 0079 section 1) and for a seal it cannot read, while the clobber guards take ResolvedDelta::classes and pay no read; surface, rehome and the pull auto-surface list through the new Workspace::with_sealed_publish_status. the status machine listing is the working tree on disk and keeps the rule. measured over a 400-path tree with the counters, every added read is a memo hit: object_gets moves by one per row with a recorded side (show of a half-edited change 1602 to 1802, status with a third deleted 804 to 938, surface --json 802 to 1203) and object_disk_reads is flat on each (601, 401, 401), a clean status is flat on both, and a hyperfine A/B over 2000 paths reads within noise (show 98.2 vs 97.3 ms, status 93.1 vs 92.6, surface --porcelain 165.4 vs 168.3, status with deletions 130.8 vs 129.8, load 0 to 6 percent). surface_object_reads counts the listing marker read apart from the opens, and the restore pin reads the seals its capture wrote. both directions pinned red first (0 passed and 2 failed with the fix undone), each through the verb: show and status deletion rows, and surface over trees ferried from git commits that delete and add a published rule. red with each piece undone, counts read each time, each restored green: the delta seam on the rule (1 passed and 1 failed), marker or rule, the overstating repair (1 and 1), the new side asked for a deletion (1 and 1), the listing on the rule (1 and 1), the listing as marker or rule (1 and 1), the guard paying the reads (0 and 2 in surface_object_reads). the published values in diff and surface machine output change for such rows and no key or column moves (ADR 0023). no format, wire or migration byte moves, so this owes no deploy. the workspace suite is green (4527 passed over 140 binaries, 13 ignored) (#2352)
0c27bd77 · 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.