Skip to content

S3: enrol a REQUIRED CI phase that actually runs cargo over an emitted closure, with a discriminating red established by MUTATION not inspection — one arm failing ALONE, with a restore between, or it is a decoration cited as coverage - #9528

Closed
gunbai-bot[bot] wants to merge 13 commits into
mainfrom
session/deep-gull-307

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

Auto-opened by session-dashboard for session deep-gull-307.
Pushing to session/deep-gull-307 advances this PR.

Worker attestation

Before flipping this PR to ready for review, confirm each item:

  • Title describes the change (not the session id or branch).
  • PR body summarises what and why (replace the TODO below).
  • Tests run: name the command (e.g. npm test, cargo test) and the result.
  • If this closes a work item, the body contains a Closes #N directive.
  • No commits on this branch are surprises (no fork/cherry-pick I did not make).
  • No secrets / credentials / large binaries staged.

Summary

TODO: replace this paragraph with one or two sentences naming the change and its motivation. Reviewers read this first.

Test plan

  • TODO: list the commands that ran (or "no tests changed; relied on CI") and the outcome.

gunbc-ci-auto-heal and others added 13 commits August 27, 2026 04:52
…tablished by mutation

Closes the executing half of DESIGN's declared rung drop "A BLOCKING EMIT-STAGE
DIAGNOSTIC CAN SIT ON MAIN INDEFINITELY WITH NO REQUIRED PHASE THAT FAILS": the
v2-emission phase emits and stops, and nothing downstream compiles what it
emitted. This is the missing conjunct -- same producer, the emitted files
written as a crate, cargo run over it.

The red is manufactured every run rather than found. A green baseline alone is
not a pass: the phase injects one type error into one emitted closure member,
requires cargo to fail alone on it, restores the bytes byte-exactly and requires
the green back. NotAttempted, NotDiscriminating and RestoreFailed each fail the
phase, and a failed restore is terminal for the run rather than a per-entry
finding siblings continue past.

Membership is declared, admission measured, degradation red. The remainder is
reported as retained identities with counts and digests, never as a percentage,
and the phase's success means the selected observation was taken and persisted
-- never that the corpus is clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
DESIGN.md is a generated artifact (gunbc.generated_artifact DesignArtifact,
.gitattributes merge=generated-artifact); its prose lives in
gunbc.design_document. Editing the artifact leaves the authority untouched, so
the next regen re-derives DESIGN.md and silently drops the edit -- and the
generated-artifact drift gates are on DESIGN's own unguarded list from the floor
cut, so no required run refuses it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
# Conflicts:
#	.gitattributes
#	DESIGN.md
#	dag/gunbc/design_document.dag
#	dag/gunbc/seed_growth_admission.dag
#	dag/gunbc/stage0_crate_layout_generated.dag
#	src/v1/stage0/src/bin/claim_executor.rs
#	src/v1/stage0/src/bootstrap_stage0_crate_layout_generated.rs
#	src/v1/stage0/src/gunbc_stage0_crate_layout_generated.rs
…ed stage0 layout mirror

The phase compiled every roster entry under one package name and version into a
shared CARGO_TARGET_DIR, so the only thing separating two entries' cargo
fingerprints was cargo's use of the manifest path -- an implementation detail of
a tool, load-bearing for a merge gate, stated nowhere. Had a build ever been
judged fresh against another entry's artifacts, cargo would replay that entry's
cached diagnostics, and a replayed clean compile is byte-identical in the output
to a real one: the arm would report Completed status=0 for an entry it never
compiled and the gate would go green over it. Fail-open.

Deriving the package name from the entry makes each probe crate its own package,
so the fingerprints cannot alias. Dependencies are separate packages and stay
shared, so the warmth the target dir buys is untouched.

The layout mirror is installed from the regen candidate rather than hand-edited:
main added namespace_wave_admission.rs and target_invocation_host.rs while this
branch was open, and the merge's ours-side resolution of a generated file
dropped them.

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

The mutation arm accepted any non-compiling cargo verdict as evidence of the
injected type error. A killed cargo, a spawn failure, or a red for an unrelated
reason all satisfy !cargo_verdict_compiled, so the arm could report
Discriminated -- and green a required gate -- while establishing nothing about
sensitivity to the emitted bytes. That is a fabricated red inside the phase
whose whole purpose is to refuse fabricated evidence.

