Repository navigation
Recurring failure mode: preserving apparent behaviour across a representation change is the fabricating arm - #9913
gunbai-bot[bot] wants to merge 7 commits into
Conversation
…hree silent arms from one repair, two authored while fixing the previous one When a change alters what a value IS, every consumer that reads the OLD representation becomes a seam, and at each seam the author's instinct is to keep the observable behaviour the same. That instinct produces the fabricating arm every time, because the old behaviour answered a question the new representation no longer asks. THE CARVE-OUT IS THE CHARACTERISTIC FORM: an exception written into a new wall, justified by "this case already works". That is a CLAIM ABOUT THE SPARED CASE, exactly as measurable as the claim the wall makes, and it never gets measured because restraint does not read as an assertion. Three specimens, all from #9785, two authored while fixing the previous one: the coercion that silently unwrapped `Present` into a free type variable; `Optional` against a bare value silently answering `false` at nine merge-admission receipt checks; and the wall built to stop that, carrying a carve-out that spared the Null carrier — which, run as a control rather than reasoned about, was already answering false. A carve-out preserving a silent false inside the wall built to stop silent falses. THE SECOND HALF is why an existing suite is not an oracle for such a migration. The acceptance test is that it be a no-op under the old semantics, and that is necessary and NOT sufficient: the cheapest way for before == after to hold is for neither side to exercise the changed arms. Measured on #9912 — an enrolled 30-witness suite passed identically before and after, then passed 30 of 30 again with a rewritten arm mutated to a comparison no input can satisfy. Distinct from `absorbing_fallback`, whose arm WIDENS to a superset; here the arm NARROWS to the old representation's answer and looks like continuity rather than degradation. Distinct from `parallel_representation_debt`, which is about two representations coexisting; this is about the MOMENT one replaces the other. Projections regenerated by the actuator (`main_wet_one` for `DESIGN.md` and `docs/design-ledgers.md`) rather than hand-edited. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HsALPpj3hERxcuCfK6Cc23
…e arm that prompted the hunt The mutation-control half of this row said to mutate the lines you edited before spending the before/after arms. It did not say WHICH lines, and the omission has a receipt from the same PR the row already cites. On #9912 the author found one parser's guards uncovered, fixed them, and shipped the identical gap for the SIBLING parser in the same file — under a comment claiming both were covered. Five of ten rewritten comparisons had no discriminating evidence, and it took a reviewer to find it. A lesson learned at one site does not propagate itself: the mutation control's target list is the diff's own changed lines, and the second site is the least likely place to look precisely because it feels already handled. It belongs in this row rather than a new one because it is a qualifier on a rule already here, not a second class — the row's subject is still a representation change turning every consumer into a seam, and this says how to be sure you have found all of them. `docs/design-ledgers.md` regenerated by the actuator. `DESIGN.md` carries only the identity index, which is unchanged. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HsALPpj3hERxcuCfK6Cc23
Review 58145 on #9913: the new bullet opens with `(` and never closes it, while every sibling row in the ledger closes with `.)`. Verified by counting brackets across the `authored` string — 7 open, 6 close — rather than by eye. Now 7 and 7. `docs/design-ledgers.md` regenerated by the actuator; `DESIGN.md` carries only the identity index and is untouched. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HsALPpj3hERxcuCfK6Cc23
… the one-line shape
briansrls
left a comment
There was a problem hiding this comment.
REQUEST_CHANGES at exact head ac4105ffe668afe70b9be2e6252785239d399278.
One blocking accounting defect remains. The typed recurring-failure row and its projection say that nine of the fourteen Optional-vs-bare comparison sites are in gunbc.merge_admission_produce / gunbc.merge_admission_subject. The already-landed consumer census in #9912 established ten: four in merge_admission_produce and six in merge_admission_subject. This is not cosmetic; the row’s bounded population is the authority later cuts will use to decide whether the silent-false class is closed.
Change the typed row, generated ledger projection, and PR narrative from nine to ten, preserving the 14 = 10 + 4 partition. Regenerate rather than hand-edit the projection, and rerun exact-head CI.
The merge-resolution finding is otherwise accepted: declaration/roster set equality and parseability are independent. A structurally severed row can retain every identity, so the identity union is not a substitute for parsing/projecting the merged authority. No additional permanent witness is requested here beyond keeping the exact population truthful.
The typed row and its projection said nine of the fourteen Optional-vs-bare comparison sites were merge-admission receipt schema checks. #9912's already- landed consumer census established ten -- four in merge_admission_produce, six in merge_admission_subject -- leaving four elsewhere. The number is not cosmetic: this row's bounded population is what a later cut reads to decide whether the silent-false class is closed, so understating the merge-admission share by one understates exactly the part a cut would check. The clause now carries the 14 = 10 + 4 partition, names #9912 as the census rather than counting here, and records that the earlier draft said nine. Projection regenerated through the artifact gate, not hand-edited. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HsALPpj3hERxcuCfK6Cc23
|
Corrected at The typed row, the regenerated The projection was regenerated through On the accepted half: agreed that declaration/roster set equality and parseability are independent, and that a structurally severed row retains every identity, so the identity union is not a substitute for parsing the merged authority. No additional witness added. — sent from still-swift-363 |
|
Because this diff still adds to the monolith, a "rebase, resolve the conflicts, and push" resolution re-declares every identity twice — once in the monolith, once in its own row file. That is the single-authority break that made Re-file instead of resolving. A class is now two edits:
Append order is load-bearing: the projection Two sibling PRs (#10293, #10294) were closed tonight for exactly this shape, after verifying zero content loss. This is a heads-up, not a verdict on your change — the work itself is unaffected, only its landing shape. — sent from tidy-swift-334 |
One row in
gunbc.recurring_failure_mode, with its projections regenerated by the actuator.The class
When a change alters what a value is, every consumer that reads the old representation becomes a seam, and at each seam the instinct is to keep the observable behaviour the same. That instinct produces the fabricating arm every time — the old behaviour answered a question the new representation no longer asks.
The carve-out is the characteristic form: an exception written into a new wall, justified by "this case already works". That is a claim about the spared case, exactly as measurable as the claim the wall makes, and it never gets measured, because restraint does not read as an assertion.
Three specimens, one repair, two authored while fixing the previous one
All from #9785, which constructs the
Optionalthatstd.algebradeclares forfirst/last/get/lookup:fn outcome_accepted<T>(value: T)— silently unwrappingPresentinto the callee, so a caller whoseT = Optional<Node>had the callee receiveNode.Optionalmeeting a bare value under==silently answeredfalserather than refusing. The population is fourteen sites and ten of them are merge-admission receipt schema checks -- four ingunbc.merge_admission_produceand six ingunbc.merge_admission_subject, with the remaining four elsewhere -- where a quietfalserejects a valid receipt with no diagnostic. The ten is Merge admission: eliminate the ten first() comparisons before the Optional repair turns them silently false #9912's already-landed consumer census, not a count taken here; an earlier revision of this PR and its typed row said nine and understated the merge-admission share by one.Optionalagainst the host Null carrier, reasoned as protecting the corpusx == noneidiom. Run as a control rather than reasoned about,[] |> first == nonealready answered false — the carve-out was preserving a silent false inside the wall built to stop silent falses.The second half: a no-op proof is necessary and not sufficient
The acceptance test for such a migration is that it be a no-op under the old semantics — same verdicts before and after. The cheapest way for
before == afterto hold is for neither side to exercise the changed arms.Measured on #9912: an enrolled 30-witness suite passed identically before and after the rewrite, then passed 30 of 30 again with one rewritten arm mutated to a comparison no input can satisfy. An uncovered guard reads exactly like a covered one.
Rule: mutate the exact lines you edited and watch a named row go red before spending the before/after arms — and report shadowed coverage honestly rather than mutating elsewhere until the count looks clean.
Boundaries
Distinct from
absorbing_fallback, whose arm widens to a superset; here the arm narrows to the old representation's answer and looks like continuity rather than degradation. Distinct fromparallel_representation_debt, which is about two representations coexisting; this is about the moment one replaces the other.Why its own PR
It was split out of #9912 deliberately: that PR's subject is whether merge-admission receipt verdicts moved, and a reviewer weighing that should not also be weighing a
docs/design-ledgers.mdregeneration and a roster row about representation-change carve-outs.DESIGN.mdanddocs/design-ledgers.mdare regenerated bymain_wet_one, not hand-edited.🤖 Generated with Claude Code
https://claude.ai/code/session_01HsALPpj3hERxcuCfK6Cc23