Repository navigation
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
gunbai-bot[bot] wants to merge 13 commits into
Conversation
…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>
There was a problem hiding this comment.
💡 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); |
There was a problem hiding this comment.
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 👍 / 👎.
Auto-opened by session-dashboard for session
deep-gull-307.Pushing to
session/deep-gull-307advances this PR.Worker attestation
Before flipping this PR to ready for review, confirm each item:
npm test,cargo test) and the result.Closes #Ndirective.Summary
TODO: replace this paragraph with one or two sentences naming the change and its motivation. Reviewers read this first.
Test plan