The arm now demands three things of the faulted run, each ruling out a different
way the old check could be satisfied without measuring anything: Completed, so a
run that never reached a verdict is not a red; nonzero, so it refused; and a
diagnostic naming the injected symbol, so it refused for OUR reason rather than
for something already wrong in the tree.

Attribution is scanned from the whole stderr and carried on the verdict, not
read from stderr_tail: the tail is the last 20 lines and a genuine diagnostic
for the injected item can sit above it, so deciding attribution from the tail
would fail runs whose fault WAS refused. The reported red line is the same line
the check accepted, so the receipt cannot disagree with the evidence.

Executed both ways at one entry: normal injection Discriminated with the probe
line quoted, RC=0; the same fault renamed so no diagnostic mentions the probe
symbol, NotDiscriminating, RC=1.

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

Every roster entry's baseline returned status=101 in CI while returning status=0
locally. The emitted v1_rt.rs gates on #[cfg(feature =
"text_lookup_work_counter")]; the probe manifest declared no [features] section;
and a crate referencing a feature it does not declare earns unexpected_cfgs,
which is a WARNING locally and a hard ERROR under CI's RUSTFLAGS=-D warnings. So
the phase reported a red on every entry that had nothing to do with the emitted
closure.

The corpus already carried this finding. gunbc.self_host_logic_behavioral_transport
slb_cargo_features_note records the same exit=101 and the same mechanism, and
predicts the general case in as many words: any -D-warnings consumer of a
gunbc-emitted crate breaks the same way because the emitted Cargo.toml omits the
block. This phase is that consumer.

The section is rendered from stage0_partition_row_features and
render_stage0_crate_features_section -- the authority the partition crates
already use -- rather than from a third hand-concatenated [features] string
beside the two the corpus carries.

Verified under CI's own condition rather than the default: with RUSTFLAGS="-D
warnings", all 8 entries report baseline Completed status=0 and mutation
Discriminated with the probe line quoted, RC=0. The five verification arms all
passed before this fix; none of them could have caught it, because none ran with
the flags the required lane sets.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…dicate restore first

Three defects, two of them found by the gate's own first real runs.

THE ROOT WAS HOST-SHARED. probe_root() was a fixed path in the system temp dir.
On a self-hosted runner /tmp persists across runs, slots and tenants, so the
directory already existed owned by another uid and the lock returned EACCES. The
phase refused permanently -- red on every future PR landing on that runner, with
the only closing move being someone deleting a directory over SSH. A required
gate whose sole remedy is manual host intervention outside the repository has no
reachable green. RUNNER_TEMP is per-job and owned by the process that needs it,
and it changes nothing the shared target dir buys: one run's entries still share
workspace/target, and per-entry package names still separate them within it.

A LIVE PEER AND AN UNWRITABLE ROOT ARE OPPOSITE REMEDIES. AlreadyExists said
"investigate a concurrent run" and every other errno fell into one catch-all, so
EACCES rendered as that message's neighbour and sent a reader hunting a peer
that did not exist. They are now separate refusals; the second names the path and
says the root is wrong. The lock's own rationale is narrowed with it: under a
per-job root, concurrent collision is closed by construction, so what the lock
still catches is an attempt in THIS job that died mid-flight.

RESTORE IS ADJUDICATED BEFORE EVERY FAULT VERDICT. The fault arms return
NotDiscriminating, which fails one entry and lets siblings continue; only
RestoreFailed ends the run. Deciding the fault first therefore swallowed a
terminal failure whenever both conditions held at once, and a later baseline
could run against a tree whose state nobody established. The byte half is
adjudicated first because it is free; whether the restored tree compiles stays
below the fault verdicts, being a question about attributing a red the arm has
already declined to claim. A test pins the ORDER rather than the arms, because
both orders typecheck and only one is safe.

The build lane's step name no longer enumerates phases. It read "(regen, v2
emission)" while the lane carried four, and a session triaging a red narrowed to
the two it named and could not reach the one that failed. The run announces its
own roster before any phase executes; the label points there.

Verified under the lane's own conditions: RUNNER_TEMP set and RUSTFLAGS="-D
warnings", all entries baseline Completed status=0 and mutation Discriminated,
RC=0, crates written under RUNNER_TEMP. The EACCES arm executed separately
against an unwritable root returns its own refusal naming the path.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…uthority by crate kind

