Skip to content

Stop two roadmap_page witnesses rendering an emit rejection as an empty string - #9040

Merged
briansrls merged 3 commits into
mainfrom
session/bold-raven-901-roadmap-page
Aug 24, 2026
Merged

briansrls merged 3 commits into
mainfrom
session/bold-raven-901-roadmap-page

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Aug 23, 2026 •

Copy link
Copy Markdown
Contributor

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:

let h = match try_serialize_html_source(node: ...) {
  EmitOk { html: page } => page
  EmitRejected { reason: _ } => ""
}
string_contains(s: h, pattern: "class=\"program-progress\"") && ...

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. EmitRejected carries 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 EmitOk arm; EmitRejected returns false on 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

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):
        BUILD_EXIT=0
        FAIL witness_daily_leads_operational_not_narrative
        PASS witness_finish_line_variants_render_from_fixture   <- positive control, same run

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=0 is there because an earlier attempt at this control ran with a deleted target/ 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 remote claim_batch run 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:

Mutate a conjunct the row claims to assert. If the row stays green, that conjunct is decoration.

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:

  • SentinelCollapse — a refusal and a valid empty result share one value (""), so two facts with opposite repairs arrive as one. Here: EmitRejected { reason: _ } => "" threw away a reason the variant carries.
  • VacuousNegative — an assertion that an empty value satisfies permanently, so it can never fail. Here: three !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: HtmlEmitResult is EmitOk { html: String }, so "emitted nothing" and "emitted content" remain the same value inside the success arm. Splitting that (a RenderedFragment with an explicit empty variant) is the real construction fix and is deferred: EmitOk is 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 to HtmlEmitResult so the flattening has no spelling, and lands separately (with the forked twin in roadmap_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

…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
@gunbai-bot

gunbai-bot Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor Author

The witnesses red is main's, not this PR's, and cannot be closed from this branch.

required-ci: floor refused: subject=f6e5e6a4134205f0 modules_resolved=3847 modules_excluded=4
dag/gunbc/runner_slot_provision.dag:240:14: error: sole_constructor type 'ArgvCommand'
    cannot be constructed outside its defining module

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, dag/test/claim/long/ is a declined home — the floor discovers these witnesses and folds none of them. So a green witnesses check on this PR will still not mean these two rows ran. The evidence for them is the remote claim_batch run recorded in the description (green, plus a discriminating red with a same-run positive control), and that remains the only evidence that exists for this file.

— sent from bold-raven-901

@briansrls
briansrls merged commit 1c3cadc into main Aug 24, 2026
2 checks passed
@briansrls
briansrls deleted the session/bold-raven-901-roadmap-page branch August 24, 2026 00:33
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant