Skip to content

An expected-red enrolment cannot hold an identity that never executes - #9036

Closed
gunbai-bot[bot] wants to merge 1 commit into
mainfrom
session/smart-ram-730-expected-red-declined
Closed

gunbai-bot[bot] wants to merge 1 commit into
mainfrom
session/smart-ram-730-expected-red-declined

Conversation

@gunbai-bot

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

Copy link
Copy Markdown
Contributor

Main is red on a stale expected-red roster

Required CI on main refuses with:

REQUIRED-FLOOR REFUSAL cause=ExpectedRedIdentityDidNotExecute count=3
  test.claim.compile_accepted_unevaluable_program_control.primitive_call_with_extra_argument_must_refuse_at_compile
  test.claim.compile_accepted_unevaluable_program_control.primitive_call_with_missing_argument_must_refuse_at_compile
  test.claim.compile_accepted_unevaluable_program_control.primitive_call_with_wrong_argument_type_must_refuse_at_compile

These three were enrolled by #9022. Their file declares ReadsLiveTree, so it is DeclinedLiveTree — discovered, counted, and never executed. The floor requires every enrolled expected-red identity to be observed among the executed claims, so an enrolment for an unexecutable identity is stale by construction, not by drift.

The defect is the belief, not the three rows

The enrolment's own annotation said the enrolment was protective:

"Until it lands they are held here so that admission does not red main."

That is backwards. Enrolment does not shelter a not-yet-planned identity — it is the thing that reddens main. Nothing in the tree relates the expected-red roster to the decline arm, and no carrier was consulted to check: the claim was that registering in A makes B behave, with B never named.

That is the authority substitution class from DESIGN's recurring-failure-modes paragraph, and this is a second receipt for it. The tell is exactly the one the class describes — a sentence of the form "I registered it in A, so B now does X" where B never appears.

Why it went unseen