Two findings, both from review.

ROOT SPELLED TWICE. When the probe root moved to `RUNNER_TEMP`,
`emit_compile_report` was left re-deriving `std::env::temp_dir()
.join("gunbc-emit-compile")` by hand, so the crate directories landed on
the runner path while the retained remainder still went to the shared
host `/tmp` -- the exact EACCES the reroot closed, reopened one line
away from the fix. `emit_compile_report` now calls `probe_root()`, and
`the_probe_root_name_is_composed_in_exactly_one_place` pins that there is
one composition site. That test assembles its own needle with `format!`
rather than writing the literal, because a literal in the test body is
itself a second spelling and the first cut of the test failed by
counting itself.

Verified by execution under `RUNNER_TEMP=/tmp/rt-verify-final`: the
remainder is retained at `<RUNNER_TEMP>/gunbc-emit-compile/
emit-compile-not-selected.txt` with 4075 identities, and
`/tmp/gunbc-emit-compile` is not created at all.

FEATURES AUTHORITY. The probe manifest needs the same `[features]` the
generated foundation crate declares -- without it `unexpected_cfgs` is a
warning locally and a hard error under CI's `-D warnings`, which is what
put all 8 baselines at `status=101`. `v1.compiler.stage0_crates` now
exposes `stage0_features_for_crate_kind`, and
`stage0_partition_row_features` is derived from it, so the host reads the
modeled authority instead of copying either of the two hand-authored
feature strings that already existed in the tree. The stage0 mirror is
the emitter's own candidate, installed rather than hand-written.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Two conflicts, both in GENERATED PROJECTIONS -- DESIGN.md and
.github/workflows/witnesses.yml -- while their .dag authorities merged
cleanly. The merge driver refused rather than picking a side, which is
correct: with both sides changed since the merge base, neither side's
bytes are the projection of the merged authorities. Resolved by
regenerating from authority, never by hand-editing the artifacts.

VERIFIED THE MERGE INPUTS BEFORE REGENERATING, which is the order that
matters -- regenerating from a badly merged authority produces
correct-LOOKING bytes that launder the bad merge. `design_document.dag`
differs from origin/main by exactly the two `li(text:)` lines that are
mine; `witness_floor_workflow.dag` retains main's #9398 content (the
bypass_actors correction, the YamlKeyValue import) beside my
emit-compile edits.

RESTORED 1093 CHARACTERS MAIN WOULD OTHERWISE HAVE LOST. Diffing the
regenerated DESIGN.md against main's showed THREE changed lines where
exactly two were mine. The third was a complete recurring-failure-mode
entry -- **bound-shaped closure**, with a receipt citing gunbc#9418 --
present in main's committed DESIGN.md and in NO .dag authority:

  git grep bound-shaped origin/main -- 'dag/**' 'src/v2/**'  -> EMPTY
  git grep -l 'hollow alias' origin/main -- 'dag/**'         -> 3 files

with the second line as the positive control proving the search works.
Both plausible homes were checked: `gunbc.design_document` has none, and
`gunbc.recurring_failure_mode` -- the actual authority for that line --
had none either. So the entry lived only in the projection, and ANY
regeneration on ANY branch deletes it silently, as a side effect of an
unrelated merge.

It is added to `gunbc.recurring_failure_mode` as `bound_shaped_closure`,
transcribed verbatim from main's published bytes (captured
programmatically, not retyped) and placed in the roster between
positional_citation and authority_substitution to match main's
rendering. This is a RELOCATION to the authority, not an authoring: not
a character of the content is mine. After it, the regenerated DESIGN.md
differs from main's by exactly the two lines this branch owns, and the
failure-modes line is byte-identical.

Unrelated regeneration side effects were reverted rather than swept in:
one plan doc main has not regenerated, and two plan files the generator
emits that have never existed on main. Those are main's drift and are
not this branch's to land.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Second merge of main in one resolution: main advanced 9 commits while the
first regeneration was running, so the same two generated projections
re-conflicted. That is a property of the projection being SHARED -- nearly
every lane edits DESIGN.md -- not of the resolution, and no amount of care
wins the race, only merging sooner.

