Skip to content

The shell-service refusal test reads the refusal out of emitted bytes — the class #9886 filed in the same commit that landed the test - #10049

Closed
gunbai-bot[bot] wants to merge 1 commit into
mainfrom
fix/shell-service-refusal-oracle
Closed

gunbai-bot[bot] wants to merge 1 commit into
mainfrom
fix/shell-service-refusal-oracle

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

compiler_tests::shell_service_unmodeled_output_key_refuses has failed on main since it landed. It is a stale test over a wall that is holding — the emitter is right and the oracle is wrong — and it is stale in the exact direction the commit that landed it forbade.

The wall holds; the oracle is pre-climb

The test's line 1045 is a precondition, not an assertion:

.expect("service module must emit src/probe.rs");

Neither refusal assertion after it ever executes. Running the compile and printing the result shows why:

files: []
diagnostics: [ ErrorNode { diagnostic: TransportEmissionNotModeled {
    transport_kind: "shell", service: "Probe", operation: "Version",
    declaring_module: "probe", target: "rust",
    missing_realization_fact: "shell transport output key 'not_a_channel' has no modeled
      channel -- the modeled channels are stdout, stderr, exit_success, success, exists,
      exit_code, stdout_lines, stderr_truncated, stderr_total_bytes and stderr_retained_bytes",
    span: SourceSpan { file: "probe.dag", start: 83, end: 88 } }, module_name: "probe" } ]

A typed, located, fail-closed refusal with zero emitted files — strictly better than what the test demands. The test's oracle reads the refusal out of the emitted Rust bytes (emitted.contains("has no modeled channel")), which requires the refusal to exist as text inside the emitted program.

That is precisely refusal_deferred_to_emitted_runtime — the recurring failure mode #9886 filed in the same commit that added this test. The class was climbed a rung (emit-text-mentioning-the-problem → compile-time typed refusal) and the pre-climb oracle was left enrolled. There are no emitted bytes left to read, so the precondition can never be satisfied. The proximate cause is visible in 05_emit.dag's bind_shell_operation, which cites review 58091: the convention was re-keyed from arity to authorship late in that PR, so output { first: String from "not_a_channel" } stopped binding stdout in silence and started refusing.

git log -S on the test name returns exactly one commit. It landed red and never passed.

The new oracle, and the anti-fallthrough arm STRENGTHENED

The oracle now reads the diagnostic. Three assertions replace two, and per DESIGN §4b(4) the evidence is re-expressed at the new rung, not retired:

before after
emitted.contains("not_a_channel") && emitted.contains("has no modeled channel") same two substrings, asserted on missing_realization_fact — the refusal must still name the key
— (transport_kind, service, operation) == ("shell", "Probe", "Version") — it must name what it refused
— span == ("probe.dag", 83, 88) — it must stay located, not merely typed
!emitted.contains("stdout.clone()") !r.files.iter().any(|f| f.path == "src/probe.rs")

That last row is a strengthening, not a relaxation, and it is the one worth reading twice. The old form asserted that one spelling of the stdout fallthrough was absent from the emitted text — satisfiable by an emission that spells the fallthrough differently, or by any text that happens not to contain that token. The new form asserts that nothing is emitted for the module at all. Emitting nothing entails not emitting a fallthrough; the converse does not hold. A reviewer seeing a textual assertion deleted from a .rs file should read it as the weaker claim being replaced by the stronger one.

Every file is PRODUCED — and which round produced which

file origin
src/v1/compiler_tests_rust.dag the authority — hand-edited, and the only hand-edited file here
src/v1/stage0/src/v1_compiler_compiler_tests_rust.rs round 1 output, installed from the regen candidate
src/v1/stage0/src/compiler_tests.rs round 2 output, installed from the regen candidate

Two rounds are structural, not ceremony. The emitted compiler_tests.rs is produced by the seed's own compiled-in compiler_tests_source (called from the emit site in v1_compiler_emit_rust), not by interpreting the .dag. So round 1 moves only the mirror of the authority; the seed must then be rebuilt before round 2 can emit the new test text. A .dag-only change would have left rust-unit-tests exactly as red while looking correct — specification-without-execution.

Why round 2 used a full cargo build, and why that is sound

--regen-round-cost refused:

StageSeedBuildRefused: no partitioned build was attempted and no full-build fallback ran
-- partition-rebuild: RebuildScopeRefused MirrorHasNoOwningPackage
   mirror=v1_compiler_compiler_tests_rust.rs

Round 2 was completed with a plain cargo build --release -p v1-compiler instead.

This is not defeating the refusal. --regen-round-cost is a cost-measuring instrument, and what refused is its partitioned-rebuild optimization, which must know the minimal set of crates to rebuild and cannot scope this mirror. Name the hazard the refusal guards: MirrorHasNoOwningPackage prevents under-building — rebuilding too narrow a scope, so the seed does not actually contain the change. A full build cannot under-build. The hazard is structurally unreachable on the path taken, which is what distinguishes this from routing around a wall.

Declining an optimization whose precondition does not hold is not the same as defeating the wall that says so.

The obligation the full build creates, discharged

Because the scope-verifying instrument was not used, the seed must be shown by execution to carry the change rather than assumed to. Round 2's emitted compiler_tests.rs differs from the committed one exactly as the authority edit specifies — the byte-reading oracle removed, the diagnostic-reading oracle in its place. A round 2 that silently re-emitted the old text would have looked identical to success, so this diff is the check that it did not.

Finding, not fixed: a second live instance of the unowned-mirror hole

v1_compiler_compiler_tests_rust.rs is a second live instance of MirrorHasNoOwningPackage. stage0_partition_rebuild_scope_witness_test's witness_unowned_mirror_refuses_holds currently cites only cli_run.rs, and its own comment calls that "the live shape of the coverage hole, not an invented name."

Two instances is materially different evidence from one: it makes the hole a pattern rather than an anecdote, and it says the class is not confined to hand-authored host modules — this mirror is generated, and still owned by no partition row. Deliberately not fixed here: stage0_crate_partition_generated.dag carries its own header saying it is generated from v2.workflow.rust_crate_partition and must not be hand-edited, so closing the hole is a change to the crate-partition authority plus a regen, which wants its owner.

Also observed: a correct wall with an undocumented remedy

--regen-round-cost refuses when run from target/release/:

the seed build replaced the running executable (0594fb1acd2068e1 → 7b72dede5f2113fd), so an emit from this process would measure a seed the build did not produce

Correct and well-named. The remedy — run it from a copy outside the target directory — is written nowhere, so a compliant reader hits a refusal that names the hazard precisely and offers no way forward. Recorded here because it cost a cycle to rediscover.

Where this was executed, and why locally

HostBudgetUnreadable from entry_resolve makes the floor and the regen unrunnable on BuildBuddy: no cgroup memory.high/memory.max binds the process, and GUNBC_MEMORY_BUDGET_BYTES may only lower a ceiling, never supply one, so there is no env workaround by construction.

This session's container satisfies the arm — memory.max = 33578549248 (31.27 GiB) binds it — so the regen ran here. That is not bypassing the refusal; it is running where its precondition holds.

🤖 Generated with Claude Code

https://claude.ai/code/session_01EN2pmV7GbBZYhCZWYqFbCc

… — the class its own commit filed as forbidden

compiler_tests::shell_service_unmodeled_output_key_refuses has failed on main since it
landed. `git log -S` on the test name returns exactly one commit (#9886): it landed red
and never passed.

THE WALL IS HOLDING AND THE ORACLE IS STALE. The compile refuses correctly -- files: []
and one typed, located TransportEmissionNotModeled naming the key and spanning
probe.dag 83..88. The test's `.expect("service module must emit src/probe.rs")` is a
PRECONDITION, so neither refusal assertion ever ran. Its oracle requires the refusal to
exist as TEXT INSIDE THE EMITTED PROGRAM, which is exactly
refusal_deferred_to_emitted_runtime -- the recurring failure mode #9886 filed in the same
commit. The class climbed a rung and its pre-climb oracle stayed enrolled; DESIGN 4b(4)
says the evidence is re-expressed at the new rung, not retired.

THE ANTI-FALLTHROUGH ARM IS STRENGTHENED, NOT RELAXED. `!emitted.contains("stdout.clone()")`
asserted that one SPELLING of the fallthrough was absent from the emitted text. It is now
`no src/probe.rs is emitted at all`. Emitting nothing entails not emitting a fallthrough;
the converse does not hold. The span and the (transport, service, operation) triple are
newly asserted so the refusal stays LOCATED and named, not merely typed.

EVERY FILE IS PRODUCED. compiler_tests_rust.dag is the authority and the only hand-edited
file. v1_compiler_compiler_tests_rust.rs is round-1 regen output; compiler_tests.rs is
round-2 output. Two rounds are structural: the emitted compiler_tests.rs comes from the
SEED's compiled-in compiler_tests_source, so the seed must be rebuilt between rounds. A
.dag-only change would have left rust-unit-tests exactly as red while looking correct.

ROUND 2 USED A FULL cargo build BECAUSE --regen-round-cost REFUSED, AND THAT IS SOUND.
RebuildScopeRefused MirrorHasNoOwningPackage names v1_compiler_compiler_tests_rust.rs. The
refusal guards its PARTITIONED-REBUILD optimization against UNDER-building. A full build
cannot under-build, so the hazard is structurally unreachable on the path taken -- this
declines an optimization whose precondition does not hold rather than defeating a wall.

Because the scope-verifying instrument was not used, the seed is SHOWN to carry the change
rather than assumed to: round 2's emitted compiler_tests.rs differs from the committed one
exactly as the authority edit specifies.

EXECUTED, not asserted. The test passes; its sibling
render_rust_applied_type_routes_qualified_base_through_leaf_name still passes; and the
discriminating RED is established by mutation -- restoring the pre-#9886 silent bind
(shell_field_authors_from_key answering false) makes the new oracle fail with
"Got diagnostics: []", so it is not green for an incidental reason.

FILED, NOT FIXED: v1_compiler_compiler_tests_rust.rs is a SECOND live instance of
MirrorHasNoOwningPackage. stage0_partition_rebuild_scope_witness_test cites only
cli_run.rs today. The second instance is generated where the first is hand-authored, so
the hole is not confined to hand-written host modules. Closing it means changing the
crate-partition authority, which declares itself generated and not hand-editable.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EN2pmV7GbBZYhCZWYqFbCc
@gunbai-bot

gunbai-bot Bot commented Sep 2, 2026

Copy link
Copy Markdown
Contributor Author

Closing: superseded by #10025, which landed the same repair while this was in regen.

#10025 reached the same diagnosis independently — the oracle read the refusal out of emitted bytes, the emitter was right — and its rust-unit-tests passed (22m45s). The red this PR existed to close is already closed on main, so re-landing a conflicting version of the same test would be creating a second authority for one fact rather than fixing anything.

What main's version does not carry, stated so it is not lost rather than as an argument to merge this:

  • span == ("probe.dag", 83, 88) — main asserts the refusal is typed, not that it is located. DESIGN §4b treats those as different rungs.
  • (transport_kind, service, operation) == ("shell", "Probe", "Version") — that the refusal names what it refused.

Both are small additive assertions on a test that is now green. Whether they are worth a regen round and a review is a judgment call for the roster's owner, not something to smuggle in on a superseded branch.

One finding here does not depend on this PR and should outlive it: v1_compiler_compiler_tests_rust.rs is a second live instance of MirrorHasNoOwningPackage, and it sits on the opposite side of the hand-maintained partition from the first. Verified in bootstrap_stage0_crate_layout_generated.rs: cli_run.rs is in HAND_MAINTAINED_STAGE0_FILES; v1_compiler_compiler_tests_rust.rs is not, which by the regen's own rule means it is emitted rather than copied.

That distinction changes the claim. One instance on a hand-authored file is consistent with the roster not having caught up with hand-written host modules — a bookkeeping gap. An instance on a generated mirror says the crate-partition authority does not cover files the regen itself produces: the hole is in the partition's coverage of its own output. Two points support that because they differ on exactly the axis in question. stage0_partition_rebuild_scope_witness_test cites only cli_run.rs today.

Not fixed here or anywhere — stage0_crate_partition_generated.dag declares itself generated from v2.workflow.rust_crate_partition and not hand-editable, so it wants its owner.

— sent from smart-crane-230

@gunbai-bot gunbai-bot Bot closed this Sep 2, 2026
@gunbai-bot
gunbai-bot Bot deleted the fix/shell-service-refusal-oracle branch September 2, 2026 10:13
@briansrls
briansrls restored the fix/shell-service-refusal-oracle branch September 2, 2026 10:50
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