Skip to content

Complete the #7470 WalkPlan migration: the fifth plan function the rename missed - #7642

Merged
briansrls merged 6 commits into
mainfrom
session/neat-owl-506
Aug 2, 2026
Merged

briansrls merged 6 commits into
mainfrom
session/neat-owl-506

Conversation

@gunbai-bot

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

Copy link
Copy Markdown
Contributor

Completes the #7470 WalkPlan migration, which landed declaring itself INCOMPLETE and missed one of five plan functions. The falsifier's native-cache cold control step has been red on every one of the 8 runs that reached it since 2026-07-30 (0 successes).

The defect

claim_executor: malformed plan value (gunbc_falsifier_native_cache_cold_batches):
expected a WalkPlan record { batches, finalization, on_success_stages },
got [[RunnableDiscoveryBatch { ... }]]

The executor is behaving correctly and this PR does not soften it. walk_plan_uniformity_note deliberately provides no fallback from a failed record parse to a bare-list reading, because that fallback would let a malformed plan run with its success stages silently dropped — the §5 silent-widen shape. The refusal is the wall working; the fix is completing the migration behind it.

It read as intermittent rather than permanent only because the step is skipped whenever the falsifier step fails first, so a deterministic red hid behind whatever witness was failing that cycle.

Root cause: a missing constant, not a miscount

walk_plan_uniformity_note claimed the consumers "follow automatically because they derive from the *_plan_function constants." That was true of four and false of the fifth — native_cache_cold_control_invoke passed plan_function: "gunbc_falsifier_native_cache_cold_batches" as an inline string literal, so it derived from nothing and no rename could reach it. The wrong census (FOUR) was the symptom.

So the repair adds the constant rather than only correcting the sentence — a prose census is validation, the constant is construction (§5):

  1. gunbc_falsifier_native_cache_cold_plan() returns WalkPlan<NoWalkFinalization>.
  2. New naming authority falsifier_native_cache_cold_plan_function (gunbc.falsifier_workflow); the step derives from it, so the next rename cannot skip this consumer.
  3. walk_plan_uniformity_note corrected FOUR→FIVE, incident recorded rather than quietly patched, with the residual gap named: nothing yet refuses a fresh inline literal at a plan_function position. Dissolve-on stated.
  4. The witness roster also counted four — ci_floor_plan_witness imported four plan functions and asserted plan_carries_no_finalization on three. That note names those rows as the enforcement, so the fifth had none, which is why nothing could red on this. Added.

Evidence (green by execution)

  • The exact CI invocation claim_executor --plan-entry src/v2/workflow/ci_floor_plan.dag --plan-function gunbc_falsifier_native_cache_cold_plan now exits 0 with zero malformed plan value, running the native-cache cold batch to completion.
  • falsifier_native_cache_cold_plan_carries_no_finalization returns true.
  • Generated-artifact drift gate ExitSuccess (byte-idempotent fixed point).
  • RED control is on the real acceptance path: the identical invocation refused on 8 consecutive CI runs under the bare-list shape.

Note on the regenerated workflow

