Repository navigation
A restoration trigger prescribed an index; the mechanism it derived that from is refuted - #10757
Conversation
…hat from is refuted gunbc#10744 corrected this drop's cause from the number of reachable declarations to a rescan of the candidate pool, and derived a trigger from it: the callee lookup answers BY INDEX rather than by scanning the pool. That mechanism is refuted by execution, and the trigger it generated is therefore a repair prescription pointing at something that is not being paid. v2.std.fn_index.decls_in_modules is a plain-valued call with hashable arguments, and the v1 interpreter's eval-frame call memo is on by default (GUNBC_EVAL_MEMO), keyed by fn identity x argument identity. The loop-invariant the trigger asked a lane to hoist had already been hoisted by the interpreter: it is evaluated once per walk and served from the memo thereafter, as are repeated lookups of the same callee. gunbc#10753 built exactly the prescribed index and measured it at directory grain -- three alternating repetitions in one dispatch on one machine, only src/v2/std/fn_index.dag swapped. The verdict rule was pre-registered before the numbers existed: normalise each run by its own positive control, HARMFUL iff the AFTER range lies entirely above BEFORE. The ranges are disjoint (BEFORE 19.90/20.06/20.11, AFTER 23.07/23.51/23.56), so the index ADDS about 1.1 seconds and removes nothing. Both arms remain twelve to fourteen times the per-claim line. The FIT is unchanged and still good evidence -- O(reached x pool) agrees within 1.9x across two grains where O(reached^2) misses by 44x. The MECHANISM behind it is now UNESTABLISHED. A correct fit carrying a false mechanism is the more dangerous artifact, because it keeps recruiting repairs aimed at the wrong thing while looking already diagnosed, which is what it did to #10753. So the trigger is WITHDRAWN, not weakened. A trigger is a prescription; leaving it standing with a "the index did not help" note beside it would be the misleading artifact this row exists to prevent. The next trigger is an ATTRIBUTION rather than a repair: separate acquisition, the reachability walk and the determinism fold, and distinguish cost tracking the POOL from cost tracking what is REACHED by holding the closure fixed while the pool varies. Only then may this row name a repair. The SUFFICIENT FOR clause is untouched, including WITHOUT NARROWING THE SUBJECT. Scoping pool_roots to the reachable modules remains the trap. One observation at the grain it was taken: under claim_batch the directory-grain walk executes, completes and passes at 6-7s -- not interrupted. That establishes executability and nothing about the required floor, whose disposition for this claim is unpinned, so this row's interrupted_before_verdict cause is recorded as unverified pending required-floor instrumentation -- not "cannot finish", and equally not "finishes over budget on the floor". docs/design-rung-drops.md regenerated; the whole-tree regen left docs/design-failure-modes.md byte-identical, so this contends with nothing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CQuBs4mLu9ArojSWFiRcey
…s real Six arms, two repetitions, one dispatch, agreeing within 1%. Acquisition over the lens pool 592-597ms; the closure list 9ms; the reachability walk 4399-4412ms; the walk PLUS the determinism fold over every reached declaration's whole subtree 4341-4351ms. THE FOLD IS FREE, which refutes the other obvious hypothesis -- including the one this branch's own PR body advanced. Adding determinism_findings measured BELOW the walk alone in both repetitions. So its concat accumulator is not the cost either, and a lane that optimises it will move nothing. THE WALK IS POOL-SENSITIVE AT A FIXED REACHED SET. Holding the entry and the closure fixed -- lens modules only, so the reachable set is identical -- while enlarging only the candidate pool from src/v2/lens to src/v2/lens plus src/v2/std: acquisition 592-597ms -> 1905-1950ms, walk 4399-4412ms -> 8474-8637ms. This is the arm neither #10744 nor #10753 ran, and it is the one that separates the fit from the mechanism: #10744's pool term is corroborated, and it lives inside the reachability walk. WHICH construct inside the walk is pool-proportional remains unattributed. The per-lookup rescan is refuted, so it is something else; one candidate a reader should not skip is the eval-frame memo's own keying, which must derive a key from the pool-sized argument on every call -- a provider that removes a pool-sized scan can reintroduce a pool-sized cost in its key. Written as the hypothesis it is. Two honesty items. Whether each arm re-pays acquisition or is served from a cross-witness share is not pinned by this run, so the ratios are directional and not quotable as exact. And interrupted_before_verdict is a disposition shared across unrelated subjects -- it appears on main-tip receipts for outside_modeled_guarantee_witness_test and carrier_reference_integrity too -- so the row no longer lets a reader infer it names this population. Recorded and NOT recorded as a cost result: on main tip 9b341e1 this witness appears only in a roster membership list, not on a BLOCKING line. Those are consecutive main tips rather than a controlled comparison, so absence of a blocking line settles urgency, not cost. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CQuBs4mLu9ArojSWFiRcey
Two findings, both correct, both against DESIGN authorities this row itself invokes. FIRST: the rewrite deleted the instrument-naming sentence and expanded the transcription. The old trigger carried a re-derivation recipe; the replacement dropped it and copied in a full result table instead. That reproduces, one layer up, exactly the failure this row records -- figures unreachable from the thing that owns them, rotting untouched, with the recipe to re-derive them deleted to make room. DESIGN section 6: name the instrument, never transcribe its output. The fix is a real entry point rather than fewer digits. scratch-probe/test/claim/fn_index_attribution_probe.dag lands as the named instrument, with the claim_batch invocation that runs it, an account of what each arm isolates, and why arm f -- entry and closure fixed, pool enlarged, so the reached set is unchanged -- is what separates the fit from the mechanism. It lives in scratch-probe because it is an instrument and not a floor witness, and its rows assert only non-emptiness; that is stated so nobody reads them as coverage. The trigger now names it and states findings qualitatively. For the index comparison it cites gunbc#10753, which carries its own method and pre-registration, rather than copying that PR's figures here. Every transcribed measurement is gone from the row. SECOND: the annotation block and the trigger string had become two carriers of the same content -- the memo mechanism, the verdict rule, the ranges, the n=1 story, the fit/mechanism split, the withdrawn ruling, all in both. In a row whose subject is a duplicated authority that is the fork it exists to prevent. The typed field is the authority for how this drop ends, so it carries the prescription, the evidence and the instrument. The annotation keeps only what the field cannot: why a trigger is withdrawn rather than weakened, why a correct fit carrying a false mechanism is the dangerous artifact, and why the numbers are not written down. docs/design-rung-drops.md regenerated; design-failure-modes.md byte-identical. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CQuBs4mLu9ArojSWFiRcey
|
Both findings in review 61856 are correct and both are now fixed in code, not argued away. Finding 1 — deleted the instrument-naming sentence and expanded the transcription. This is the sharper of the two, because it is the same failure this row exists to record, committed one layer up: I removed a re-derivation recipe and replaced it with a larger pile of figures unreachable from the thing that owns them. That the row's own thesis is "a stale attributed number recruited a lane to the wrong repair" makes it worse, not better. The fix is a real entry point rather than fewer digits. The trigger now names that instrument and states its findings qualitatively (the fold is not the cost; the walk is pool-sensitive at a fixed reached set; the construct inside the walk is unattributed). For the index comparison it cites #10753, which carries its own method and pre-registered verdict rule, instead of copying that PR's numbers across. Every transcribed measurement is gone from the row — no ms figures, no normalised ratios, no percentages. Finding 2 — two carriers of the same content. Also correct, and in a row whose subject is a duplicated authority it is the fork the row exists to prevent. The typed field is the authority for how this drop ends, so One thing I did not change, so it is visible rather than silent:
|
…review 61869) attribution.probe.sh was a throwaway dispatch wrapper used to run the probe on a remote runner. It was never meant to land; a git add -A swept it into the commit, at repo root, with no header, no marker and no dissolution trigger. The reviewer is right on both counts and either alone is disqualifying. DESIGN section 6 names this shape exactly -- a hand-authored script performing out-of-band actuation -- and section 5 admits a scaffold only with a documented, bounded dissolution trigger, which this had none of. A root-level filename that reads as permanent is the worst version of it. And it forked an invocation the corpus already owns. The entry path, the three source roots and the six function names were restated in the shell script and again in the rung drop's restoration_trigger, so the two could drift apart independently: rename an arm and the script silently runs a stale --functions list while the row still reads correctly. In a PR whose whole subject is naming the instrument rather than transcribing it, this file transcribed the instrument's INVOCATION into a second, unmodeled medium. Deleted rather than modelled and marked. The row's prose already carries the recipe, so the second carrier buys nothing that would justify keeping it under a trigger. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CQuBs4mLu9ArojSWFiRcey
|
Correct on both counts in review 61869, and it is a clean catch — It was a throwaway wrapper for dispatching the probe to a remote runner and was never meant to land. A The second half of the finding is the sharper one and is the reason it is deleted rather than modelled and marked. It forked an invocation the corpus already owns — entry path, three source roots, six function names, restated in the script and again in the row's Nothing else in the change moves; the row and the probe are unchanged. |
…o wrong ones Two single-tip readings were made in one night, in opposite directions, and both were wrong for the same reason: a roster appearance and a blocking appearance are the same population sampled twice. 9b341e1 showed the witness reaching a verdict; #10764 -- eight lines of Rust comment, no .dag -- showed it interrupted before one. Since #10764 changes nothing this row reads, the intermittency is a property of main, not of any branch. The row now says INTERMITTENT, which is what the original brief said before either observation. It also records why an intermittent blocker is worse than a steady one: the principal paying the cost is not the one who caused it (DESIGN.md 1). Also declares the scratch-probe exposure: fn_index_attribution_probe.dag is cited by this row but reached by no compiled closure, so it can rot silently. The alternative -- homing it under a source root -- would put six multi-second claims on the floor, which is the worse trade. The exposure is stated rather than left silent. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CQuBs4mLu9ArojSWFiRcey
…-637-drop-trigger
…estion (review 61911) The row justified leaving the attribution probe outside every compiled closure by saying enrolment would put six multi-second claims on the required floor. That priced RUNNING the arms, but the exposure is about COMPILING them, and a compile-only enrolment buys the typecheck without running anything. The argument was wrong, not merely weak. The real reason is a boundary, not a trade: the compile-only surface is gunbc.ci_layer_roots.compile_clean_source_roots, and a root added there must also be added to the partition that dag_compile_clean_shard_a_witness_test.compile_clean_partition_boundary_matches_compile_clean_source_roots checks against it. That widens what four serial full-corpus compiles cover on every push and pull request -- a roster this repository holds closed to growth without operator sign-off, and one this lane's brief forbids outright. The discharge stays available to whoever may perform it, and the row now names it precisely enough to be taken in one edit. The probe also gets the dissolution it lacked: it exists only to attribute the cost this row leaves unattributed, so the lane that either retires the row or names the pool-proportional construct deletes the module in the same change. An instrument that outlives its investigation is residue and this one is not exempt for being cited. And arm g lands beside f, because f's whole discrimination rests on the two walks reaching the same set -- which was an argument from "the closure bounds the walk", a true fact about a different subject than what a given run enumerated. g measures the two reached-set sizes and is red if they differ; reached_sizes reports the numbers rather than only the verdict. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CQuBs4mLu9ArojSWFiRcey
|
Taken, review 61911 — and the central point is right in a way worth stating plainly rather than just patching. The argument I had written was wrong, not merely weak. It priced the cost of running the six arms and offered that as the reason they are not enrolled — but the exposure the review names is about compiling them, and a compile-only enrolment buys the typecheck without running anything. I never addressed it. That is the same shape as the errors this row exists to record: a true sentence doing duty for a different subject. What replaced it is a boundary rather than a trade. The compile-only surface is And I took (b) as well, since the review is right that it was missing entirely. The probe now carries its dissolution on the row that owns it: it exists only to attribute the cost this drop leaves unattributed, so the lane that either retires the row or names the pool-proportional construct deletes the module in the same change. An instrument that outlives its investigation is residue and this one is not exempt for being cited. I agree that a missing dissolution condition makes the finding more severe, and that One thing the same commit fixes that no review caught, because it is my own error of the identical shape: the arm that separates the fit from the mechanism ( Separately, so a reviewer does not have to rediscover it: the — sent from bright-badger-637 |
…cond one The two answered the same question -- does enlarging the pool change what the walk reaches -- so keeping both was two carriers of one fact, which is the failure review 61856 already caught in this same file. g survives because it is the enrollable form and it goes red rather than reporting. The premise it exists to test is measured and holds: both pools reach 89. So none of the f-minus-c difference is reach and all of it is pool. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CQuBs4mLu9ArojSWFiRcey
GUNBC_EVAL_MEMO=0 removes the key comparisons AND the retained entries in one move. So if the 211s frame collapses with the memo off, the keying hypothesis and the allocation-pressure hypothesis are confirmed equally and nothing is learned about which. An arm that cannot come out against the thing it tests establishes nothing, which is this repository's own rule about discriminating REDs applied to a measurement. h does the same amount of walking as g -- two full reachability walks in one eval frame -- while holding the pool at one pool rather than two, so frame retention and key diversity halve while the walking does not. Against c: ~2x means the blowup needs pool diversity in the frame, so keying survives and pressure dies; ~13x means two walks in a frame suffice regardless of pool, which points at retention or at something per-frame that is not keying at all. The two walks use different entry modules deliberately. Repeating one entry hands the second walk an argument-identical call the memo serves outright, which would measure the memo working rather than the frame cost under test. The header also now records that claim_batch reports VmHWM per PROCESS and not per witness, so peak RSS is attributable to an arm only when that arm is alone in the process -- and that frame structure is itself a variable, since c and f are separate frames while g and h are one frame each. A 211-versus-16 ratio invites a reader to assume different machines or different load; the frame is the variable and the file now says so. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CQuBs4mLu9ArojSWFiRcey
determinism_live_intra_holds runs at FILE grain over affected_set.dag with pool_roots EMPTY, and builds its closure from those same empty roots. Arm c runs at directory grain over a real root list. Those are not the same fold at two values of n -- the closure term differs structurally, and an empty root list is a term no arm above exercises. So arms i, k and l reproduce the floor's subject term by term. l minus i is what the walk and fold cost at the grain that actually blocks lanes, which is the quantity a repair aimed at the floor has to move; the directory arms answer a question about cost SHAPE and are only a magnifier if these agree. k is not a timing arm. The rung-drop row records that the floor's closure fold runs over an empty list, and that is why the witness is named intra rather than transitive. If k goes red that recorded fact is stale and the readings built on it need revisiting. It is the one arm here that can falsify a written row. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CQuBs4mLu9ArojSWFiRcey
Pre-registration: how arms
|
h ran two walks in one frame over one pool and came in near c rather than near 2c. So two walks in a frame is not enough to produce the blowup, and neither is anything per-frame that does not depend on the pool. What survives is pool diversity -- and h cannot say which kind, because one pool means one key universe AND one retained pool at the same time. m takes those apart. It acquires both pools in one frame, so retention matches g, while walking only the small one, so the repeated pool-sized probes match c. Near c+e means two-pool retention is free and the cost needs two pools flowing into repeated probes, which is the keying signature. Near g means retention is the payer and the memo-keying hypothesis is dead. Run under GUNBC_INTERP_STATS=1, which prints retained-value accounting and VmHWM, so the memory half is measured rather than inferred from time. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CQuBs4mLu9ArojSWFiRcey
Pre-registration II: arm
|
m lands at |
reading |
|---|---|
~c+e (~8s) |
two-pool retention is free. The cost needs two pools flowing into repeated probes — the keying signature, not the pressure one. |
~g (~200s) |
retention is the payer. The memo-keying hypothesis is dead, the repair is about footprint rather than key derivation, and the observation below needs re-explaining rather than keeping. |
| anywhere between (say 40–80s) | neither factor is "the payer." The single-payer framing is retired: the question stops being which of two and becomes how they compose, plausibly multiplicatively. The next arm then varies pool size at fixed diversity, to see which term carries the growth. |
The middle is registered because it is the outcome to expect if both factors are real, and it is the one most easily narrated away as "mostly keying" or "mostly pressure" after the fact.
The observation m will confirm or destroy
Flagged as observation, not result: in h the second walk cost ~0.6s against the first's ~6s, over an identical pool. So the memo is excellent on identity and catastrophic on diversity. That is a mechanism-shaped statement — it says the memo has a probe whose cost is a function of how different the keys are, which is what a structural comparison over a pool-sized value looks like and is not what allocation pressure looks like. If m shows retention is the payer, this observation needs re-explaining rather than keeping.
Why the memory half is no longer inferred
Every arm so far shares one weakness: footprint inferred from wall time. GUNBC_INTERP_STATS=1 makes claim_batch print retained-value accounting for the data cache and pure-call memo, plus VmHWM. m, c and g are dispatched under it.
And the finding that reframes the blocker, from i/k/l
ifloor acquisition alone — 27mskfloor closure is empty — GREEN, 0mslthe floor claim's body, exactly — 228ms, against a 500ms line
k green refutes the absorbing-fallback suspicion I raised in the previous comment: module_declaration_facts_live([]) returns nothing rather than walking ctx.modules. Empty roots means empty. §5 does not apply to this call, and the zero-arity ancestor's behaviour did not survive into the current builtin. Green k also confirms the rung-drop row's empty-closure fact is current and the intra rename is sound rather than a §3 meaning fork.
And l at 228ms means the floor claim run alone is at less than half its budget, while the same claim measures 503ms in CI. The claim is not slow — it is slow in company. That gap alone proves nothing (different machines, different load), so the discriminating arm is l alone versus l beside deliberately pool-diverse company in the same dispatch on the same machine; it is running now. If l inflates there, the subject is cross-claim interpreter state rather than fn_index or the lens, and every repair aimed at the walk since gunbc#10744 — including the index in gunbc#10753 — was aimed at the wrong thing.
— sent from bright-badger-637
A green run is not an acceptance test for any repair to this subjectStated now, while nobody has a repair to defend. This is the discipline that has to hold when the arms come back, so it goes on record before they do. There are at least two independent contributors to this blocker.
The methodological consequenceA claim sitting 3ms over a 500ms line in a process with 1.31×–1.80× step variance will go green sometimes with nothing fixed at all. So the first green after any change to this subject carries almost no information — and it is exactly the observation that will be offered as proof that the change worked. Acceptance evidence here must be a distribution over repeated runs, on the same machine, before and after. A single green run establishes nothing. A single red run establishes nothing either. This is the same rule this PR already applied to the index verdict in gunbc#10753 — pre-registered rule, n=3, disjoint ranges — and it applies with more force here, not less, because the margin is 0.6% rather than a factor. It also means a repair to either contributor alone will look partially effective while leaving the intermittency in place. Partial improvement must not be read as a fix. What is already established, independent of the armsWhether or not the eval-frame memo turns out to be the payer, this much is true from the code and does not wait on a measurement: a cost tier exists that the fill subtraction cannot see, and a merge-blocking per-claim budget is enforced on the difference. The measurement decides how much that matters; it does not decide whether it is true. The precise defect is not "fill is broken" — fill works, and is scoped to one tier deliberately. It is that Both of those belong in — sent from bright-badger-637 |
…utlived all of them The row had been holding its position open for a cause. That was backwards. What is established is not a mechanism but a shape -- the walk's cost is proportional to the pool it is HANDED rather than to what it REACHES -- and it is established three independent ways: the reached set is pinned equal across a small pool and a much larger one, so reach is constant while cost moves; and the cost ratio between those pools is the same with the eval-frame memo on as with it off. That third measurement is what makes it a shape rather than an implementation detail. A cost that tracks the pool identically with a caching tier present and absent is not a property of that tier, of any key, or of any index. It is invariant under every mechanism proposed here and refuted here, which is a stronger result than a mechanism, not a weaker one. DESIGN section 2 prices a proven cost-shape defect as always worth fixing regardless of realized n, and does not make that conditional on naming the cause. A measured defect with no carrier is how a defect becomes ownerless. The refuted candidate is removed rather than left standing. Its death condition was written before the arm ran -- if pool sensitivity survives with the memo off, keying is not the cost -- and it survives. Recording the death keeps the next lane from spending a dispatch re-killing it. The same arm carries a constraint the next lane will not expect: with the memo off these arms run about two orders of magnitude slower. The memo is not a cost on this path, it is very nearly the whole performance of it, and it is invisible in the .dag source -- so a later simplification that bypasses it will look clean and will make this walk a hundred times slower. And the row now says what it does not claim. Reproduced term by term at the floor's own grain, the claim runs at well under half the per-claim line, and running it beside deliberately pool-diverse company on one machine does not move it. The shape defect is real AND is not the blocker's excess. A lane that fixes the shape should expect the intermittency to survive it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CQuBs4mLu9ArojSWFiRcey
… every arm Learning that the claim's own cost is well under half the line makes a bigger line look reasonable. It is not. A budget cannot distinguish a claim whose true cost is half the line from one measured at the line when the environment is separately recorded as swinging by more than a factor of two on byte-identical evaluator steps. That is a measurement trustworthiness defect, not a threshold defect, and the repair is never a bigger number -- which is the escape hatch DESIGN section 5 forbids, stopping the refusal without stopping the wrongness. The row also carries a reading, labelled as one because it explains every arm at once and that is exactly when to be careful: the eval-frame memo is evicted per witness frame, so diversity between claims is cleaned up while diversity within one frame is not. That predicts all three observations without residue, and it carries the consequence a later lane must not miss -- the within-frame blowup does not bear on this blocker, so whoever re-derives it will have found something real and will be wrong to call it the cause. Its payer is not retention, refuted by two independent instruments; before those two, every arm inferred memory from time, so a timing result and a memory story could not disagree. And the machine-population boundary is now explicit. Every measurement behind this row was taken on remote build executors; the line is enforced on the required-lane CI runner. A distribution measured on the first says nothing about the second. The instrument gap is declared with its trigger named as a capability rather than an artifact. The analysis already exists and must not be re-minted -- gunbc.floor_cost_distribution models the cost as a coproduct so a censored bound cannot be divided as a cost, and identity_inflation_permille_at_equal_work already pairs rows by identity and equal evaluator steps. What is missing is an actuator that can run it on demand, and the one that exists runs only inside CI. An actuator that reaches only a build executor does not retire the trigger, because it cannot observe the population the refusal fires on. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CQuBs4mLu9ArojSWFiRcey
Harvest the retained required-floor claim-cost artifacts from successful main runs, take this claim's rows, and group by eval_steps so work is held constant -- which is what the existing pairing authority exists to do. Eighteen of twenty recent runs share one step count. Across those eighteen, at byte-identical evaluator work, with no change to the claim and none to the tree, observed CPU spans nearly 1.4x and its top reaches 99% of the per-claim ceiling. A claim whose cost distribution at fixed work already touches its own line needs no cost defect, no drift, no accounting hole and no mechanism to refuse intermittently. It needs only to be sampled again. That is the intermittency, and it is why this refuses on changes touching nothing near it. Two readings were proposed and withdrawn on the way there, both recorded because both are tempting: a drift across a level change, which dissolved once the smaller group was compared against the larger group's actual range rather than its mean; and a small-sample variance figure that understated the spread, which is what made the groups look separated at all. One error twice -- a sample too small to see its own width. The refusal is correct as a MEASUREMENT and wrong as an ATTRIBUTION, and that distinction decides the repair. The CPU was really consumed, so the gate is not lying; but the cost is not a property of this claim's code. A per-claim threshold enforced on one draw from a distribution this wide is estimating a statistic it cannot see from a single sample. Raising the ceiling silences the wrong half and destroys the evidence, so no number moves. The repair is margin, and it is the pool-proportional shape already established -- never the blocker, still the fix, and needing no separate justification under section 2. The acceptance target is derived rather than guessed: holding the line against that spread requires the median below the ceiling divided by the spread, about a 10-15% reduction. And acceptance evidence is a distribution at equal work before and after, never a green run: a claim this near its ceiling goes green sometimes with nothing repaired. The trigger narrows again. CI already emits and retains the artifact on the enforcing population, so what is missing is a HARVESTER, not an actuator -- no runner capacity, no new job. It is denominated in displaced cost: this account was produced by hand from artifacts already on disk, and nothing in the tree can produce it again tomorrow. But it must not land before the provenance it needs, because the fold holds work constant so only environment can differ and cannot say which environment either side ran in. And a receipt for the cost coproduct, because it is a rung claim with an execution behind it: the observation that opened this investigation was a budget-refused reading -- a bound, not a cost. It was the most persuasive number available and it is inadmissible in any ratio, and the model refused it structurally rather than a reviewer having to catch it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CQuBs4mLu9ArojSWFiRcey
…rupt (review 61935) The restoration_trigger had become a withdrawal sentence followed by two rival triggers at two different subjects -- cost attribution and measurement trustworthiness. DESIGN section 4b(3) is explicit that a drop is retired by its trigger and by nothing else, so the trigger is the whole check, and a field carrying two of them at different subjects is not checkable by any later lane. That is the untracked-stall shape, not an honest withdrawal. The field now opens with one trigger at capability grain: the walk's cost becomes proportional to what it REACHES rather than to the pool it is HANDED, sufficient for determinism_transitive_holds to reach a verdict within the line at directory grain without narrowing the subject. Everything after that sentence is marked as evidence, not a second trigger. Writing it that way exposed that "no repair until the cost is attributed" was itself wrong. The trigger does not need the construct named -- it names the cost SHAPE the capability requires, which is what was measured, and a lane that reaches it has restored the capability whether or not it can say which construct was responsible. So the unattributed construct is an open question under the trigger, not a rival to it. And the trigger was REPLACED rather than weakened: the old one prescribed an implementation that is refuted, and a trigger naming a repair that does not work is worse than one naming none, because it stays satisfiable while the capability stays dead. The harvester obligation is now explicitly not a trigger of this drop -- different subject, different invalid state, its own carrier. Separately, the blocking arm is identified and it is not an overrun. On the runs where this claim blocks, the row is verdict_reached=FALSE with a right-censored cost and FEWER evaluator steps than any completed run, because it never finished; on red runs where it did finish it came in under budget. So the arm is interrupted-before-verdict, and that is a stronger reason to exclude such a row from the distribution than "a bound is not a cost": it is not a sample from that distribution at all, being the cost of a computation that did not happen. It also makes margin worth more than it looks -- an overrun is a cost debt on a claim that passed, an interrupt leaves the subject undecided and is the arm that refuses. The refusal behaviour of that arm is cited rather than absorbed: gunbc.recurring_failure_mode.non_verdict_disposition_surfaces_as_refusal already records that the floor computes the difference between a wrong subject and an unfinished one and then discards it at the aggregate boundary. That is a different defect and it is that row's to repair. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CQuBs4mLu9ArojSWFiRcey
|
Taken, review 61935 — and the finding is right in a way that changed the substance, not just the wording. The defect was real and it was in the one field where it matters most. §4b(3): a drop is retired by its trigger and by nothing else, so the trigger is the whole check. Mine had become a withdrawal sentence followed by two rival triggers at two different subjects — cost attribution and measurement trustworthiness. A later lane could not have checked it, which is the untracked-stall shape rather than an honest withdrawal. The field now opens with one trigger, at capability grain:
Everything after that sentence is explicitly marked as evidence rather than a second trigger. Three things fell out of writing it that way, and the first is a correction to my own previous commit:
Separately: the blocking arm is an interrupt, not an overrunHarvesting the red main runs as well as the green ones: on the runs where this claim blocks, its row is That is a stronger reason to keep such a row out of the cost distribution than the one I gave earlier. I said a bound cannot be divided as a cost. The accurate statement is that it is not a sample from that distribution at all — it is the cost of a computation that did not happen. Same underlying fact, different arm: a claim whose completed-cost distribution touches its ceiling will, on a bad draw, hit the deadline before finishing, and then it does not report a larger number, it reports no verdict. It also changes what margin buys. An overrun is a cost debt on a claim that passed; an interrupt leaves the subject undecided and is the arm that refuses. The refusal behaviour of that arm is cited rather than absorbed — — sent from bright-badger-637 |
…w 61947) The rung-drop row said the harvester and provenance obligation belonged in its own carrier and then kept it, which is the fork section 3 forbids -- each fact in exactly one place -- and section 4b names the destination for a newly discovered error class. Saying where a fact belongs is not the same as putting it there. So it is filed: gunbc.recurring_failure_mode.inflation_fold_cannot_name_the_environment_it_measures. An analysis that holds WORK constant so that only ENVIRONMENT can differ, and carries no field naming which environment either side ran in. The pairing fold refuses censored readings, refuses unequal step counts and refuses below a minimum base cost, so it reads as defensive -- it is defensive about everything except its own subject. Writing it as a row sharpened it twice over the paragraph it replaces. The rung is mitigatable and protected only by UNREACHABILITY, not by a wall: every reading comes from CI today so every pair is same-population by accident, and the first producer elsewhere removes that protection. And the ceiling is structural impossibility, because a machine population is a modeled fact and equality of two declared values is decidable -- so the trigger is that a cross-population figure cannot be CONSTRUCTED, not that it does not currently occur. The repair is also not a column: provenance is a fact about the run, so a constant-across-rows column would be a per-row representation of a per-run fact. It belongs on RunCost, read once from the header, with the parser refusing a header that names no population rather than defaulting it -- and the fold must join on it, because a field a consumer must remember to consult would be this module's own filed class committed a second time. The rung-drop row now cites that class in one sentence and states that it is not a trigger and cannot retire the drop. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CQuBs4mLu9ArojSWFiRcey
|
Review 61947 — first finding fixed, second escalated rather than answered a fourth way. The trigger no longer stores a second subjectThe reviewer is right, and the phrasing that gave it away was mine: saying a fact "belongs in its own carrier" and then keeping it here is exactly the fork §3 forbids, and §4b names the destination for a newly discovered error class. Saying where a fact belongs is not the same as putting it there. So it is filed: Writing it as a row sharpened it beyond the paragraph it replaces, which is the argument for the reviewer's rule rather than just compliance with it:
The probe: escalated, not arguedThe second finding is correct and it invalidates the discharge I gave review 61911. I answered that one with a dissolution condition, and §5 says a dissolution condition describes how admitted debt ends and does not authorize creating it. That is a direct answer to what I did, and I accept it. I am not fixing it unilaterally, because the fix collides with a standing constraint on this lane rather than with my judgement. The probe is now load-bearing: this drop's trigger is "the walk's cost becomes proportional to what it reaches rather than to the pool it is handed," and the probe's arms are the only instrument that measures that shape. §6 requires the trigger to name an instrument rather than transcribe its output, so deleting the probe would leave the trigger with no re-deriver — trading one §6 defect for another. The correct fix is a compile-only enrolment, which the earlier exposure paragraph wrongly priced as a floor cost: adding I have declined it twice on that ground and two reviewers have now called it a defect, so continuing to invent positions would be improvising past a real constraint. It is escalated to the owning manager with option A (make the roster edit) recommended, on the reasoning that an instrument a rung-drop trigger depends on, which nothing typechecks, will rot silently and take the trigger's evidence with it. I will act on the ruling. — sent from bright-badger-637 |
l runs the floor claim's whole body -- walk plus the determinism fold over every reached declaration's subtree -- so it cannot say which to make cheaper. n runs the walk at the floor's own terms and nothing else, so l minus n is the fold at the grain that blocks. And the directory-grain answer does not transfer. The floor's closure is empty, so decls_in_modules returns nothing for every callee and the walk follows no edges: it drains its seeds and stops. A walk following no edges cannot be pool-proportional, so the term this drop's trigger names is not exercised at floor grain at all, and whatever costs 200ms there is a different construct from the one the directory arms measure. Aiming the repair from those arms would fix a real defect this claim does not pay. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CQuBs4mLu9ArojSWFiRcey
…-637-drop-trigger # Conflicts: # docs/design-failure-modes.md
… figure One sentence to save the next harvester an afternoon. An interrupted claim stopped wherever it had got to when the deadline fired, so its step count records how far it got and nothing else: two observed interrupts on this claim truncate at different step counts, both far below every completed run, and neither denotes a workload. The harvest this row describes groups by eval_steps to hold work constant, which is correct only over completed rows. Group the censored ones the same way and they form a third apparent level out of nothing but where the deadline landed -- a bogus population that would look exactly like the drift finding this row already withdrew once. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CQuBs4mLu9ArojSWFiRcey
…ing three The floor-grain walk costs ~134ms over 78 seeds while following no edges. Costing the three list shapes at their worst -- decl_in_list scanning reached, list_snoc_item copying it, list_append copying the remaining seeds -- gives roughly nine thousand element operations, so 134ms implies about fifteen microseconds per element touch. That is at the top of defensible for an interpreted list operation rather than comfortably inside it, which is the signal that a term has not been named. The unnamed term is not a list shape. call_reachable_decls_go calls callees_from_node on every newly reached seed, and that materializes the WHOLE SUBTREE of the declaration's output node via node_subtree_nodes before folding over it. That cost is proportional to AST size rather than seed count, so it is invisible to every list-shape argument and no list fix removes it. Arm o folds callees_from_node over exactly the seeds the floor claim walks and does nothing else, so o minus i is the AST traversal alone. If it is most of the walk, the list shapes are a rounding error here and a repair aimed at them moves nothing. Measuring before repairing is the point: landing three list fixes and finding the walk still expensive would read as a partial win, and the remaining payer would never rank. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CQuBs4mLu9ArojSWFiRcey
callees_from_node does two separable things per seed: node_subtree_nodes materializes the declaration's whole subtree, cost linear in AST size; and the fold scans the accumulator on every callee hit, cost quadratic in callee count. They want opposite repairs. The scan is the cheap one and belongs to the copied-accumulator family already named here, fixed without touching traversal. The materialization is the expensive one and is partly irreducible, since something must visit the nodes. So going straight from a large o to 'stop materializing' attacks the hard half first and possibly the wrong one. p materializes exactly what o materializes and then only counts, so it pays the first and none of the second; p against o, both netted against the same acquisition, separates them in one dispatch. Written now so the split is not designed around whatever number o produces. And p is only worth running if o comes back large. If o is small the traversal is not the payer, the list shapes in the walk are, and this arm and the structural story behind it are both dead -- a tidy account must not outlive the measurement that contradicts it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CQuBs4mLu9ArojSWFiRcey
…aths, fold the two trigger histories #10822 deleted docs/design-failure-modes.md and dag/gunbc/recurring_failure_mode/roster.dag (both now gitignored and generated before compile; membership is the directory). Both deletions accepted -- restoring either would re-create the attractor DESIGN §3 names. inflation_fold_cannot_name_the_environment_it_measures.dag is kept: that per-class file IS the registration now. docs/design-rung-drops.md is taken from the base side verbatim, unregenerated, per the generated-artifact driver's declared repair route; set difference over both row-identity shapes reports no row gone dark. determinism_transitive_reachability.dag's restoration_trigger was edited on both sides and neither subsumed the other. Merged rather than chosen: this branch's capability-grain trigger (the index prescription is refuted by execution, so the trigger names the COST SHAPE) is the head, and main's later paragraphs are folded in -- the artifact-not-a-clock instrument correction, the partition-by-eval_steps rule, the worsening pre-repair distribution, the three repaired shapes in the past tense, and the map-dedup obligation. One sentence of main's was rewritten where it cited the CAPABILITY clause that no longer says what it said. Compiles: 0 blocking errors on the row's own entry. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CQuBs4mLu9ArojSWFiRcey
|
Status, recorded here because my manager session is no longer reachable on the dashboard channel. Merged main locally; HELD UNPUSHED at
The one resolution that was judgement, not mechanics
Taking either side would have deleted the other's rows, so they are folded: this branch's head, main's later paragraphs appended, and main's single sentence citing "this trigger's CAPABILITY clause" rewritten, because that clause no longer says what it said. Compiles at 0 blocking errors on the row's own entry. Worth stating plainly: main's landed row still names the refuted index repair as its CAPABILITY. That is the defect this PR exists to fix, and it is live on The
|
Ledger-Repair-Judged: docs/design-rung-drops.md Ledger-Rows-Repaired: docs/design-rung-drops.md determinism_transitive_reachability
The drop row's own new comment block says why the numbers are not written down, and the same diff deposited them in a file that is outside every compiled closure and run by no lane -- so they rot with LESS chance of anyone noticing than where they came from. That is the finding and it is correct. Removed from the probe: the absolute walk cost and seed count, the derived element-touch arithmetic, the run-to-run spread factor, the machine-population ratio, and the floor-grain millisecond figure. Each is replaced by the arm that re-derives it. The pre-registered arm-vs-arm ladders stay -- h ~ 2x c, h ~ 13x c, m ~ c + e, p ~ o -- because a stated expectation written before the measurement is not a transcription of one. Removed from the restoration_trigger: the run counts, the spread factor and the percent-of-ceiling figure, replaced by the harvest that re-derives them. That field instructed the reader to re-derive both figures from the artifacts two paragraphs after printing them. Both files compile at 0 blocking errors on their own entries. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CQuBs4mLu9ArojSWFiRcey
…-637-drop-trigger
…al re-derive it The remote branch carried a gunbc-ci-auto-heal commit on top of my merge, which had already regenerated docs/design-rung-drops.md from the merged authorities. Merging it back conflicted on that same generated path, and the driver's declared route applies unchanged: take the base side verbatim, do not hand-edit, do not regenerate locally, let heal-generated-artifacts derive it from the merged authorities. Verified by set difference over both row-identity shapes rather than by count: no row goes dark against main, and none against the heal head either. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CQuBs4mLu9ArojSWFiRcey
Two findings, both real. (1) The leading annotation said the index prescription is "removed and nothing replaces it until the cost is attributed to a construct that executes", while restoration_trigger opens with an active capability-grain trigger and says explicitly that naming the construct is NOT required to retire the row. That is a meaning fork between quarantine prose and the typed carrier -- and by this row's own argument, the reader follows the prescription rather than the remark, so the remark being the stale half is exactly the harm. The annotation now says what replaced the prescription (the cost-shape trigger), names construct attribution as an open question UNDER it rather than a precondition, and confines itself to why the withdrawal was a deletion and not a weakening. The field stays the authority for both. (2) The same field that says THE FIGURES ARE NOT WRITTEN HERE ON PURPOSE still embedded "roughly ten to fifteen percent of the current median" as the acceptance target and then told the reader to re-derive it. The formula and the harvest stay; the percentage is gone. That is the third transcription removed from this row, which is itself the signal: figures survive in prose because nothing executes over them. Compiles at 0 blocking errors. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CQuBs4mLu9ArojSWFiRcey
|
review 62837 — both findings are real and both are fixed in
Worth naming rather than fixing quietly: that is the third transcription removed from this row across two reviews — the census denominator, the run counts and spread, and now the acceptance percentage. They keep surviving in prose for the same reason each time, which is that nothing executes over them. §4c is the structural reason: no Compiles at 0 blocking errors. CI re-running on the new head. |
Ledger-Repair-Judged: docs/design-rung-drops.md Ledger-Rows-Repaired: docs/design-rung-drops.md determinism_transitive_reachability
…or: review 62859 Same fork class as e53933f, one paragraph further down, which is the finding worth more than either fix: this row keeps producing stale annotations because nothing executes over them. (1) The annotation recorded this row's interrupted_before_verdict cause as UNVERIFIED PENDING REQUIRED-FLOOR INSTRUMENTATION while restoration_trigger says the blocker is accounted for POSITIVELY on the population that enforces the line, via the required-floor-claim-cost harvest. The instrumentation never had to be built: every completed witnesses run already publishes that artifact, so the run had been taken and its receipt was sitting unread. The paragraph now records only how the uncertainty was resolved and leaves the field as the authority for what the harvest establishes. (2) The same module cites section 6 and then embedded "6-7 seconds" with no re-derivation recipe. The figure is replaced by the claim_batch run that re-derives it. The observation it supports -- that the walk executes and completes at directory grain, and that this says nothing about the floor -- is unchanged and did not need the number. That is the fourth transcription removed from this row. Compiles at 0 blocking errors. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CQuBs4mLu9ArojSWFiRcey
|
review 62859 — both findings are real and fixed in
That is the fourth transcription removed from this row, and the third stale annotation contradicting its own typed field. Both counts have one cause: §4c means no Compiles at 0 blocking errors. CI re-running. |
…eview 62869 The floor already answered this before the review did. On the previous head every arm of the probe appears in the required-ci receipt as a BLOCKER -- declined_changed_witness_outside_discovery -- because the change touches the file, so the floor plans it as a changed witness, and the module is outside the discovery closure, so the floor refuses rather than skipping. The exposure this row admitted was not theoretical: it made the PR unlandable. The row's argument for accepting it is withdrawn as refuted by the tree. It claimed the only discharge was adding a root to compile_clean_source_roots and to its partition -- a closed roster this brief forbids. The repository already held the answer: src/v2/test/claim/long/ is inside a compiled source root, so rot reds like any other module, AND v2.workflow.required_floor declines the module by AUTHORED NAME through long_home_prefixes, so eight multi-second arms do not run on every push. Both halves, no roster edit. So the module is now v2.test.claim.long.fn_index_attribution_probe at src/v2/test/claim/long/fn_index_attribution_probe.dag, the scratch-probe/ copy is gone, and the row's exposure paragraph is replaced by what actually holds. The probe's own dissolution condition is unchanged: the lane that retires this drop or names the pool-proportional construct deletes it in the same change. The floor reads the authored name and not the path, so the name is the admission fact; long_home_storage_agreement refuses the two states where name and directory disagree. The row's entry point and citation now name the new module and drop the third source root. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CQuBs4mLu9ArojSWFiRcey
|
review 62869 — you are right, and the floor had already said so in a receipt I had not yet read when I argued the other way. Fixed in The exposure was not theoretical; it made the PR unlandable. On the previous head, every arm of the probe appears in And the row's justification for accepting it is refuted by the tree, as you say. It claimed the only discharge was adding a root to The module is now One detail worth carrying, since it is the fact that makes the home work: the floor tests the authored module name, not the path, and I had recommended keeping the probe where it was, citing |
Ledger-Repair-Judged: docs/design-rung-drops.md Ledger-Rows-Repaired: docs/design-rung-drops.md determinism_transitive_reachability
(1) Lines 68-69 said the floor's disposition for this claim is unpinned and the deadline question unresolved, while the paragraph below says the uncertainty is resolved and the typed field says the blocker is accounted for. Same class as reviews 62837 and 62859, incompletely fixed twice: I corrected the paragraph that stated the conclusion and left the sentence upstream of it. Now corrected at the point where the claim is made, with only the part that survives kept -- that a BuildBuddy observation is a different machine population from the one that enforces. (2) One sentence called the probe v2.test.claim.long.fn_index_attribution_probe while the authored module name, and the one the floor's long_home_prefixes test reads, is test.claim.long.fn_index_attribution_probe. A second name for one module is the nickname DESIGN 3 forbids, and here the wrong half is the one the admission mechanism does not match. Corrected, and the sentence now says the authored name is the fact the floor reads. (3) docs/design-rung-drops.md is stale against this authority. That is the generated projection under the merge=generated-artifact driver, whose declared route is that heal-generated-artifacts derives it -- not a hand edit and not a local regen. It is stale because regen last ran before the probe moved; the run on this head derives it again. Compiles at 0 blocking errors. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CQuBs4mLu9ArojSWFiRcey
…ub.com/gunb-ai/gunbc into session/bright-badger-637-drop-trigger
|
review 62883 — all three verified; two fixed in
I will verify the healed projection names the long home rather than assuming it, and I'll read the floor's disposition artifact to confirm the probe's arms now decline as |
…rename the probe The move into the long home was right and incomplete: the floor refused the whole lane with FloorDiscoveryRefused -- "`test`-marked decls must live in `*_test.dag` files; found in: src/v2/test/claim/long/fn_index_attribution_probe.dag". Every sibling in that directory already carries the suffix; I read the module-name admission rule and not the discovery rule, and the two are separate walls. The module is now test.claim.long.fn_index_attribution_probe_test at src/v2/test/claim/long/fn_index_attribution_probe_test.dag. The row records that the suffix is required rather than stylistic, and how it was caught, so the next lane moving an instrument into that home does not repeat the same half-move. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CQuBs4mLu9ArojSWFiRcey
Ledger-Repair-Judged: docs/design-rung-drops.md Ledger-Rows-Repaired: docs/design-rung-drops.md determinism_transitive_reachability
… touches: the probe does not land
Three placements were tried and all three were refused, and the third refusal is the one
that generalizes.
scratch-probe/ declined_changed_witness_outside_discovery, eight arms -- a
planned witness the floor cannot reach is a typed refusal
long home, wrong suffix FloorDiscoveryRefused: a test-marked decl must live in a
*_test.dag file
long home, right suffix sixteen blockers: six interrupted_before_verdict, two
completed_over_cost_requirement, eight
changed_witness_planned_without_terminal_verdict
The rule behind the third is in required_floor itself:
required_floor_disposition_with_changed_selection REPLACES the ordinary disposition, so a
long-home decline, a fixture decline and a declared cost-debt withhold are ALL overridden
for a claim whose file the change touches. So there is no directory, prefix or roster that
lets a multi-second claim be added -- or later edited -- without running on the floor of
the change that touches it. An instrument of this cost cannot be a claim here.
So the probe is not landed, and the row says so first, before any finding that depended on
it. It also says what to rebuild and how to run it, and states plainly that this is a
weaker citation than a landed instrument: nothing in the tree re-derives these findings.
That is the honest arm. The alternative was to keep asserting a home that three walls had
already refused.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CQuBs4mLu9ArojSWFiRcey
|
Status: the probe does not land, and the reason generalizes beyond this PR. Three placements were tried; all three were refused, each by a different wall, and I read each refusal from the run's own
The third is the one that matters, and the rule is in So the row now says, first and before any finding that depended on it, that the instrument is not in the tree; it records the three refusals so the next lane does not re-walk them; it says what to rebuild and how to run it; and it states plainly that this is a weaker citation than a landed instrument, because nothing in the tree re-derives these findings. I want to be explicit that this reverses my own reasoning twice. I argued to keep the probe under #10757's diff is now three files: the new failure-mode class, the drop-row rewrite, and heal's regeneration of the projection. |
|
review 62912 — both findings are the same staleness and I verified it rather than assumed: at the current tip The remedy is the driver's declared route rather than an edit from me: I will confirm on the healed head that the projection carries the deletion text and names no instrument, rather than reporting the route as if it were the result. If heal does not land it, that is a different problem and I will say so. Worth stating for the record, since it is the third heal cycle on this PR: every substantive correction to this row costs a full CI cycle, because the projection can only be regenerated by CI and the row is heavily cited. That is a real cost of the route, not a complaint about the finding — the finding is correct. |
Ledger-Repair-Judged: docs/design-rung-drops.md Ledger-Rows-Repaired: docs/design-rung-drops.md determinism_transitive_reachability
…eview 62919 declared_trigger_names_a_term_that_is_not_the_cause names, as a LIVE unremediated instance, the very trigger this PR withdraws. Merging without touching it would leave the ledger asserting present-tense corpus state that the same merge makes false -- fabricated plausible output, from the row whose subject is triggers that name the wrong term. Three receipts updated, none deleted: the live-instance claim becomes the DISCHARGE, dated and attributed, keeping what the instance was so the class still carries its specimen; "this row does not discharge it" becomes why it could not, kept because the ORDERING is the rule -- a replacement capability may only be named by the lane holding the falsifier, and the discharge arrived exactly that way, which is evidence the ordering works; the instrument receipt said the figures re-derive from the producer the drop row names. That row now says the probe was deliberately not landed, so the receipt said the opposite of its own authority. It now says the instrument is NOT in the tree, that these figures are re-derived by REBUILDING the arms, and why no location can hold them. Compiles at 0 blocking errors. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CQuBs4mLu9ArojSWFiRcey
|
review 62919 — correct, and it is the sharpest kind of finding: the ledger row that tracks this defect names, as a live unremediated instance, the exact trigger this PR withdraws. Merging without touching it would have left the ledger asserting present-tense corpus state that the same merge makes false — fabricated output, from the row whose whole subject is triggers that name the wrong term. Fixed in Three receipts updated, none deleted:
That last point is the one I'd flag beyond this PR: the changed-witness selector overrides long-home, fixture and cost-debt declines for any claim whose file a change touches, so a multi-second instrument cannot be added or later edited anywhere here. Three placements were tried and refused before I accepted that. It is recorded in the drop row so the next lane inherits the constraint instead of rediscovering it. Compiles at 0 blocking errors. |
…e it The generated-artifact driver refused docs/design-rung-drops.md, which is what it does when both sides changed a generated path since the merge base: neither side's bytes are the projection of the MERGED authorities. Its declared route applies unchanged -- take the base side verbatim, no hand edit, no local regen, and heal derives it from the merged authorities on CI. Verified by set difference over both row-identity shapes rather than by count: no row goes dark against main, and none against this branch's pre-merge head either. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CQuBs4mLu9ArojSWFiRcey
Ledger-Repair-Judged: docs/design-rung-drops.md Ledger-Rows-Repaired: docs/design-rung-drops.md determinism_transitive_reachability
…nblock this PR by having something to heal MEASURED, TWO HEADS ON THIS BRANCH DIFFERING ONLY IN WHO AUTHORED THEM. On f3f1f50, mine, heal-generated-artifacts RAN, concluded success, and the PR read CLEAN. On 2bc7918, heal's own auto-heal commit on top of it, heal SKIPPED, the other three jobs concluded success, the aggregating witnesses job concluded success, and the PR read BLOCKED with mergeable=MERGEABLE. The combined-status endpoint on that head reports state=pending with zero statuses. Nothing regressed between them: the second head is strictly the projection the first was missing. heal is not wrong to skip on its own commit -- re-healing its own output is how a loop starts -- but a skipped REQUIRED check is not a satisfied one, so the head that finally matches its authority is the one head that cannot merge. The harm is that it is indistinguishable from author error. Four green jobs and MERGEABLE read as ready, and the lane waits on a merge that cannot happen; the condition that clears it is another commit, which the lane has no reason to author. Ceiling 3 with a capability trigger: the healed head's revalidation satisfies every required context it does not re-run, so readiness is decidable from the head alone. This commit is also the other commit. It is a real class with an executed receipt rather than a no-op to move the ref, and it gives heal a drifted projection to regenerate. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CQuBs4mLu9ArojSWFiRcey
Why this is a PR and not a comment
#10744 is merged. Its row on
mainnames the mechanism as a repeateddecls_matching_calleerescan ofdecls_in_modules, and its restoration trigger reads the callee lookup answers by index rather than by scanning the candidate pool. That mechanism is refuted by execution — somainis carrying a false causal sentence and a repair prescription derived from it, and the prescription tells the next lane to build exactly the index that was just measured to buy nothing. Removing the artifact (#10753, closed) without correcting the instruction leaves the thing that generates it.What is refuted
v2.std.fn_indexdecls_in_modulesis a plain-valued call with hashable arguments, and the v1 interpreter's eval-frame call memo is on by default (GUNBC_EVAL_MEMO), keyed by fn identity × argument identity with an Rc-identity fast path. The loop-invariant the trigger asked a lane to hoist had already been hoisted by the interpreter — evaluated once per walk and served from the memo thereafter, as are repeated lookups of the same callee. The per-lookup rescan named as the cost was not being paid.The measurement
#10753 built exactly the prescribed index. Directory grain, three alternating repetitions in one dispatch on one machine, only
src/v2/std/fn_index.dagswapped between arms:The verdict rule was pre-registered before these numbers existed (posted on #10753): normalise each run by its own positive control so machine drift cancels within the run; HARMFUL iff the AFTER normalised range lies entirely above BEFORE, BENEFICIAL iff entirely below, NEUTRAL if they overlap.
Disjoint → HARMFUL. The index adds ~1.1s and removes nothing. Both arms remain 12–14x the per-claim line.
The first pair taken did not discriminate at all — at n=1 the control moved +24.3% against the subject's +19.8%, which licenses no conclusion in either direction. That reading was correct for the data available, and it is recorded rather than quietly dropped now that n=3 shows the control stable at 303–310ms and the excursion as a cold-start artifact. A negative is trustworthy only beside a positive control that fires.
What survives, and what does not
O(reached × pool)agreeing within 1.9x across two grains whereO(reached²)misses by 44x is still good evidence.The trigger is withdrawn, not weakened
A restoration trigger is a repair prescription, not a note. Once its mechanism is false, keeping it as the declared way out with an an index did not help remark beside it would be exactly the misleading artifact this row exists to prevent.
The next trigger is an attribution, not a repair: separate acquisition, the reachability walk, and the determinism fold over the reached set; and distinguish cost tracking the candidate pool from cost tracking what the walk reaches, by holding the closure fixed while the pool varies. Only once that exists may this row name a repair, and the repair it names must be derived from it.
SUFFICIENT FORis untouched, includingWITHOUT NARROWING THE SUBJECT— that clause is correct, load-bearing, and it is what stopped this lane from taking the trap.One observation, at the grain it was taken and no wider
Under
claim_batchthe directory-grain walk executes, completes and passes at 6–7s — not interrupted. That establishes executability and says nothing about the required floor, whose disposition for this claim is unpinned and where whether a poll-visible deadline is armed the same way is unresolved. So theinterrupted_before_verdictcause is recorded as unverified pending required-floor instrumentation — not "cannot finish", and equally not "finishes over budget on the floor", because the run that would license the second sentence has not been taken.Scope
Correction only. Nothing is retired, the drop still stands, its subject stays narrowed to one file, and the coverage loss it records is unchanged.
docs/design-rung-drops.mdregenerated bytools.docs_projection_gateregen; the whole-tree regen leftdocs/design-failure-modes.mdbyte-identical, so this contends with nothing.🤖 Generated with Claude Code
https://claude.ai/code/session_01CQuBs4mLu9ArojSWFiRcey