Changes touching this path
- the afk loop learns which hunt opens the night, so a security or perf run files its own tickets against a stated bar instead of the backlog being the only place the night's work can come from
b8f63e6a · dbf3dbe6… - the perf gate stops reporting a run that measured nothing as a clean pass, and the load probe stops letting one bursty draw discard the measurement, because the two bracketing reads were folded by max and the second sat in the harness's own wake (#1389)
542d5442 · 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 - the three surfaces describing the perf gate stop disagreeing about what an absent metric means, because an explained absence is reported and exits 4 exactly as an unexplained one does, and each surface now points at the one that owns a fact rather than restating it — including the exit code itself, named once in loot-perf and read from that name by both the gate binary and the land (#1403)
dc3ccf75 · dbf3dbe6…diff - a perf half added tomorrow cannot go undocumented, because one table now drives the gate's parse, its usage line, its module doc and both operator docs — and the figures that had drifted from whatever owns them, including a timing resolution quoted ten times better than the shipped tolerance, point at the owner instead of restating it (#1436)
4568d998 · dbf3dbe6…diff - one whole-tree decrypt stops being spent to answer a question the first differing path already settled, and working_preview gets the in-process sample that can see it, because the cli tier could only ever ask a 476 ms process to resolve half a percent of itself (#1423)
f5ce12eb · dbf3dbe6…diff - a verb stops reading every loose object in the store before it can open one, because the open now indexes the object directory and reads the file at the address it is asked for, so one complete index still answers membership, the persist's candidate set, gc's sweep and ADR 0038's burn while a burned address keeps no route back through the directory it came from, and the sixth opt-in half that can see any of this refuses a fixture whose object directory does not hold the objects it claims (#1545)
5c98eff6 · dbf3dbe6…diff - a push's first bundle stops asking the object store about every change it has already decided not to send, because the entry's ride decision is taken before the probe rather than after it, so an entry whose bytes and key both stay home is skipped instead of being looked up and discarded — the shape #1425 removed from the follow-up bundles only — and that arm stops being unmeasurable, because --batched passes have = &[] and can therefore never enter it, so a new --push-shape half passes the change one behind the tip and refuses outright any fixture whose have does not resolve to the history behind it (#1546)
a8d1806a · dbf3dbe6…diff - a push stops walking its whole object store to answer one yes-or-no, because the unsigned-tip refusal now asks whether anything is offered at all and stops at the first thing it finds, instead of building the entire unfiltered offer and then discarding it — on every push whose relay declared heads — to walk again scoped to them; and that walk stops being unmeasurable, because no cli sample can reach it at all: the tier gives every push repetition a fresh relay, so have is always empty there and the discarding branch is never entered, which a new --offer-guard half over a 128-change history reads at 34.3 ms against 17.6 us (#1559)
dca66add · dbf3dbe6…diff - a pull, a wants answer and the relay's cache restore stop faulting the whole loose object store in from disk, because the receiver's membership question is now asked of the index that put's dedup, the persist's candidate set, gc's sweep and ADR 0038's burn already answer rather than through the read #1545 made lazy, so a held address whose file vanished under a live process is no longer re-fetched, which was a five-commit-old accident that would have asked a relay to resurrect what another process had just burned, while an address absent from the object directory at open is still named and a withheld one still asks forever (#1565)
113b4588 · dbf3dbe6…diff - a document, an ADR and five code comments stop asserting things the code does not do, because the interval a perf doc invented for its own blind fixture is deleted rather than corrected, the store census that moved three times in 36 hours is deleted at all four sites that shipped it, and every place a rotted object's failed read becomes a silent negative is now a recorded decision instead of an accident of is_ok() - including the cross-store save that dropped a held object and returned Ok(()), which now propagates (#1566)
5c97b104 · dbf3dbe6…diff - the implicit-capture door stops faulting the whole object store in from disk before every bare mutating verb, because the closure walk it gates on asks the index the membership question it always meant, and that door reaches a skip only through false so a held-but-unreadable address can no longer switch it into the narrower policy #891 wrote for an incomplete closure, while the half that watches the walk stops timing a store with no files in it (#1576)
732d63fa · dbf3dbe6…diff - a per-change cost inside the repo open stops being unmeasurable, because the open now has a depth axis beside #1545's width axis: a --graph-load half over a chain of N changes, whose control refuses a depth-1 fixture outright instead of letting it report the absence of a workload as the absence of an effect, which is what parked #1547 and #1548 while both were correct (#1571)
10730151 · 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 - head count and grant count stop being fixed at trivial values in every fixture, because the harness now carries a fan whose heads the union folds one complete manifest apiece and a tree whose custody manifest the per-path gate has to descend, each built only after its own ceiling was measured first at 2,000 exact heap allocations per additional head and a 30x step from an empty manifest to one grant per object, while the three axes whose ceilings came back flat are recorded on the issue instead of built and the head fixture is a correctness instrument too, because a chain admits exactly one topological order and every fixture here was a chain (#1601)
b98b1efc · dbf3dbe6…diff - the land gate stops watching only what a run produces and starts watching what it does, because two work counters now ride the untimed batch it was already measuring so they cost no fixture, no repetition and no workload_id move and orphan no baseline, while the twelve opt-in timings stay ungated on the argument that a timing is dropped by the load policy exactly on the busy machine a land runs on, and the count feature stays off by default because turning it on in a manifest was measured to change the loot.exe a plain workspace build produces (#1602)
f641ea1d · dbf3dbe6…diff - the perf skill index stops stating a gated status that nothing checked, because the work-counters row now carries a sentence generated from Work::ALL and gate::COUNTERS rather than one written by hand, which is how it came to read not recorded and not gated for a whole land after #1602 gated two of them in the very commit that corrected three other passages of the same file, and the four claims from the same arc that outran their code are fixed at both copies each: the loot-count module doc now carries the amendment ADR 0073 made to its verbatim twin in ADR 0072, ADR 0072 counts five counters beside a list of five and states the allocator split without a count at all, a fabricated test citation gives way to the test that really pins the gated id, and the land-time on-cost in ADR 0073 is about 56 microseconds derived from the table 80 lines below it rather than 2.8 (#1629)
f5a642e0 · dbf3dbe6…diff - the aspect a half refuses under stops being a const in the measure module and becomes a field of the row itself, built by a macro so a row names its fixture and never the sentence, because that was edit site 9 and the census that called it fictional had missed three module-level consts and five of the eight function-local ones while #1601 went on to pay it twice more; the five defaults each Workload constructor re-listed collapse into one plain base; and the two-edit promise is restated with the scope a throwaway half on a new axis measured, seventeen structural sites down to twelve, the last silent one now failing a test because a dimension added without an arm in Workload::id makes two fixtures report one workload_id (#1633)
c2a454dc · dbf3dbe6…diff - six sentences that read wider than their subject are narrowed rather than deleted, because in at least two of them the sentence is the argument: the verb tier's width figure stops being typed at all and is generated off the impl blocks with the predicate written beside it, since this ticket's own 244 is not reproducible under any predicate - pub fn alone gives 202, every fn including test-gated gives 320, production-only gives 309 - which is the ticket committing a mild form of the class it was filed about, as was its claim that the figure had gone stale a second time when git log -S finds the sentence written once and never corrected; finalized_anchor is repointed to the two hops it really takes rather than dropped from the list of delegates; the duplicated surface tail is extracted and not deleted because BOTH copies are live, one a trait method the bench calls and one the escrow-promoted twin, so establish-which-is-live had the answer both; thiserror leaves two manifests that never derive it, each row replaced by why the absence is deliberate now that RepoError is loot-codec's type re-exported; the push-shape row is documented and pinned rather than renamed, because a metric string is output and this change is behaviour-neutral, and the new pin found the drift is two rows and not one; and the whole cost of opening a repo is narrowed in all three live copies rather than the single one named here, since correcting one of three is the trap #1629 records, while ADR 0012's copy stays because its subject is the loose-object slice and not the harness. one finding was simply wrong and is reported as wrong with no edit, since run_checks has a production caller and fourteen tests and the file this ticket cited does not exist. and load_from turns out not to be what the open calls at all: assemble asks load_from_needing with the verb's declared RepoNeed since #1536, so the timed call is the widest spelling rather than the live one, which is now said in both places that time it (#1656)
44b5b98a · dbf3dbe6…diff - loot ferry parses both policy files once per commit instead of once per changed path, and the instrument had to be built before the fix because PolicyLoads sat on Attributes::load while both ferry doors call parse, so the counter read a structural zero over this whole path and would have read zero after the fix too - a 0-valued counter being indistinguishable from one watching code that does not run. The tally moves to Attributes::parse and Ignore::parse_recorded rather than being routed through a counted door, because the fix itself removes those door calls: a counter on them would read zero afterwards, which is the same blindness relocated. That changes what the counter MEANS, from policy file reads to policy re-derivations, so all three existing pins were re-read rather than adjusted until green - status moves 2/3 to 3/4 with the +1 being its single Ignore::load now counted, and the point is that the GROWTH half passed untouched (narrow equals wide) while only the constant moved, so the test is re-pinned and not re-decided; the tier-exclusion test is still green because the in-process tier links loot-core and never loot-cli, so ADR 0073's exclusion needs no re-taking; and lane_new_sweep's note that policy_loads is one per read_tree_at is repointed to two, since read_tree_at calls both loads. The instrument was proved non-vacuous against the UNFIXED code first, at 18, 66 and 258 parses over four commits of two, eight and thirty-two changed paths, which is exactly 2 plus 2 times commits times width; after, it is 2 plus 2 times commits, so 258 falls to 10 at width 32 and stays 10 as width grows. The most useful thing learned here is a red proof that inverts an assumption: blinding the instrument by putting the tally back on load makes the counter read a constant 1 everywhere, so the constancy pin passes AND the parses-greater-than-zero guard passes, and only the GROWTH assertion catches it - a positive-value pin does not protect against a blinded instrument, which is what ADR 0072's controls bullet credited it with, and that bullet is corrected rather than left standing. This ticket's own wall clock does not reproduce and is corrected rather than repeated: the removed re-parse is 4.63 microseconds per path in release against this repo's real policy files, not 22.0, so a full-history ferry is about 1.9 seconds rather than 8,819 milliseconds - 22.0 is close to the debug reading of 31.53, so the hunt appears to have measured a debug build, and a figure taken under a different build is not a smaller version of the same number. ignored_under is deleted rather than kept as a pure forward once the parse is hoisted, and ADR 0028 is amended because it argued its delete-arm decision partly on an Ignore::parse per deleted path, a cost that no longer exists - the decision stands on the attribution argument, which was load-bearing anyway. seal_under takes a parsed Attributes and narrows pub to pub(crate) since Attributes is crate-private, and its doc said it keeps the bridge from re-parsing the policy twice per path, which was true about the wrong unit: it halved a cost that should never have been per-path. One honest regression is recorded rather than hidden: a deletions-only commit now costs 2 parses where it cost 0, because the hoist is unconditional (#1704)
1822132f · dbf3dbe6…diff - ancestor_closure stops re-walking the whole ancestry once per seed, and unlike its two siblings from the same hunt this ticket's numbers REPRODUCE in release - 94.97 ms against a claimed 101.1 and 383.9x against a claimed 424x, both within ten percent - so the debug-build correction #1704 and #1702 each needed does not apply here and the ranking that placed this finding stands. What does repeat is the other family trait: this ticket also said the fix already exists one file away, and that was wrong again, though for a narrower reason than #1702's. GraphView::ancestor_closure is NOT set-identical, proved by running rather than assumed - it seeds its out set with whatever it is handed, so an unrecognized seed comes back inside its own closure where the per-seed loop skipped it through graph.get(h).is_some(). A probe printed DagRepo 0 against GraphView 1 for a stranger alone and 6 against 7 mixed, differing by exactly the stranger, and this is not a corner because sync.rs hands it a PEER's declared heads. A dangling parent reached mid-walk is kept by both, which is why the fix is the shared walk plus a SEED filter and not either one alone. The instrument was blind for a reason worth naming precisely: --push-shape passed vec![parent], which is the shape of a /haves REPLY, where sync.rs passes that id's whole closure - so the half was already not describing the code, making this #1576's extend-in-place case rather than #1425's honest-but-narrow one, and #1702 had re-based the same readings one commit earlier so there was no unbroken series to protect. Widening it moved the instrument 4.9x against the UNCHANGED engine, 273 microseconds to 1.33 ms at 200 by 128, which is the non-vacuity proof taken before any fix was trusted. After, the quadratic term is gone: per doubling of depth the cost grew 2.8x, 4.0x and 4.3x before and grows 1.2x, 1.4x and 1.6x after, and at depth 512 the half reads 22.713 ms against 0.608. The evidence is therefore a THREE-point chain and not a pair - the landing position's 273 microseconds, the widened fixture on the old engine at 1.33 ms, and the widened fixture on the new engine at 283 - and only the last two are the A/B, because the first is a different fixture; reporting the outer pair alone reads as a regression, so that rule is written into HUNT-PERF.md rather than left for the next reader to rediscover. The control on the widened have is the part most worth recording: the first version was a count-nonzero floor, and a two-element have of parent and root clears a floor of two, passes coverage, and still seeds a 127-deep walk twice - about ninety-nine percent of the blindness back with every control green. It is now set equality against the have's own closure, the fixed point sync.rs actually passes, with a negative arm proving that closure is a fixed point and a red proof that reverting to the floor fails on the two-seed case (#1700)
04859438 · dbf3dbe6…diff - BOTH READINGS WERE RIGHT and the contradiction was a DENOMINATOR: #1536 made a repo open stop materializing half a million manifest entries, which is the very call graph_load times, so the same absolute saving of one to two milliseconds at depth 1024 was 0.9% of a 189 ms open before that landed and 11% of a 10.4 ms open after it. measured across that one commit rather than argued - 155.89 ms against 10.36 ms at the SAME workload id, 15x from a change that touched neither the scan nor the fixture - and corroborated by the scaling signature, since before it the depth ratios are 2.01 and 2.06, LINEAR, with the manifest term burying everything, and after they are 2.25 and 2.69, superlinear, with the quadratic term finally EXPOSED. the fixture never moved. the general rule is now written where the next run will read it: A PERCENTAGE IS A RATIO, so a landing that shrinks the DENOMINATOR flips a verdict without touching the change, and same flags is necessary and not sufficient - record the absolute beside the ratio and the growth beside both. re-measured at the depths the ticket comments ASKED FOR and never got, 8192, 16384 and 32768, interleaved, thirty runs, all exit 0: minus 55.7%, minus 81.5% and minus 91.3%, disjoint at every depth, and the claim is about SHAPE rather than percentage - per doubling the old engine grows 2.70, 5.06 and 4.32 while the new one grows 2.12 and 2.02, which is the sum-over-k term leaving and a linear load remaining. nothing is claimed at 1024 and the old claim is WITHDRAWN, the point replaced by a dated spread carrying all thirty raw readings. #1547 figures are marked the same way, because they are pre-#1536 too and equally un-reproducible - their percentages stand, since both sides were taken on one engine, but their absolutes are marked NOT A BASELINE rather than silently re-used, and the ratio is deliberately NOT re-derived because that is a measurement nobody has taken. and the refcount preference is answered honestly rather than defended: the land DID reverse a recorded preference without saying so, the two shapes answer DISJOINT halves, and on the callers that keep the scan - the ingest paths, the two-sequence rewrite and a third site nobody had listed - the refcount REMAINS THE BETTER ANSWER (#1860)
e3c5456c · dbf3dbe6…diff - the adopt and ferry re-read stops deep-copying a pool it is about to drop, and the instrument that can SEE that was built first, because NONE existed: measure.rs had no reference to ingest anywhere, and both depth-capable halves time DagRepo::load_from, which is the OPEN - ingest_shared_lineage re-reads the shared graph AFTER it, so no fixture built on load_from executes a line of it at any depth. the new opt-in half sizes #778 own reproduction: a dock owns the store and records one change of its own, then a lane over the SAME shared store lands a depth-change line into the graph file while the dock heads file stays put, so an open of the dock is filtered back to its one change and the landed line is exactly what the ingest must splice. the instrument is proved by a POSITIVE CONTROL rather than by an argument that it ought to work - the clone line made knowingly expensive moves the number 168.3 to 188.5 to 203.7 ms at one, two and five copies, while the graph-load half on the SAME knowingly-wrong binary reads 10.30 ms UNMOVED. the ceiling was measured before the percentage was trusted: a second discarded read_graph takes depth 1024 from 171.2 to 322.9 ms, so the EAGER graph decode is about 89% of the timed region, because this seam uses read_graph while the open uses the deferred read_graph_required of #1536 - a real and much larger finding, deliberately NOT made here, written down at the call site with its correctness question, which is that the deferred manifest holds an Arc into the buffer this function drops. the change itself is the #1547 arrangement at the other site of the same shape: collect the walk order as IDS, then MOVE the nodes out with remove instead of cloning them. the re-read semantics are untouched on purpose - same node set, same emitted order, same insert rather than from_parents_first, because this is a splice into a LIVE graph, and refresh_objects_loose and the keyring catch-up still run AFTER the splice, which is #778 ordering. it MOVED: interleaved, ten reps a side, every run exit 0 and carrying a VALUE rather than reading skipped, with the idle probe at 2 to 8 percent - min of ten per round goes 185.1 to 145.6 ms at depth 1024 and 375.1 to 291.9 at 2048, sets DISJOINT at both, and the graph-load half flat as the negative control. the magnitude is qualified rather than quoted flat: an earlier pair of the same two engine sides read minus 10.0 and minus 10.9 percent, and re-running all four binaries interleaved reproduces each level to within one percent, so the shift is CODEGEN LAYOUT rather than machine state - direction certain, sets never overlapping, minus 10 percent the conservative figure, recorded at the code. and one doc claim is REFUTED rather than restated: the function said the parents-before-children order is why head tracking stays exact, and the mutation that reversed the order came back GREEN, because the splice goes through insert, which is right under any arrival order - so the sentence now says what the order actually buys, and no pin was added to assert a courtesy (#1572)
ff123eb9 · dbf3dbe6…diff - the open two biggest arms become COUNTABLE, so a regression in them can fail a land instead of passing all three checks: store.rs held no instrumentation whatsoever, no Work, no tally, no bump - and that NEGATIVE was re-verified before anything was built on it, because a negative that has quietly become false is exactly how this class of blindness starts. every line number had moved and every one is re-derived: the graph read at 2200 rather than 1993, the keyring read at 2228 rather than 2019, the two call sites at 4467 and 4510 rather than 3468 and 3502. the unit is READS, one counter rather than a pair, and the reasoning is recorded rather than assumed. a byte count is NOT 0%-gatable here, being a function of fixture contents and encoding, so every format change would fail a land for a reason its author cannot act on - and tolerancing it instead re-creates precisely the load-sensitive alarm ADR 0073 rejected the timings for. at this seam a byte count would also be blind to its own stated reason, since the lazy half of #1536 already landed and read_graph_required still reads the file WHOLE while deferring the per-change manifests, so bytes READ did not move for #1536 and will not, while bytes DECODED are a different counter at a different seam whose value depends on which manifests a verb happens to touch. the object pair precedent does not transfer either: those are two because a MEMO sits between them, and nothing analogous splits a metadata read. disjointness is BUILT rather than assumed, because object files are whole files in the store too - the object store now reads through its own door, same body, same retry budget, no tally - and the two of that door four sites which tally NOTHING today are named in the code and deliberately left alone, since closing that gap would move an already-gated number. the tally sits OUTSIDE the retry loop, because inside it would count attempts and read 1 idle against 17 busy, and that placement is pinned DETERMINISTICALLY rather than by timing luck, since an absent path walks the whole budget by construction. the structural-zero bar is met by SHAPE rather than by not-zero: across a tenfold fixture the object counters go 60 to 600 and 20 to 200 while the store counter STANDS STILL AT 24 - per-open and not per-object - and no tally left on the object door, nor one that had picked up a per-path read, can produce that pair of lines. four mutations with counts read, and the discrimination one is a discrimination rather than a constant because it ALSO fails the excluded-counters pin, catching it from both directions. the gate was then run for real in a release build: exit 0, the workload id UNMOVED so no baseline is orphaned, and the new metric absent from the baseline, so the first armed land records it and the land after that is armed. and ADR 0073 consequence clause is amended exactly where it read as full coverage, with the correction stated in as many words, alongside its table row, its status header, and six other surfaces carrying the same claim (#1662)
904f6996 · dbf3dbe6…diff - the harness gains the dimension that dominated it, and the axis is PROVED against the binary that carried the cost rather than added after the fix and trusted: a clone at the parent commit, running the same fixture through the same timed call, reads 171.0, 388.8 and 870.6 ms at 218, 436 and 872 paths a change where the lane reads 10.5, 18.0 and 35.4 - so the axis MOVES, 16.3 then 21.4 then 24.6 times, and the pre-fix side grows 2.27 then 2.24, linear in the axis, which is the changes-times-paths term. at 436 by 1024 it is 0.87 microseconds an entry against the ~1.02 implied by the original 507 ms over 494,810 entries, so the fixture STANDS IN for the real open rather than gesturing at it. the GRAPH_LOAD question is MEASURED rather than assumed, and the ticket own correction is confirmed while its stronger framing is refuted: at its pinned width the parent binary reads 155.6 ms against the lane 9.7, a sixteen-fold step, so that half WOULD have moved - its weakness is MAGNITUDE and FRAMING, 200 paths against this repo ~436 average and an id_key that presents it as graph load, not structure. only REPO_OPEN is structurally blind, because depth one pins the dimension at its identity value and one change cannot observe a quantity summed across the graph at any width. the control has three arms and none is implied by another - floors, then INTERCEPT on what the opened graph actually binds, then RESPONSE, where the same generator at HALF the declared breadth must carry exactly that many fewer entries - and the response arm is the one a count cannot supply, since a fixture pinned at one width passes the intercept whenever the flag happens to name that width. that independence is MEASURED and not argued: a discrimination pair reddens one arm each, and a diagnostic re-order shows the first mutation still trips the intercept when the response arm is asked first. the after column is deliberately NOT called flat, because it is not: 1.73 then 1.95, since a wider manifest is more bytes to FRAME even when nothing decodes them, and the row doc says so. the negative control the comment supplied is taken and then made DETERMINISTIC rather than left as a timing - a topology-only walk holds node count, parent edges and head count IDENTICAL across a doubling that moves the open by 97 percent. no counter is folded in, because #1662 is the counter half of this territory and the two are alternatives to choose between. and the blind-instrument roster is deliberately NOT given a row: that table is scoped to one run and says so, so the new kind joins the paragraph already carrying the later members, leaving the count sentence and its pin untouched (#1670)
5334741c · dbf3dbe6…diff - three sweeps running, the commit that DELETES an asserted-complete list writes a new one in the sentence that replaces it - so the recurrence itself is recorded as a named shape rather than fixed a fourth time and forgotten: the replacement is where the next list gets written, because the author is mid-sentence explaining what the true set IS. and this change caught itself committing the class TWICE while writing, which is the evidence rather than an embarrassment - an amendment draft saying the page said twelve in FOUR places where it was five, and a draft of the replacement paragraph writing six of the NINETEEN artifacts. both numbers are gone. the six-item metadata list becomes the PROPERTY: the set is the StoreArtifact trait, RepoStore::read routes every implementor through one door, and what keeps the conclusion true as the set GROWS is each impl path resolving to a named file under the store root - verified across all nineteen, none into the object directory. the conclusion that carries the 0% gate is kept verbatim, because it was never the wrong part. a THIRD copy of that enumeration, which the ticket did not name, was found and folded in. the twelves take a RULE rather than a sweep: drop the numeral where the sentence is a present-tense claim about the current table, KEEP it where the sentence narrates what ADR 0073 decided or refused as an EVENT. fifteen sites fixed, six deliberately LEFT - including the ADR title, which is the name the decision was accepted under, and a dated amendment recording what one mechanical edit touched, since correcting THAT is precisely the defect this ticket warns about. one of the twelves was already off by one and now states the property instead. the durable guard refuses a cardinal standing before opt-in halves across derived directories, and its LIMITS are in its own header rather than discovered later. the mutation that matters most is M2: writing todays CORRECT number, fourteen, is still RED, which is what stops the next reader fixing it to a value that expires. and the control that mattered is M3: the first draft tokenized raw text, so a count split by an 80-column comment wrap read clean - it PASSED OVER ITS OWN DOC COMMENT, which was quoting the offending phrase - and with the comment-marker strip removed and the defect still in place the pin goes GREEN, which is what proves the strip load-bearing rather than decorative. the fourth count of the roster population is deleted and all three of its escape routes closed, and the ADR stops citing a miscounting line as its authority for the run-versus-night correction, making the landing times the authority and citing that line only for the NAME. the negative-control heading is narrowed to what was actually measured, on the fixture rather than on the metric, and the two unreconciled readings of one measurement are reconciled once - where the ticket own framing was itself slightly off, since the two are the same commit pair measured in two sessions (#1907)
b781aefd · dbf3dbe6…diff - the policy counter is renamed PolicyParses and policy_parses because it has counted parses since #1704, and the policy.rs block and the ADR 0073 row now point at the variant doc instead of restating why; no stored perf record carried the old key, because the gate does not record this counter. PUSH_SHAPE_DEPTH, OFFER_GUARD_DEPTH and MISSING_DEPTH are literals rather than aliases because their reasons have diverged, and each is still 128. ride_entry takes one RideState instead of three maps, while the one_pass_bundle oracle keeps its own transcribed walk and memo so the byte-identity test still compares two walks, and still went red when the key arm was disabled. the gated counters read 743, 200 and 24 before and after (#1718)
bbd04ef4 · dbf3dbe6…diff - a deposit plan builds the tree it ships once instead of once per custody lane, and the first act had to be an instrument that could see the difference: no counter a land can read moved over a repeated whole-graph pass, so Work::GraphSorts now tallies ChangeGraph::in_order and is gated at 0% beside the object pair and store_file_reads, reading 8 on the gated fixture and one string across the drift pin repetitions. THE TICKET ASKED FOR THE TALLY TO REUSE Work::TreeWalks INSIDE finalized_tree and for ADR 0073 to re-decide that exclusion, and that was refused rather than followed: tree_walks counts a whole-tree FILESYSTEM walk of a working tree and this is a graph pass, and the in-process tier links loot-core and never loot-cli while nothing in loot-core outside its own tests calls the deposit lanes, so a tally there would have read zero on that tier anyway and the pin would have stayed green while its stated reason went false. the exclusion therefore stands unmoved on its own measurement, and the ADR records the trigger that did not fire rather than a re-decision it did not force. measured in the counter and not in wall clock: a forge plan over a fixture carrying an embargoed path, a Restricted path and the Internal default read 3 sorts before and 1 after, a relay plan 2 before and 1 after, the three lanes now taking the finalized tree as an argument plan_deposits builds once. the tips membership test inside that build became a set lookup rather than a Vec scan, which no counter can see and which is named as such rather than claimed. red under mutation, counts read each time: the shared build removed so each lane derives its own again failed the new pin (0 passed and 1 failed, graph_sorts 3 against 1, and with the forge arm relaxed the relay arm failed at 2 against 1), the tally dropped from in_order failed the anti-vacuity pin (10 passed and 1 failed) and the new pin (0 passed and 1 failed), and graph_sorts dropped from gate::COUNTERS failed four at once (7 passed and 4 failed), each restored to 11 and 1 passed. the two generated membership sentences in CONTEXT.md and HUNT-PERF.md are pasted by hand as their pins demanded, the hand-written workspace width in verbs/mod.rs moves to 390, the visibility census gains the two argument bindings the by-reference lanes create, and a count in loot-count that was wrong in the commit that wrote it is replaced by the property. no migration, no wire or format byte moves and no host behaviour moves, so this owes no deploy, though the gate records a new metric from the next land. the workspace suite is green (4174 passed over 132 binaries, 8 ignored) (#2225)
fe6a089f · dbf3dbe6…diff - the residual #1888 could not settle is settled by counting instead of timing, and the answer is that the clean pair was never in excess: a new measure half counts allocations over the whole of ingest_shared_lineage and splits the call into the eager graph read and the walk and splice, two bands that sum to the region EXACTLY, counter by counter, because the region is those two doors with a map lookup between them - the property no stop instrument can have, and #1888 recorded its own stop reading an early return as costing more than the work it skips in six rounds out of six. at the width the half pins, the pre-#1572 clone spelling put back reads 6488, 12512, 24552 and 96803 allocations at depths 8, 16, 32 and 128 against 4289, 8113, 15754 and 61606 shipped: a removal of 1.37 per manifest entry at every depth in that table and of 33.9 to 36.4 percent of the region, both arms linear with per-entry slopes agreeing to four significant figures, so the same fit carries the depth #1888 measured at to about 281000 removed allocations out of 771000, or 36.5 percent of the times the region reaches the heap. THE TIMED BAND WAS NEVER A CEILING ON THIS CHANGE: the walk and splice the stop instrument left 16.2 ms, a tenth of the region by time, makes 37 percent of it by allocation, so a clean delta of 13.6 percent sits BELOW the share of the work the change removes rather than above it, and nothing is left over to explain. the published magnitude does not move, because a count does not convert to milliseconds and this instrument prefers none of the three timings - what is withdrawn is the reason to distrust the largest of them. no opt-in half is added and Fixtures::gated is untouched, because a land builds release, where the allocation control refuses rather than reporting a false zero, so this reading is a test one taken by hand: its own binary installs the allocator no library may install, opens on require_allocation_counting, and carries an ignored sweep. HUNT-PERF gains the marginal-cost trap it was missing, with the measured instance where a discarded second read reads over 100 percent of the region it is supposed to be a fraction of, the band decomposition that replaces it, and the note that a summing decomposition is still a perturbing one. red under mutation, counts read each time: the clone spelling restored failed the splice-band pin (2 passed and 1 failed, 190 allocations against 73 entries), the pool read moved outside its band failed the sum control in all three (0 passed and 3 failed, 65 against 272), the global allocator removed failed all three on the control itself (0 passed and 3 failed), and a fixture ignoring the declared width failed the scaling pin (2 passed and 1 failed, 0 entries added), each restored to 3 passed. no migration, no wire or format byte moves and no host behaviour moves, so this owes no deploy. the workspace suite is green (4177 passed over 133 binaries, 9 ignored) (#1890)
4c6b019a · dbf3dbe6…diff - the figure the #1890 verdict rests on is now a column in the table it was missing from, taken the way that table was taken: the pre-#1572 clone spelling put back and the ignored sweep run once per arm, which reads the splice band at 41.3, 39.2, 38.0 and 37.2 percent of its own region on the before binary against 11.2, 6.2, 3.4 and 1.3 shipped, so the 37 percent the conclusion turned on is readable from the tree instead of from a session transcript, and the re-take reproduced every before and after cell already there to within one allocation. THE VERDICT IS NARROWED TO WHAT THE COUNT SHOWS: withdrawing the band ceiling and confirming the clean delta are separate acts and only the first was done, because a count does not convert to milliseconds - what is retired is a contradiction between two readings rather than the spread among the timings, and the published magnitude stays where they left it. two precision defects in the #2242 retraction go with it: the move over that size range is about 4.8x in the call and about 3.4x as a process and the sentence now names which, and rests on one reading is withdrawn because #2223 records no repetition count for its whole-verb rows, so what is known is that the figure does not reproduce and not how it was taken. the sweep doc had its axes inverted against the code under it and now states the property instead, that the shapes fall into runs holding one axis while the other moves, and the list class is answered for the third time in this run by replacing the two named untimed controls with the questions that decide membership. the duplicated in-loop guards are extracted: prove_the_position_has_not_ingested and prove_the_tip_was_spliced are asked by the timing and the count alike, each refusal written once and true of both. the named positive control is refused rather than built, because an in-tree knowingly worse arm means a wrong body in production code, and the before column now published stands in its place. sdk records the node type-stripping floor its .ts import imposes in engines, where npm reads it. red under mutation, counts read each time: the position control inverted failed all three allocation pins (0 passed and 3 failed, naming a position holding 1 change), and the splice control fed a false answer failed all three on its new text (0 passed and 3 failed), each restored to 3 passed. no migration, no wire or format byte moves and no host behaviour moves, so this owes no deploy. the workspace suite is green (4179 passed over 133 binaries, 9 ignored) (#2247)
c8b11725 · dbf3dbe6…diff - HUNT-PERF gains the trap #2223 was filed on: the last cell of a sweep has no neighbour past it, so the outlier check that caught a 1,091.9 ms reading mid-axis had one side to hold the 226.2 ms reading at 128 KB against, and #2242 found that figure reproduces in neither arrangement it took. the entry says what is known and no more, since #2247 withdrew the claim that the figure rested on one reading; it names the arrangement of each ratio, 4.8x in the call and 3.4x as a process, and records the refutation leaning on the same end cell until #2242 carried the axis to 1 MB. the remedy is stated as a property rather than a number of sizes: a cell a finding is filed on needs a neighbour on both sides or a repetition spread reported with it. prose only with no behavioural seam, so there is no mutation proof; the generated work-counter cell is untouched and work_counters reads 12 passed before and after. the workspace suite is green (4254 passed over 135 binaries, 10 ignored) (#2245)
1e60a43b · dbf3dbe6…diff - the graph rewrite a finalize pays reads the graph file back deferred and copies each manifest stored frames where Manifest::frames proves them to be what encoding its map writes (no backslash key, keys strictly ascending in Path order, UTF-8 holder names), and falls back to the eager read otherwise, so save_to no longer decodes every path of every change in history to add one change. the new --graph-rewrite opt-in half times that whole save at 200 paths; paired, three interleaved rounds, the gate reading load idle at 1 to 4 percent: 48.18 to 48.48 ms down to 12.65 to 12.72 ms at depth 256, 183.43 to 183.49 down to 39.14 to 39.47 ms at 1024, and 750.3 to 759.4 down to 179.5 to 182.6 ms at 4096. counted by the new graph_rewrite_allocations test, the save at depth 1024 allocates 6,039 and 6,061 times on two runs against 695,198. the file written is byte-identical to the decoding rewrite, pinned over every golden and a lone y//ab key (copied), the legacy separator and the #2273 shapes (not copied, rebuilt from the eager read), and a key or holder name that is not UTF-8 (not copied, and the save still refuses it). red under mutation, counts read each time: the eager read put back (1 passed and 1 failed), the holder check dropped, the ascent check dropped and the eager fallback dropped (1 and 1 each), the counts check dropped (0 and 2), restored to 2 passed each. riding along: HUNT-PERF names the new half, and the visibility census names the moved and new bindings. no migration and no format byte moves, so this owes no deploy. the workspace suite is green (4278 passed over 137 binaries, 11 ignored) (#2280)
e7d666e0 · dbf3dbe6…diff - the review-sweep fix-up over #2280, #2281 and #2282. the closure-walk pin stored x/abc after x/ab, which a random address beginning with c completes, so its stored-once control failed 5 runs in 400; it now uses y/abc and read 400 of 400 green. the spliced-node pin claimed the tree a later save writes back, but that save writes the copy the graph file already holds, since the rewrite inserts what it reads back first and ChangeGraph::insert keeps the first node for an id; it now saves into a store with no graph file, the splice comment says why, and a splice that blanks each spliced manifest goes red on that assertion (0 passed, 1 failed). decided and pinned: an ingest past a key or holder name that is not UTF-8 in a node it does not splice returns Ok and the next rewriting save refuses, kept because the open already defers such a file and stepping every pool node reads 13.8 to 14.4 ms beside a 54.4 to 55.0 ms deferred read of this repo graph file (red when the check scans the whole pool and when the save fallback is dropped, 0 passed and 1 failed each). measured with a tracking allocator over that 85.7 MB file: the rewrite union holds 88.2 MB deferred against 222.5 eager and peaks at 193.9 against 382.0, both freed when the save returns; a pool keeps one copy of the file per read that splices, 85.7 to 342.7 MB over one to four reads against 1.2 to 6.7 eager, recorded at the splice. the move-not-clone property lost its count pin to deferred manifests (a clone costs about two allocations per spliced node, 78 against 65 at the pin shape) and is pinned by the pool ids instead (red under the clone, 0 and 1). the closure walk doc names the holder-name case where it answers and the decoding walk panicked, pinned (red when the ascent check also steps holders, 0 and 1). each mutation restored to green. list-class sentences in HUNT-PERF and the loot-perf fixture rows now name what defines the set of graph file reads, and a rewrap leftover and a stale keys_ascend reference are fixed. no migration and no format byte moves, so this owes no deploy. the workspace suite is green (4285 passed over 137 binaries, 11 ignored) (#2287)
a8c863e3 · dbf3dbe6…diff - loot blame and loot log --path read the one path they ask of each change through the new GraphView::address_at, which answers off the manifest frames through the new Manifest::address_of where the frames provably are the map (no backslash key, keys strictly ascending in Path order, checked by the keys_ascend step Manifest::addresses uses) and from the decoded map otherwise, so a history walk no longer decodes every manifest on the lineage to read one entry of each, and blame no longer clones each tree; has_path keeps decoding, since its remaining production caller asks many paths of each of a few changes. the new --path-history opt-in half times address_at over every change of a re-opened chain at 200 paths, asking the path that orders last; paired, one loot-perf-gate --features count built per arm with the frame arm never taken as the before, interleaved, the gate reading load idle at 1 to 4 percent (peak 7): 34.87 to 34.97 ms down to 4.46 to 4.53 ms at depth 256, 138.8 to 139.3 down to 18.01 to 18.03 at 1024, and 279.2 to 280.6 down to 35.9 to 36.2 at 2048; counted by the new path_history_allocations test at width 200, the walk allocates 484,352 times at depth 1024 against 0. through the binary, against the landing position binary over a repo 1,025 changes deep and 203 paths wide, min of 15 over two rounds: loot blame 160.4 to 160.6 ms down to 33.7 to 33.8, loot log --path 164.8 to 165.8 down to 43.7 to 44.0, plain loot log 28.9 to 29.2 on both, and every output compared was byte identical with its exit code and stderr: blame plain, --porcelain, --json, with a selector and on an absent path, log --path on flat, nested, dotted and absent paths, and shortlog --path. new pins: over every golden, a file whose Path order is not its byte order, the legacy separator file and the three #2273 shapes, address_of answers what the eager map answers for every key and for probes that are not keys, decoding nothing exactly where the frames are the map, and it answers off the frames past a holder name that is not UTF-8; a spawned blame and log --path find a/b.txt beside a-b.txt and a.txt. red under mutation, counts read each time: the frame arm never taken (0 passed and 1 failed in the codec pin, 1 and 1 in path_history_allocations), the ascent check dropped (0 and 1, on the answer), the counts check dropped (0 and 1, on the control, since Windows reads a backslash as a separator), byte order in the stop (0 and 1 in the codec pin, 0 and 1 in the spawned pin), each restored to green. riding along: HUNT-PERF names the new half. no migration and no format byte moves, so this owes no deploy. the workspace suite is green (4289 passed over 137 binaries, 12 ignored) (#2283)
045c7e42 · dbf3dbe6…diff - the review-sweep fix-up over #2287, #2283 and #1986. a resumed pick now asks again about a path its stop asked about when the record holds no answer for it, rather than handing it to the three-way, which merged over the resolution and put back the edit it rejected: change_delta_merge takes the stopped record whole and takes every question on it out of the three-way, keeping an answer only where the line still holds it, so a resolve that recorded no answer (a loot from before #1986, or a failed answer write, which the workspace comment now truthfully says costs a re-ask) re-stops with nothing applied, keeps the restore point, and lands once the question is answered again; refusing --continue was weighed and rejected in the ADR 0080 #2291 amendment, since nothing would be left to resolve. the replay reads its direction from pick::SPECS, which now pairs each spec with it, and a record naming a version under a verb SPECS does not hold refuses instead of replaying as a cherry-pick. the usage note names no verb, so each stopping verb line is true of its own verb, and its test now fails if the note names a verb that replays. a cherry-pick replay to completion is pinned through the binary on the home position, a pinned primary and a lane. false sentences fixed: the in-progress operand reader, the pick stop comment, the resume test doc link, the continue_clause list, the CONTEXT.md in-progress entry and HUNT-PERF on graph file reads; rewrap leftovers in fixture.rs and engine.rs are fixed, and the replaying tests keep their resolution file outside the working tree. red under mutation, counts read each time: questions taken from the answers alone (16 passed and 1 failed in the loot-core pin, 31 and 2 through the binary), an unknown verb replayed as not inverted (20 and 1), the note naming cherry-pick and revert again (19 and 2, the second the census the usage lines no longer matched), each restored to green. no migration and no format byte moves, so this owes no deploy. the workspace suite is green (4309 passed over 138 binaries, 12 ignored) (#2291)
812c48c7 · dbf3dbe6…diff - the review-sweep fix-up over #2291, #2043 and #2080. loot verify no longer walks past the deferred-bodies refusal: it finds its store by layout through resolve_store_dot and never met the record, so in a store carrying .loot/deferred-bodies it reported a body it had never fetched as missing, and verify --accept-loss wrote that body into .loot/lost as unrecoverable while the remote still held it. the refusal is now decided once, in BodyNeed::admit, which the open (Workspace::assemble) and the layout door both call, so the doors it guards are that function callers: resolve_store_dot takes a BodyNeed, verify declares Held and is refused naming the state, and doctor and config declare the new Unread, since they read no body. the relay doors take none, and loot_net::is_relay records why: each refuses a store without the relay role marker before reading an object, no code that writes the record makes a relay, and gc there removes only objects the store holds; gc --dir, count-objects --dir, relay reap-grants, relay abandon-head and serve --dir were each driven through the binary at a deferred store and each refused it. the refusal now says the verb did not declare it fetches first rather than that it reads a body, since whoami, status and log read none, and doctor, ADR 0093 section 3 and CONTEXT.md say the same; section 3 is restated as the property and records the #2295 correction. false sentences fixed: the counts beside GATES in spawn.rs and orchestrator.rs now point at the rows, the sdk gate doc and SDK_GATE_STEPS say build:wasm can reach the network and refuses rather than degrading there, the in_progress verb and operand docs state the property instead of listing verbs, HUNT-PERF stops counting the reads around the graph load, and the rewrap leftovers in the land-change skill and ADR 0071 are fixed; resolve_store_dot also gets back its own doc, which sat on registered_peer_keys. red first through the binary: verify answered 1 missing (0 passed, 1 failed). red under mutation, counts read each time: verify declaring Unread (1 passed and 1 failed), verify refused but --accept-loss let through, which accepted 1 missing object as lost (1 and 1), the refusal in admit keyed on the wrong need (0 and 2), each restored to green. no migration and no format byte moves, so this owes no deploy. the workspace suite is green (4323 passed over 137 binaries, 12 ignored) (#2295)
ded7dfa3 · dbf3dbe6…diff - the review-sweep fix-up over #2295, #2096 and #2137. the discovering layout door takes its caller body need: workspace::ambient_store_dot, which fixed BodyNeed::Unread and so would have admitted a body-reading verb that found its store through it to a body-deferred store, is now discovered_store_dot(start, bodies), passing the need through to resolve_store_dot, and loot doctor declares Unread at its call. ambient_local_config keeps a fixed Unread, since it hands back the config path and lane id rather than the store, and its doc says so. pinned in workspace.rs: a Held caller is refused naming the state from the root and from a subdirectory, an Unread caller still finds the store, and the same repo before the record is the control; red first with the need ignored (0 passed and 1 failed), red under mutation with the door fixed at Held (0 and 1), restored to green. the refusal text, the doctor bodies line and the ADR 0093 section 3 heading now say a verb that declares neither that it fetches first nor that it reads none is refused, since Unread passes. set sentences replaced by the property in workspace.rs, CONTEXT.md and ADR 0093: a door that finds a store without reaching BodyNeed::admit is unguarded and whether that is safe is a question for that door, is_relay is recorded as why a relay store needs no guard, and a verb behind an admit door meets the refusal unless a need other than Held is named there. the site marker pin: the hash now covers every module the page reaches by a relative import, so RETENTION_DAYS on /privacy moves it, and the privacy pin is re-pinned with its date unchanged; the scan reads markers with comments stripped, so a comment saying last updated no longer makes a file unreadable; the header defines a dated marker as the words last updated and says why the known-issues Last reviewed date is left to its own pins. red first against the old test, counts read: RETENTION_DAYS moved to 31 stayed green (9 passed), a terms comment saying last updated went red (2 failed and 6 passed); with the change the first is red (1 failed and 10 passed) and the second green (11 passed). red under mutation: the import reach dropped from the pin (1 failed and 10 passed), comment stripping dropped from the marker read (1 and 10), the import walk reading nothing (2 and 9), each restored to green. stale sentences fixed: HUNT-PERF names every other read the open makes rather than the reads in the body of assemble, the in_progress verb is the verb that wrote the record rather than a STOPPING member, the SDK read test no longer calls its shape the one where the head derivation is load-bearing, and repo.ts and the ChangeView doc name the superseded-head half of within_depth_of_heads and say its working-change branch is not mirrored. no migration, no format byte and no published wording moves, so this owes no deploy. the site gate is green (680 passed and 62 skipped over 62 files, 62 surfaces) with no ceiling moved, the sdk build:wasm and type-check are green, and the workspace suite is green (4324 passed over 137 binaries, 12 ignored) (#2299)
d7d5ef94 · 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.