.github/workflows/falsifier.yml is committed here rather than auto-healed. The heal job regenerates it correctly but cannot push it — GitHub refuses to let a GitHub App update .github/workflows/* without workflows permission (receipt: run 30722802575 job 91429923479, main_wet succeeded, push step failed). Any change to a generated workflow artifact must be committed by the authoring session.

The structural guard (added on review)

Repairing only the rename would leave intact the mechanism that let the fifth consumer escape. plan_function was an unconstrained String crossing the modeled boundary, so plan identity was an argv token nothing could check and completeness could only ever be a hand-maintained count.

gunbc.cli_invoke PlanFunction is now a closed coproduct; claim_executor_run_plan_shell and _transport_argv take a variant:

  • An inline string literal at a plan_function argument is a type error — the incident class is unwritable, not validated.
  • A new production target cannot be authored without adding a variant, and every exhaustive match over PlanFunction fails to compile until it is handled. Completeness is structural, not a recount.
  • The interim naming constants are deleted, not kept beside the wall (§4b dissolution-on-climb). floor_plan_function and friends survive only as name projections for the floor predicates that still compare a String, and say so.

New witness rows: an exhaustive match proving every declared target's plan value carries its declared finalization; emitted-argv rows tying each variant to what CI actually runs; and a permanent regression control that the pre-repair literal is absent from both generated workflows.

No fake control was written for the exhaustiveness itself. The obvious candidate — fold a short list and assert refusal — is a tautology that passes for the wrong reason. That guarantee is compile-time (a sixth variant breaks the build), so its control is a compile failure, not a Bool. Recorded in plan_roster_control_placement_note rather than papered over with a green row that cannot go red.

Emission is byte-identical: regenerating after the refactor changes no artifact, so the type work altered no CI behavior.

Bound, stated

This closes which targets exist. It does not prove the argv token resolves to that function — the variant-to-value pairing is hand-authored, since resolving a name to a declaration needs the containment SymbolIndex the namespace lane is building. A variant mapped to the wrong plan value would still pass. Dissolve-on: a typed DeclarationRef over a resolved plan symbol.

Corrections to my own earlier report

  • My falsifiability prediction failed. I predicted run 30718084989 would clear the HeadCommit refusal and then visibly fail on the malformed native-cache plan. It cleared HeadCommit, but failed earlier at generated-artifact drift, so native-cache was skipped and the predicted sequence was never observed. The source-level contradiction still proves the step fails when reached; it was not empirically demonstrated in that run.
  • 900001ms > 900000ms proves a witness reached its deadline. It does not by itself establish corpus growth as the cause — that needs a timing trend or phase profile.
  • One correction I checked and did not apply: WalkPlan success stages + in-executor floor finalization (INCOMPLETE — see known gaps) #7470's title. The GitHub API returns WalkPlan success stages + in-executor floor finalization (INCOMPLETE — see known gaps), which is what I quoted.

Scope

Deliberately narrow, per coordination with eager-boar-610 (who confirmed this is not tracked in their lane): the falsifier plan function, its naming authority, the two censuses, and the regenerated yml. quick-heron-791 has in-flight edits to different functions in ci_floor_plan.dag on #7522.

Not addressed

The falsifier streak has other independent causes, left for their own lanes: a 900001ms > 900000ms budget overshoot in resolution_divergence_silent_pick_gate_keystone_holds, inert_carrier_no_unrostered_or_stale, and a git.Inspect.HeadCommit hermetic refusal already fixed on main by #7607.

🤖 Generated with Claude Code

gunbc-ci-auto-heal and others added 2 commits August 1, 2026 23:10
The auto-heal job regenerates this correctly but cannot push it: GitHub
refuses to let a GitHub App create or update .github/workflows/* without
`workflows` permission, so any change to a generated WORKFLOW artifact must
be regenerated and committed by the authoring session. Receipt: run
30722802575 job 91429923479, which ran main_wet successfully and then failed
only at the push step with `refusing to allow a GitHub App to create or
update workflow .github/workflows/falsifier.yml`.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gunbai-bot gunbai-bot Bot changed the title falsifier is red again Complete the #7470 WalkPlan migration: the fifth plan function the rename missed Aug 1, 2026
gunbc-ci-auto-heal and others added 2 commits August 1, 2026 23:56
Review finding: repairing only the missed rename leaves intact the mechanism
that let the fifth consumer escape a migration claiming to cover "all four".
plan_function was an unconstrained String crossing the modeled boundary, so
plan identity was an argv token nothing could check and completeness could
only ever be a hand-maintained count.

gunbc.cli_invoke PlanFunction is now a closed coproduct; claim_executor_run_
plan_shell and _transport_argv take a variant. An inline string literal at a
plan_function argument is a TYPE ERROR, and a new production target cannot be
authored without adding a variant, which makes every exhaustive match over
PlanFunction fail to compile until it is handled.

The interim naming constants added in the previous commit are DELETED rather
than kept beside the wall (4b dissolution-on-climb); floor_plan_function and
friends survive only as name projections for the floor predicates that still
compare a String, and say so.

New witness rows in v2.test.claim.ci_floor_plan_witness: an exhaustive match
proving every declared target's plan value carries its declared finalization,
the emitted-argv rows tying each variant to what CI actually runs, and a
permanent regression control that the pre-repair literal is absent from both
generated workflows. No fake control was written for the exhaustiveness
itself: that guarantee is compile-time, and a runtime row for it would be a
tautology that cannot go red -- recorded in plan_roster_control_placement_note.

Emission is byte-identical: regenerating after the refactor changes no
artifact, so the type work altered no CI behavior.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review August 2, 2026 00:07
The finding is correct and is a rung-inflation defect in my own notes, which
DESIGN 4b calls worse than sitting low: an inflated class never ranks for
climbing. Adding a PlanFunction variant forces a match ARM TO EXIST; it does
NOT force that arm to be EXECUTED, because the witness roster is a
hand-authored list. Since a declared return type is not checked against its
body, a malformed new arm could sit unexecuted while the row stayed green.
The note claimed "the set of targets and the set of proofs are the same set,
by construction". That was false.

Corrected, not softened:
- every_production_plan_target_is_walk_plan_shaped renamed
  declared_plan_targets_are_walk_plan_shaped; it no longer claims universality
  in its own name.
- the roster is extracted to plan_target_roster so the hand-authored set is a
  named carrier rather than an inline literal hidden in the assertion.
- plan_roster_exhaustiveness_note now states enforced / not-enforced
  separately, and points at the rows with real teeth for this incident class:
  the emitted-argv rows, which read the generated workflows CI actually runs.
- the same overclaim is corrected where I repeated it in
  gunbc.cli_invoke plan_function_closed_roster_note and in
  v2.workflow.ci_floor_plan walk_plan_uniformity_note.

Full structural closure needs variant enumeration over a closed coproduct,
which the language does not offer; that is recorded as the dissolve-on rather
than implied, per 4b's no-untracked-stall rule. The production type wall is
unchanged and regeneration remains byte-identical.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gunbai-bot

gunbai-bot Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor Author

review 46883 — finding accepted and fixed in b193b25acbc.

The finding is correct, and it is a rung-inflation defect in my own notes — which DESIGN §4b calls worse than sitting low, because an inflated class never ranks for climbing. Verified against the code before fixing: every_production_plan_target_is_walk_plan_shaped fed every_plan_target_shaped a five-element inline list. Adding a PlanFunction variant forces a match arm to exist; it does not force that arm to be executed. Combined with the probe this file already records — a declared return type is not checked against its body — a malformed new arm could sit unexecuted while the row stayed green.

So the sentence "the set of targets and the set of proofs are the same set, by construction" was false. That is exactly the completeness failure this PR exists to remove, restated one level up.

What changed

  • every_production_plan_target_is_walk_plan_shaped → declared_plan_targets_are_walk_plan_shaped. It no longer claims universality in its own name.
  • The roster is extracted to plan_target_roster, so the hand-authored set is a named carrier rather than an inline literal buried in the assertion.
  • plan_roster_exhaustiveness_note now states enforced and not enforced separately: enforced is "no target can exist without an arm" (compile-time); not enforced is "that arm is executed", because the roster is hand-maintained. It also points at where the real teeth are for this incident class.
  • I repeated the same overclaim in two other notes I wrote; both are corrected — gunbc.cli_invoke plan_function_closed_roster_note and v2.workflow.ci_floor_plan walk_plan_uniformity_note.

Why not full structural closure. I tried. It needs variant enumeration over a closed coproduct, and the language does not offer it — I checked a next-variant chain, which still lets a sixth variant dangle off the end unwalked, and there is no substring-occurrence primitive to derive the roster from the emitted argv instead (only concat / string_contains / string_head / string_tail / string_length / string_is_empty). Rather than ship a weaker mechanism dressed as the stronger one, the gap is recorded as the dissolve-on, per §4b's no-untracked-stall rule.

On where the guarantee actually lives. For the class that caused this incident, the rows with teeth are every_emitted_plan_target_names_its_variant and no_emitted_plan_target_retains_the_batches_shape, which read the generated workflows — what CI actually executes. An emitted target is the only kind that can break CI, and those rows tie emissions to declared variants rather than to the hand roster. The note now says so instead of resting the claim on the roster row.

The production type wall is unchanged (plan_function remains a PlanFunction, so an inline literal is still a type error), and regeneration remains byte-identical after these edits.

— sent from neat-owl-506

@gunbai-bot

gunbai-bot Bot commented Aug 2, 2026

Copy link
Copy Markdown
Contributor Author

review 46909 — finding accepted and fixed in b3b4b2fe1e6. One correction to the stated mechanism, established by experiment rather than argued.

The defect is real and it was mine. When I deleted the now-dead regen_floor_plan_function constant, the same edit also stripped CiRegenFloorPlan from the gunbc.cli_invoke import list, while the call site in scheduler_invoke_with kept using the variant. Import restored.

I also audited the rest of the diff for the same class — every other cli_invoke symbol flagged by a naive scan turned out to be my own note prose naming the symbol, not a code reference. CiRegenFloorPlan was the only real one.

The mechanism is not what the finding says. The finding states the reference is "unresolved" and the changed DAG is "statically invalid". I ran the controlled experiment before replying — removed the import again, recompiled:

  • corpus compiles
  • dag/tools/generated_artifact_gate.dag::main returns ExitSuccess

So the reference does resolve and the DAG is not statically invalid. ci_spec.dag already imports gunbc.cli_invoke for other symbols (claim_executor_run_plan_shell, PlanFunction, CiFloorPlan, …), so the module is in the pool and the resolver finds the variant whether or not the explicit list names it. Worth being precise about, because it means the whole-tree search that "confirmed" the reference was unresolved was reading the import list, not resolution behavior.

Why I fixed it anyway. It is an undeclared symbol dependency rather than a build break, and that is still a real defect: the import list is the declared dependency edge (§3), and the namespace lane intends exactly this lookup to tighten to "own declarations ∪ direct import lists" — at which point an undeclared reference becomes a hard failure. It is also the pool-membership-coincidence shape DESIGN already tracks in the import-strip cascade thread, where a reference resolves only because something else dragged the target into the closure. Silent today, breaking later, is precisely the class worth closing while it is cheap.

Re-verified after the fix: declared_plan_targets_are_walk_plan_shaped → true, every_emitted_plan_target_names_its_variant → true, regeneration byte-identical.

— sent from neat-owl-506

@briansrls
briansrls merged commit dec89b6 into main Aug 2, 2026
5 checks passed
@briansrls
briansrls deleted the session/neat-owl-506 branch August 2, 2026 01:28
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