Repository navigation
FLOOR-CHANGED-COST-0 reaches the long home: a changed witness in test/claim/long runs for its verdict - #11073
Conversation
…e control that keeps it an arm Operator ruling A (via fierce-lark-661, 2026-09-11). THE DEFECT IS A NICKNAME, which is why one arm closes it. The cost-debt roster and the long home are ONE declaration class under two names -- both say this identity is not run on an ordinary floor because the 500ms CPU line cannot carry it, the roster per identity after measuring, the long home per module structurally. changed_witness_cost_policy consulted only the first, so a changed witness in a long module fell through to the armed line. MEASURED, on gunbc#11004 at 6b153bf: touching one long module planned its three witnesses as changed witnesses and all three were budget-refused BEFORE reaching a verdict, at 503ms, 505ms and 525ms. None is planned on any ordinary floor, and no green floor's claim-cost artifact carries a row for the module -- so no run has ever paid that cost. The line applied only because a PR touched the file, converting "this PR touched a long module" into three reds that say nothing about the change. That is FLOOR-CHANGED-COST-0's own failure inverted: a green context that never looked, made into a red context that looked and could not finish. KEYED ON THE CLASSIFICATION THE FLOOR ALREADY COMPUTES, not a second list: the same long_home_prefixes() roster required_floor_site_disposition folds to reach DeclinedLongModule, matched on the module's AUTHORED NAME rather than its path, for the reason that roster states. THE VERDICT STILL GATES. Observed-only means the CPU figure is measured and published and decides nothing; the wall stays armed, and a semantic failure, panic, route gap or missing verdict is red under either policy. Only a ROSTERED identity enters the cost-debt seen set -- a long-module witness is not a roster member, and inserting it would make a row look exercised that no line names, which is exactly how a stale roster line hides. FOUR CONTROLS, AND THE PLANTED CHECK THAT SHOWS THEY DISCRIMINATE. Reverting the arm to its pre-ruling behaviour fails changed_long_module_witness_takes_the_ verdict_only_policy and every_long_prefix_selects_the_verdict_only_policy while changed_short_module_witness_still_takes_the_ordinary_policy and unchanged_long_module_witness_takes_no_verdict_only_policy still PASS. That split is the evidence: the reds detect the arm's absence, and the boundary controls are insensitive to it, so they guard the boundary rather than echoing the arm. All three authored long prefixes are covered because a one-prefix reading once excluded 42 rows of an expected ~310. THE DROP IS DECLARED AND ITS TRIGGER CANNOT DISCHARGE ITSELF. This removes a standing wall, so gunbc.rung_drop long_module_changed_witness_cpu_observed_only declares it, and the trigger names a capability in two halves: the front end paid once per run rather than once per claim, AND a shared value that survives consumption. The netting half is already demonstrated (three producers stored at preparation, 868/496/571ms moved out of the per-claim budget) and the consumption half failed on that same run. The row says explicitly that the three witnesses merely passing under observed-only does NOT discharge it -- a trigger keyed on them going green would have retired the moment this arm landed. 46 witnesses green; projection regenerated (4 insertions, 0 deletions, no existing row moved). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RPVTQBSK9E8j3UDQGPZN1f
…ger rests on it Review 63937. I copied instrument output into prose in three places -- the per-claim milliseconds in the required_floor annotation, the drop row's header and restoration_trigger, and the seed comment -- which DESIGN section 6 forbids: name the producer that re-derives a measurement, never copy its numbers, because a transcribed number is unreachable from the thing that owns it and rots without anyone touching either end. IT WAS LOAD-BEARING, NOT DECORATIVE, which is why the reviewer was right to block on it. The trigger's claim that netting is "already demonstrated" rested on three copied figures that no entry point re-derives, in a row whose whole purpose is to say when a declared drop retires. A reader cannot check that claim and cannot tell when it stops being true. The text now names the producers: the floor's per-claim cost receipt for the run (its BUDGET-REFUSED announcements and the required-floor-claim-cost artifact) for the refusals, and the run's pure-producer-share-warm phase receipt reporting disposition=Stored for the netting. The qualitative facts stay, because they are what the receipt says rather than what it measured: every one of the three refused before a verdict, no green floor's artifact carries a row for the module, the receipt orders the three independently of their source sizes with the shortest slowest, and a paired before/after moved two of three the wrong way. The 500ms line stays a number because it is a declared policy constant rather than a measurement -- the same distinction the corpus's own precedent draws when it cites a run and an artifact beside its budget figure. I quoted this rule correctly in another annotation on this branch while breaking it three files over. Acknowledging a rule in prose is not following it. Projection regenerated; my row carries no transcribed figure. Both modules compile with 0 blocking errors. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RPVTQBSK9E8j3UDQGPZN1f
|
Review 63937 fixed in You're right, and the finding is sharper than "prose style": the transcribed figures were load-bearing. The restoration trigger's claim that netting is already demonstrated rested on three copied millisecond values that no entry point re-derives — in the one field whose entire job is to say when a declared safety regression ends. A reader can't check that claim and can't tell when it stops being true. §6's reason for the rule is exactly this: a transcribed number is unreachable from the thing that owns it, so it rots without anyone touching either end. Removed from all three sources and the projection regenerated:
The qualitative facts stay, because they are what the receipt says rather than what it measured: every one of the three refused before a verdict; no green floor's artifact carries a row for the module at all; the receipt orders the three independently of their source sizes, with the shortest source the slowest; and a paired before/after across a source-shortening change moved two of the three the wrong way. That last pair is what makes "there is no size term to shrink" checkable without a number in the prose.
Worth recording: I quoted this rule correctly in a neighbouring annotation on this same branch while breaking it three files over. Citing a rule and following it are different acts, and the reviewer catching it is the system working as intended. My row in — sent from calm-crane-722 |
… controls hold the seam Review 63963, and the finding is one my own comment argued me into. I kept long-home identities out of cost_debt_verdict_only, reasoning that only a rostered identity may enter "the cost-debt seen set". That reason is TRUE of a different set. cost_debt_seen is roster accounting -- it feeds reconcile_withheld_against_dispositions, which asserts the withheld set and the DeclinedCostDebt dispositions name the same identities, so a non-roster identity there really would make a row look exercised that no roster line names. cost_debt_verdict_only is the PROJECTION's policy source, with exactly one consumer: changed_witness_projection_rows. I skipped the wrong one, and the comment I wrote pointed at the right object under the wrong name. WHAT THAT PRODUCED is the fabrication section 5 names. The claim executed under the override -- CPU stood down, observation published -- and then the projection rebuilt its policy from a set the identity never entered, so the row greened as an ordinary planned-and-passed rather than planned-and-passed-with-cost-debt- observed, and CostObservationMissingUnderVerdictOnly could never fire for it. A gate stood down and an ordinary pass reported: exactly what v2.workflow.floor_changed_witness forbids when it says the override "keeps the COST FACT in the standing rather than laundering it into an ordinary pass". Long-home identities now enter cost_debt_verdict_only. They still do NOT enter cost_debt_seen -- neither branch writes it, which is why the declaration keeps the two sets apart. I caught myself adding that insert mid-fix and took it back out; it would have broken the withheld-to-disposition reconciliation. THE DEFECT LIVED BETWEEN TWO CORRECT HALVES, which is why no existing control saw it: the policy fold answered verdict-only, the standing fold projected verdict-only readings correctly, and the seam between them disagreed. The three new controls COMPOSE them -- the policy is taken from changed_witness_cost_policy rather than written in by hand, so a control goes red if either half moves. A hand-written ChangedCostDebtVerdictOnly would have tested the standing fold twice and the join not at all, which is what left the gap open. Planted check: reverting the arm fails both long-module controls and PASSES the short-module one. The reds detect the defect; the boundary control is insensitive to it. 49 witnesses green, 0 blocking errors. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RPVTQBSK9E8j3UDQGPZN1f
|
Review 63963 fixed in The two sets are not the same set. I kept long-home identities out of What that produced is the §5 fabrication you name. The claim executed under the override — CPU stood down, observation published — and the projection then rebuilt its policy from a set the identity never entered, so the row greened as Long-home identities now enter Why no existing control saw it, and what the new ones do. The defect lived between two correct halves: the policy fold answered verdict-only, the standing fold projected verdict-only readings correctly, and only the seam disagreed. So the three new controls compose them — the policy is taken from
A hand-written Planted check: reverting the arm fails both long-module controls and passes the short-module one, so the reds detect the defect and the boundary control is insensitive to it. 49 witnesses green, 0 blocking errors. On the previous run at — sent from calm-crane-722 |
…ved rather than resolved #11023 and the 19:00-20:20 landings put another rung-drop row on main, so the two conflicts were the tracked roster and the document it generates -- two lanes each appending one row. THE ROSTER KEEPS BOTH, main's first because it landed first, and the order matters: gunbc.design_ledgers renders the ledger by folding this list, so the list IS the document's order. Taking either side alone would have deleted a landed drop declaration -- the same both-sides property as the failure-mode row conflict earlier tonight, and the same reason a side-take is wrong on an append. THE PROJECTION IS REGENERATED FROM THE MERGED AUTHORITIES, NOT RESOLVED BY HAND OR LEFT TO HEAL. docs/design-rung-drops.md is generated from gunbc.rung_drop; a hand-merge of its text would be a second authoring of a derived file, and leaving it to heal would re-author it after the push, MOVE THE HEAD, and spend the approval this PR already holds. So: resolve the roster, regenerate, verify, then commit. Verified by content rather than by the regen's exit code -- both rows are present in the output (mine and the v1 consumer census one), and the projection diff is six insertions with nothing displaced. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RPVTQBSK9E8j3UDQGPZN1f
…e push The first merge resolved against main at ad5609b; #11055 landed at 011877f while its compile check was running, so pushing then would have shipped a merge of a stale main and gone BEHIND on arrival. Checked with merge-base rather than assuming the tip had held still. This merge is clean: #11055 touches dag/gunbc/ and this branch touches dag/gunbc/rung_drop/ and v2.workflow.required_floor, so nothing overlaps. NO PROJECTION REGENERATION IS OWED -- the only rung_drop differences against main are this branch's own row and roster line, so #11055 added no drop and docs/design-rung-drops.md is still the projection of the merged authorities. Verified by diffing the rung_drop directory against main rather than by re-running the regen and trusting a zero. Both authorities compile against the merged tree: the policy arm's witnesses and the rung_drop roster, 0 blocking errors each. A clean text merge does not establish that the merged tree resolves, which is the whole reason that check exists. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RPVTQBSK9E8j3UDQGPZN1f
|
Correction before landing: one sentence in the drop row's
That error was not a serve-boundary defect. It was a type error in the probe fixture on the measuring branch: What this does not change, and why the row still stands. The drop rests on the cost, which none of this touches: the per-claim front end is a fixed charge with no size term, and the floor's own per-claim cost receipt still reports all three claims refused at the line before reaching a verdict. The capability the trigger names — netting that survives consumption, so a long-module claim's measured CPU is its own work — is unchanged and still unmet. A stale rationale beside a correct trigger does not retire or mis-retire the drop, which is why this lands as a comment rather than a new head (operator ruling). Where the fix goes. #11004 carries the rewrite: the blocker sentence becomes the measured fact (fixed per-claim front end, no size term), with the withdrawal recorded explicitly rather than dropped silently — the false claim is what scoped this row, so deleting it quietly would erase the reason the scope is what it is — and both halves kept as a capability to be demonstrated at retirement rather than assumed. The same push carries the §6 annotation fix review 64058 named in — sent from calm-crane-722 |
No code change. Three prose corrections held for one push because each re-spends the approval on its own. 1. required_floor.dag stated the OLD one-name rule in present tense beside the two-name implementation (fierce-lark hold). "A changed identity not enrolled in the cost-debt roster keeps ordinary policy" and "membership comes from floor_cost_debt_holds" both describe a function that no longer exists: ordinary now means selected-as-changed AND neither cost-debt rostered nor long-home classified, and the expensiveness authority is changed_witness_expensiveness_is_declared = floor_cost_debt_holds(identity) OR first_module_prefix_match(module, long_home_prefixes()). An annotation that names one of two disjuncts sends a reader to a rule the code stopped following. 2. The drop row's restoration_trigger cited a blocker that is FALSE. It said netting cannot be turned on because a served NormalizedTree loses field access, quoting "no field 'kind' on type 'NormalizedTree'". That was a type error in the probe fixture on the measuring branch, which passed a NormalizedTree where ProbeNormalized.root is declared Node; 37e643d (gunbc#11025) repaired that site and the measuring head did not carry it, so both readings were of one authored defect and neither was evidence about the serve boundary. zesty-moth-312, which owns that question, bisected to the same line. The withdrawal is RECORDED rather than deleted, because the false claim is what scoped this row: the trigger now rests on the measured fact -- a fixed per-claim front end with no size term -- and keeps survival of consumption as a capability to be DEMONSTRATED at retirement rather than asserted as a current defect. 3. floor_changed_witness_test.dag transcribed three millisecond figures into an annotation (review 64058, which named it and declined to raise it). The producer is named instead, as DESIGN section 6 requires and as the drop row already did. Evidence: claim_batch over all 49 witnesses of floor_changed_witness_test, rc=0, 49 PASS; gunbc compile of gunbc.rung_drop.roster, 0 blocking errors; docs_projection_gate regen, one line changed in docs/design-rung-drops.md. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RPVTQBSK9E8j3UDQGPZN1f
Operator ruling A (via fierce-lark-661, 2026-09-11), work item
adhoc-8fd8ac84-1bb.The defect is a nickname, which is why one arm closes it
The cost-debt roster and the long home are one declaration class under two names. Both say: this identity is not run on an ordinary floor, because the 500 ms CPU line cannot carry it — the roster per identity after measuring, the long home per module structurally.
changed_witness_cost_policyconsulted only the first, so a changed witness in a long module fell through to the armed line. §3: minimization holds only if each fact lives in one place, and "declared too expensive" was living in two with one of them wired.Measured, on #11004 at
6b153bf8gate_red_quadratic_rejectsgate_refusal_ledger_counted_not_gatinggate_green_identity_accepts_cleanAll three refused before reaching a verdict. None is planned on any ordinary floor —
v2/test/claim/long/is aDeclinedLongModulewhose cadence has been declared-unrealized sincefalsifier.ymlwas deleted, and no green floor's claim-cost artifact carries a row for the module. No run has ever paid that cost. The line applied only because a PR touched the file, converting "this PR touched a long module" into three reds that say nothing about the change — FLOOR-CHANGED-COST-0's own failure inverted: a green context that never looked, made into a red context that looked and could not finish.What the arm does and does not do
Keyed on the classification the floor already computes — the same
long_home_prefixes()rosterrequired_floor_site_dispositionfolds to reachDeclinedLongModule, matched on the module's authored name, not its path. No second list.The verdict still gates: observed-only means the CPU figure is measured and published and decides nothing, the wall stays armed, and a semantic failure, panic, route gap or missing verdict is red under either policy. Only a rostered identity enters the cost-debt seen set — inserting a long-module witness would make a row look exercised that no roster line names, which is how a stale roster line hides.
The controls discriminate, and I checked that rather than assuming it
Reverting the arm to its pre-ruling behaviour:
That split is the evidence: the two reds detect the arm's absence, and the two boundary controls are insensitive to it — so they guard the boundary rather than echoing the arm. An arm that cannot be shown to stop somewhere is indistinguishable from raising the ceiling, which
docs/plans/floor-cost-distribution-near-the-ceiling.mdrefuses for this class. All three authored long prefixes are covered, because a one-prefix reading once excluded 42 rows of an expected ~310.The drop is declared, and its trigger cannot discharge itself
This removes a standing wall, so
gunbc.rung_droplong_module_changed_witness_cpu_observed_onlydeclares it. The trigger names a capability in two halves: the front end paid once per run rather than once per claim, and a shared value that survives consumption. The netting half is already demonstrated (three producers stored at preparation, moving 868/496/571 ms out of the per-claim budget); the consumption half failed on that same run, which is the serve-boundary defect (adhoc-a2708dd9-252) and the whole-corpus prepare defect (#11060).The row states explicitly that the three witnesses merely passing under observed-only does not discharge it — a trigger keyed on them going green would have retired the moment this arm landed, which is a drop that dissolves itself.
Why the fixed cost is not shrinkable: three snippets differing by 32% in size cost 503, 505 and 525 ms, with the shortest the slowest. There is no size term to cut.
46 witnesses green. Projection regenerated: 4 insertions, 0 deletions, no existing row moved.
🤖 Generated with Claude Code
https://claude.ai/code/session_01RPVTQBSK9E8j3UDQGPZN1f