An unrelated ArgvCommand seal break stopped strict preparation before the fold, so the roster check never ran. Repairing that break (#9031) did not cause this failure — it revealed it. Two breaks from one landing, the second masked by the first, which is the same masking shape that hid downstream defects behind an annotation break earlier today.

The repair uses the vehicle that already exists

floor_expected_red_is_live already excludes rows kept for provenance but not currently live — the mock-totality family uses it for precisely this case. The three names join that exclusion. The chunk rows stay for provenance, so nothing is lost.

No new mechanism, no second roster, no parallel authority.

Dissolution is a deletion, not an addition

When the decline arm lands (#8977, #8982) and the file executes, remove the three exclusions. Nothing has to be re-added, and the removal is the signal that the class closed.

What this does NOT claim

This repairs one roster, not the class. Nothing prevents the next author enrolling an identity that cannot execute. The floor still catches it only at the end of a ~40-minute run, and only when no earlier refusal masks the check — which is exactly what happened here.

Next-rung trigger: enrolment deriving admissibility from the identity's own home disposition, so an unexecutable enrolment is unwritable rather than caught forty minutes later.

Test plan

  • The refusal names the three identities exactly; they are now excluded from the live roster and retained in the chunk for provenance.
  • The corrected annotation states the floor's actual rule in place of the inverted one, with the run and cause that falsified it.
  • CI on this branch is the check: the floor's ExpectedRedIdentityDidNotExecute refusal must not recur. Note the branch still inherits Convert the one ArgvCommand site the seal missed, through a builder rather than by widening the seal #9031's argv fix requirement and the observed rustfmt: Text file busy regen race, neither of which is this PR's.

🤖 Generated with Claude Code

Main's required run refuses with ExpectedRedIdentityDidNotExecute count=3, naming
the three compile_accepted_unevaluable_program_control rows landed by #9022:

  primitive_call_with_extra_argument_must_refuse_at_compile
  primitive_call_with_missing_argument_must_refuse_at_compile
  primitive_call_with_wrong_argument_type_must_refuse_at_compile

THE FILE DECLARES ReadsLiveTree, so it is DeclinedLiveTree: discovered, counted,
and never run. The floor requires every enrolled expected-red identity to be
OBSERVED AMONG THE EXECUTED CLAIMS, so enrolling an unexecutable identity makes
the roster stale by construction.

THE ENROLMENT'S OWN ANNOTATION ASSERTED THE OPPOSITE, and that is the defect
worth naming rather than the three rows. It read "held here so that admission
does not red main" -- believing enrolment protects a not-yet-planned identity.
It does the reverse: the enrolment IS what reddens main. Nothing related the
expected-red roster to the decline arm, and no carrier was consulted to check;
the claim was that registering in A makes B behave, with B never named. That is
the authority-substitution class DESIGN's recurring-failure-modes paragraph
records, and this is a second receipt for it.

IT WENT UNSEEN FOR A REASON WORTH RECORDING: an unrelated ArgvCommand seal break
stopped strict preparation before the fold, so the roster check never ran. Fixing
that break did not cause this one -- it revealed it. Two breaks from one landing,
the second masked by the first.

THE REPAIR USES THE EXISTING VEHICLE, not a new one. floor_expected_red_is_live
already excludes rows kept for provenance but not currently live -- the
mock-totality family uses it for exactly this. The three names join that
exclusion; the chunk rows stay for provenance.

DISSOLUTION IS A DELETION, NOT AN ADDITION: when the decline arm lands
(gunbc#8977, gunbc#8982) and the file executes, remove the three exclusions.
Nothing has to be re-added.

WHAT THIS DOES NOT CLAIM. This repairs one roster, not the class. Nothing
prevents the next author enrolling an identity that cannot execute -- the floor
still catches it only at the end of a full run, and only when no earlier refusal
masks the check. The next-rung trigger is enrolment deriving admissibility from
the identity's own home disposition, so an unexecutable enrolment is unwritable
rather than caught ~40 minutes later.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gunbai-bot gunbai-bot Bot changed the title emission convergence An expected-red enrolment cannot hold an identity that never executes Aug 23, 2026
@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review August 23, 2026 16:44
@gunbai-bot

gunbai-bot Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor Author

Completeness join — this is the only instance of the class, not a sample

The three identities in this PR were found because they reddened main. That says nothing about whether others of the same shape are enrolled and waiting to surface, so I joined the two populations directly rather than assuming.

Method: every identity enrolled in floor_expected_red (203), against every .dag module whose source declares = ReadsLiveTree (158). An identity is in the failing class exactly when its module appears in both — enrolled as expected-red, and declined before the fold so it can never be observed among executed claims.

Result: exactly one intersection.

test.claim.compile_accepted_unevaluable_program_control
  -> dag/test/claim/compile_accepted_unevaluable_program_control_test.dag

That is the module this PR excludes. No other enrolled identity is declined, so there is no fourth break of this class queued behind the merge.

Why that matters for sequencing: today's failures have surfaced one at a time, each revealed by repairing the one in front of it — the ArgvCommand seal break masked this refusal by stopping strict preparation before the fold ever ran the roster check. A reasonable worry after two such reveals is that the next merge exposes a third. For this class specifically, it does not.

What this does not cover, stated so the join is not read as broader than it is:

  • It answers one question — enrolled ∧ ReadsLiveTree. An identity could fail to execute for a reason other than the live-tree decline (a long-home decline, a route gap, a discovery miss), and this join would not see it. route_gap and stale_route_gap are separate gating populations with their own refusals.
  • It reads the declaration, not the run. A module declaring ReadsLiveTree is declined today; if the decline arm changes, the join changes with it — which is exactly the dissolution trigger this PR names.
  • The 203/158 counts are from the current tree and will drift; the join is the check, not the numbers.

— sent from smart-ram-730

@gunbai-bot

gunbai-bot Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor Author

Nothing to push — this failure is the other half of a two-PR deadlock, now measured on both sides

The failing check is the floor phase, and every error in it is the ArgvCommand seal break this PR does not touch:

dag/gunbc/runner_slot_provision.dag:240:28  field 'argv' not found in type 'ArgvCommand'
dag/gunbc/runner_slot_provision.dag:240:14  sole_constructor type 'ArgvCommand' cannot be
                                            constructed outside its defining module
dag/gunbc/runner_slot_provision.dag:240:14  missing required field 'program'
dag/gunbc/runner_slot_provision.dag:240:14  missing required field 'arguments'

ExpectedRedIdentityDidNotExecute count on this run: 0. This PR's own fix works — the refusal it removes is gone, and what remains is a break that arrived from main.

The deadlock is now confirmed from both directions, not inferred

PR fixes still carries its run's failure
#9031 ArgvCommand seal stale expected-red roster ExpectedRedIdentityDidNotExecute count=3, 0 argv errors
#9036 (this) stale expected-red roster ArgvCommand seal 4 argv errors, 0 expected-red refusals

Each PR's run shows its own fix landing and dies on the break the other one repairs. Both are cut from main, so neither can carry both. Neither can go green alone, and no work inside either changes that — waiting for individual green checks waits forever.

Both are approved, mergeable=MERGEABLE, blocked solely on checks.

What I am deliberately not doing

I could merge #9031's one-line change into this branch and manufacture a green. I have not, because fusing two unrelated repairs into one vehicle makes each harder to revert independently, and these have genuinely different causes, owners and dissolution conditions — one is a call site that predated a seal, the other an enrolment that asserted the opposite of what the floor does.

The precedent set earlier today was to merge a mutually-blocking set together rather than fuse it. That is an operator action, and it is where this sits.

One thing that de-risks the merge

A completeness join posted above establishes that this is the only instance of its class: 203 enrolled expected-red identities against 158 modules declaring ReadsLiveTree, exactly one intersection, and it is the module this PR excludes. So no third refusal of this shape is queued behind the merge — which matters, because today's breaks have surfaced one at a time, each revealed by repairing the one in front of it.

— sent from smart-ram-730

@gunbai-bot

gunbai-bot Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor Author

Closing: consolidated onto #9031, which now carries this exact change to src/v2/workflow/floor_expected_red.dag alongside the ArgvCommand seal repair.

The reason for consolidating rather than leaving both open is that neither could go green alone. Main's floor refuses at compile on the argv break before any witness executes, so the stale enrolment here was masked; and this change alone leaves that compile refusal in place. Two PRs answering for one merge is the duplication that makes a green run ambiguous about which fix produced it.

Verified on #9031 head 63409bf3b, run 32652914269: the floor now executes — planned=10695 executed=10695 terminal=10695 — and the three test.claim.compile_accepted_unevaluable_program_control.* identities no longer appear under any known-red cause (known_red_now_passing=0, no ExpectedRedIdentityDidNotExecute). That is this change working, measured. Merge #9031.

@gunbai-bot gunbai-bot Bot closed this Aug 23, 2026
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.

0 participants