The .dag authorities merged cleanly again, carrying BOTH main's new
`diagnostic_name_mechanism_silent` row (#9414) and this branch's restored
`bound_shaped_closure`. Only the projections conflicted, and they are
regenerated rather than hand-resolved.

THE REGENERATED DESIGN.md NOW DIFFERS FROM MAIN BY THREE LINES AND ALL
THREE ARE ACCOUNTED FOR. Two are this branch's own edits. The third is the
recurring-failure-mode line, and it differs because MAIN'S DESIGN.md IS
STALE AGAINST ITS OWN AUTHORITY IN THE OPPOSITE DIRECTION FROM THE ORPHAN
REPAIRED IN THE PREVIOUS COMMIT:

  main  DESIGN.md 'accurate about the situation'        -> 0
  main  recurring_failure_mode.dag diagnostic_name_...  -> 3

#9414 landed the authority row without regenerating the projection, so
main's committed DESIGN.md does not render a class its own authority
declares. Regenerating here renders it, which is the correct projection
rather than an edit by this branch.

So this repository currently has generated-artifact drift in BOTH
directions on one file: content in the projection that no authority
produces (repaired in the previous commit), and content in the authority
that the projection does not render (rendered here). Both are invisible to
anyone who does not diff a regeneration against the committed copy and
account for every changed line.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`stage0_partition_row_features` is real and live, so the citation did not
dangle -- but the call below the comment is `stage0_features_for_crate_kind`,
and a reader checking the comment against the code found the two disagreeing.
A citation naming a symbol the code no longer reaches, sitting in the comment
that explains a §3 single-authority repair, is the same class the repair was
about.

The comment now names what the call actually reaches and keeps the
partition-row wrapper in its true relation to it: the rows reach the same
authority THROUGH `stage0_partition_row_features`, which is why the two names
both belong in the sentence and why only one of them belongs in the call.

Found in review by smart-ram-730, who correctly judged it not worth a CI cycle
on its own; it is folded in here rather than pushed alone.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…omitted 16 declarations

review 56685 (REQUEST_CHANGES) is correct on both counts and the audit it
prompted found the problem was larger than the two items it named.

THE STALE CITATION. The roster carried `PROBE_PACKAGE_NAME`, which resolves
to nothing anywhere in the tree. An earlier revision of the host carried a
package-name CONSTANT; the cargo-fingerprint-aliasing repair replaced it
with the per-entry function `probe_package_name`, and the receipt was not
updated with the code.

THE OMISSIONS. Rather than patch the two the review named, the whole roster
was audited against the file. It carried 32 rows against 47 declarations:
1 stale and 16 unaccounted. Every one of the 16 was added by a LATER repair
inside this same PR -- `probe_root`, the selection digests,
`retain_not_selected_identities`, the `cargo_verdict_probe_line`
attribution fix, and two tests -- each of which grew the file without
growing its receipt.

That is precisely the drift this carrier exists to catch, committed inside
the carrier, and it made the PR's sole checkable receipt both inaccurate
and incomplete. The review's verdict is the right one.

The roster is now exact against the file: 47 rows, 47 declarations, zero
stale, zero unaccounted, zero duplicates, verified by re-running the audit
after the edit rather than by reading the diff.

A note records why it drifted, and states the standing hazard plainly: this
is a HAND ROSTER BESIDE ITS SUBJECT, so it can only be re-verified, never
trusted. It will drift again on the next declaration added and nothing in
the required run compares the two. Its dissolution is the v1-hand-queue-drain
lane this obligation already names.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@briansrls
briansrls marked this pull request as ready for review August 27, 2026 23:06

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 430266933f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

// A STALE TREE IS NOT A SUBJECT. The previous run's bytes under the same slug would let a
// module deleted from the closure keep compiling, so the directory is removed rather than
// written over.
let _ = std::fs::remove_dir_all(&dir);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Fail when the stale probe crate cannot be removed

When a previous probe directory exists and remove_dir_all fails but the subsequent directory creation and file writes succeed, stale Rust files remain in the crate. A stale file can satisfy a module declaration that the current emission failed to materialize, allowing Cargo to compile old bytes and falsely green the new emit-compile gate; propagate the removal error as CrateNotWritten before writing the new emission.

Useful? React with 👍 / 👎.

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