Repository navigation
Stop two roadmap_page witnesses rendering an emit rejection as an empty string - #9040
Merged
Merged
Conversation
…ty string
Both rows flattened `EmitRejected { reason: _ } => ""` and then pattern-matched
the empty string, so "the page could not be emitted" and "the page rendered the
wrong thing" produced the same false with opposite repairs -- one sends you to
the emitter, the other to the presentation model. That is the
not-applicable-versus-malformed conflation, and here it discards a reason the
variant actually CARRIES.
THESE ROWS ARE WORSE THAN AN ORDINARY COLLAPSE, WHICH IS WHY THEY WENT FIRST.
Their NEGATIVE conjuncts are VACUOUSLY TRUE on the empty string:
!string_contains("", "finish-line-accepted") and the two
!string_contains("", "finish-line-...") in the daily row cannot fail. So on any
emit rejection those conjuncts were decoration -- permanently green, carrying no
information, and cited as coverage. A row that is partly incapable of failing is
worse than a row that is absent (DESIGN 4b).
The assertions now run inside the EmitOk arm, where html exists; EmitRejected
returns false on its own. The finish-line row nests two emits, so its second
match sits inside the first arm rather than being flattened beside it.
EVIDENCE, AND ITS LIMIT. Verified by remote claim_batch, both directions:
green PASS witness_finish_line_variants_render_from_fixture
PASS witness_daily_leads_operational_not_narrative
red one assertion mutated (program-progress -> program-progress-MUTANT):
FAIL witness_daily_leads_operational_not_narrative
PASS witness_finish_line_variants_render_from_fixture (positive control,
same run -- so the red is the assertion, not a broken harness)
THE LIMIT IS STRUCTURAL AND NOT MINE TO FIX: dag/test/claim/long/ is a DECLINED
HOME. The floor discovers these witnesses and folds NONE of them, so CI will
never execute either row, in either direction, however green this PR looks. The
remote run above is the only evidence that exists for this file. Do not read a
green check on this PR as coverage of it.
WHAT THIS DOES NOT REACH: the same file has ELEVEN EmitRejected => "" sites. The
other eight are in shared render helpers (authority_page_html, empty_doc_html,
depth_chain_html, bold_title_html, dispatch_doc_html_for,
dispatch_doc_html_for_with_merged, blocked_dispatch_workspace_html,
parity_row_html) which absorb the rejection before any witness sees it, so every
caller inherits the conflation. Those are the root and these two are leaves;
the helper repair needs the return type to change and lands separately.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014oG2tMMAxgZeAQxDjvNsFm
Contributor
Author
|
The
gunbc#9031 carries the seal fix; re-run after it lands rather than repairing anything here. Note the second-order point, which matters for how this PR is read: even once that seal break clears, — sent from bold-raven-901 |
briansrls
pushed a commit
that referenced
this pull request
Aug 24, 2026
briansrls
pushed a commit
that referenced
this pull request
Aug 24, 2026
… and delete the forked twin (#9043) * Stop two roadmap_page witnesses rendering an emit rejection as an empty string Both rows flattened `EmitRejected { reason: _ } => ""` and then pattern-matched the empty string, so "the page could not be emitted" and "the page rendered the wrong thing" produced the same false with opposite repairs -- one sends you to the emitter, the other to the presentation model. That is the not-applicable-versus-malformed conflation, and here it discards a reason the variant actually CARRIES. THESE ROWS ARE WORSE THAN AN ORDINARY COLLAPSE, WHICH IS WHY THEY WENT FIRST. Their NEGATIVE conjuncts are VACUOUSLY TRUE on the empty string: !string_contains("", "finish-line-accepted") and the two !string_contains("", "finish-line-...") in the daily row cannot fail. So on any emit rejection those conjuncts were decoration -- permanently green, carrying no information, and cited as coverage. A row that is partly incapable of failing is worse than a row that is absent (DESIGN 4b). The assertions now run inside the EmitOk arm, where html exists; EmitRejected returns false on its own. The finish-line row nests two emits, so its second match sits inside the first arm rather than being flattened beside it. EVIDENCE, AND ITS LIMIT. Verified by remote claim_batch, both directions: green PASS witness_finish_line_variants_render_from_fixture PASS witness_daily_leads_operational_not_narrative red one assertion mutated (program-progress -> program-progress-MUTANT): FAIL witness_daily_leads_operational_not_narrative PASS witness_finish_line_variants_render_from_fixture (positive control, same run -- so the red is the assertion, not a broken harness) THE LIMIT IS STRUCTURAL AND NOT MINE TO FIX: dag/test/claim/long/ is a DECLINED HOME. The floor discovers these witnesses and folds NONE of them, so CI will never execute either row, in either direction, however green this PR looks. The remote run above is the only evidence that exists for this file. Do not read a green check on this PR as coverage of it. WHAT THIS DOES NOT REACH: the same file has ELEVEN EmitRejected => "" sites. The other eight are in shared render helpers (authority_page_html, empty_doc_html, depth_chain_html, bold_title_html, dispatch_doc_html_for, dispatch_doc_html_for_with_merged, blocked_dispatch_workspace_html, parity_row_html) which absorb the rejection before any witness sees it, so every caller inherits the conflation. Those are the root and these two are leaves; the helper repair needs the return type to change and lands separately. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014oG2tMMAxgZeAQxDjvNsFm * Make the emit rejection unspellable in roadmap_page's render helpers, and delete the forked twin THE ROOT BEHIND THE TWO LEAF ROWS. Eight shared render helpers in long/roadmap_page_witness_test.dag flattened `EmitRejected { reason: _ } => ""` before any witness saw the result, so every caller inherited the conflation: "the page could not be emitted" and "the page rendered the wrong thing" arrived as one value, with the reason the variant carries thrown away. Fixing the two witness rows (#9040) repaired leaves while this root stood. All eight now return HtmlEmitResult and the 27 call sites match it. There is no fold-to-String left in the file, so within these helpers and their callers the flattening has no spelling. THE FORKED TWIN IS DELETED RATHER THAN CONVERTED. roadmap_row_witness_test.dag declared its OWN authority_page_html -- same name, same shape, same flatten, one caller, and no fixture work of its own: its only job WAS the flatten. Converting it would have left two same-named helpers with different return types, which is a sharper trap than the uniform copy, since the next reader greps the name and copies whichever definition they hit first. Its single caller now matches try_serialize_html_source directly. `authority_page_html` no longer exists anywhere outside roadmap_page. WHAT THIS IS NOT, STATED SO NOBODY READS IT AS MORE. It is one level short of the construction fix. HtmlEmitResult is `EmitOk { html: String }`, so "emitted nothing" and "emitted content" remain the same value INSIDE the success arm. Splitting that (an explicit empty variant) is the real wall and is deliberately not attempted here: EmitOk is referenced 78 times across 26 files including production modules, so it is a shared-authority change owned separately. And no algebraic rule makes deliberate erasure unspellable in general -- a caller can always write a total match returning "". Rung: mechanically preventable at this seam, not structurally impossible; next-rung trigger is constraining the eliminators so no caller can obtain artifact text from a refusal. NOT A SUBTRACTION IN LINES, AND THE MEASURED NUMBERS SAY SO: 9 flatten-matches deleted (8 helpers + the twin), ~28 caller matches added, net +19 matches. What is subtracted is a REPRESENTABLE STATE, not code. An earlier draft of this claimed the helpers existed mostly to perform the flatten and would mostly vanish; reading all eight refuted it -- every one constructs a fixture (an empty document, a parent/child/edge chain, a markdown title, a specimen Element), which is real work a witness helper should own and which survives unchanged. EVIDENCE, and its limit. Remote claim_batch over both files, every witness named from the source rather than a remembered list: roadmap_page 38 PASS / 1 FAIL / 39 roadmap_row 6 PASS / 0 FAIL / 6 The single FAIL is witness_ticket_brief_budget_holds_and_reds, which touches no helper here and is PRE-EXISTING: the same witness fails on the unmodified file, proven by a control run against the pre-edit source with a sibling passing in the same run. It asserts a live-population fact (no roadmap node exceeds the ticket brief budget) and is red on main today -- unnoticed because long/ is a declined home that the floor folds never. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014oG2tMMAxgZeAQxDjvNsFm --------- Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Second row of the refusal-as-empty-string lane. Sibling of #9038, independent of it — cut from clean main, not stacked.
The defect — RefusalErasure, both subforms in one file
Both rows flattened the rejection and then pattern-matched the result:
SentinelCollapse. So "the page could not be emitted" and "the page rendered the wrong thing" produce the same
false, with opposite repairs — one sends you to the emitter, the other to the presentation model.EmitRejectedcarries a reason, and the flatten throws it away.Why these two went first — VacuousNegative
Their negative conjuncts are vacuously true on the empty string:
!string_contains(active_html, "finish-line-accepted")!string_contains(h, "class=\"finish-line-progress\"")!string_contains(h, "class=\"finish-line-claim\"")On any emit rejection those cannot fail. They were decoration — permanently green, carrying no information, and cited as coverage. A row that is partly incapable of failing is worse than one that is absent (DESIGN §4b).
The assertions now run inside the
EmitOkarm;EmitRejectedreturnsfalseon its own.Both rows keep a positive anchor inside the success arm (4 positives in the finish-line row, 2 in the daily row), which is what makes the repair meaningful: a success arm holding only negatives would still be decoration, merely unreachable by a refusal. It is also why the mutant control below can go red at all — it mutates a positive conjunct, and a negative-only row would have stayed green under that mutation and told me nothing. The finish-line row nests two emits, so its second match sits inside the first arm rather than beside it.
Evidence, both directions
The unmutated sibling passing in the mutant run is what makes the red load-bearing: it is the assertion failing, not a broken harness.
BUILD_EXIT=0is there because an earlier attempt at this control ran with a deletedtarget/and produced no FAIL line at all — an instrument that never ran looks exactly like a witness that passed.Evidence limit — read this before treating a green check as coverage
dag/test/claim/long/is a declined home. The floor discovers these witnesses and folds none of them, so CI will never execute either row, in either direction, however green this PR looks. The remoteclaim_batchrun above is the only evidence that exists for this file.How to find this class in any row: mutate a conjunct and see if the row notices
The cheapest test for a decorative assertion needs no census, no naming convention, and no reading of the producer:
It generalizes past this class to any witness. Applied here it is what makes the red below load-bearing — and note which conjunct was mutated: a positive one. A row carrying only negative assertions would have stayed green under any mutation of them, because
!contains("", X)holds for every X, and it would have reported nothing while looking like a passing test.That gives the two halves of this class, which have to be stated together:
""), so two facts with opposite repairs arrive as one. Here:EmitRejected { reason: _ } => ""threw away a reason the variant carries.!string_contains(...)conjuncts.They compound. A reviewer who learns only "add a positive anchor" will pass a row whose anchor is present but unreachable — which is exactly what these two rows were. Their positives were correct and always had been; the flatten fed them
""before they could run. The missing-anchor rule and the refusal-arm repair are one wall approached from two directions, and a row needs both to be worth anything.Rung, stated honestly
This is mechanically preventable at this seam, not structurally impossible. No algebraic-data-type rule can make deliberate erasure unspellable — a caller can always write a total match returning
"". The claim is therefore the flattening has no spelling in these two rows, not RefusalErasure is now unwritable. Next-rung trigger: constraining the eliminators at the API seam so no caller can obtain artifact text from a refusal.A second collapse survives one level in, named here rather than left for a reader to find:
HtmlEmitResultisEmitOk { html: String }, so "emitted nothing" and "emitted content" remain the same value inside the success arm. Splitting that (aRenderedFragmentwith an explicit empty variant) is the real construction fix and is deferred:EmitOkis referenced 78 times across 26 files including production modules, so it is a shared-authority change needing its own decision, not a rider on a witness cleanup.What this does not reach
The same file has 11
EmitRejected => ""sites, not 2. The other 8 are in shared render helpers —authority_page_html,empty_doc_html,depth_chain_html,bold_title_html,dispatch_doc_html_for,dispatch_doc_html_for_with_merged,blocked_dispatch_workspace_html,parity_row_html— which absorb the rejection before any witness sees it, so every caller inherits the conflation. Those are the root; these two are leaves. The helper repair changes the return type toHtmlEmitResultso the flattening has no spelling, and lands separately (with the forked twin inroadmap_row_witness_test.dag, which is deleted rather than converted — it has one caller and does nothing but flatten).🤖 Generated with Claude Code
https://claude.ai/code/session_014oG2tMMAxgZeAQxDjvNsFm