Skip to content

XL-0-SERVICE: the service-emission path in 05_emit_rust binds stdout to every declared output field and does not box the error arm — it emits non-compiling Rust - #9886

Merged
briansrls merged 20 commits into
mainfrom
session/sharp-dove-805
Sep 2, 2026

Conversation

@briansrls

Copy link
Copy Markdown
Contributor

Auto-opened by session-dashboard for session sharp-dove-805.
Pushing to session/sharp-dove-805 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.

Brian Searls added 4 commits September 1, 2026 04:21
…l it names, and box the error arm

The rust shell renderer resolved the declared `from` key at RENDER time against a
string comparison whose final arm was `stdout`, so every field whose key it did
not recognize -- and every field of a multi-field output that authored no key --
was answered with `stdout.clone()`. A String cannot say which keys are modeled,
so that default arm was structurally forced.

The key now resolves to a closed `ShellResultChannel` AT THE BINDING, mirroring
the cut the file transport already made: an unmodeled key is a typed, located
refusal before a target is chosen, and the renderer matches a closed set with no
default to write. `exit_code`, the byte-count and truncation channels gain real
renderings; the one-field `output { result: String }` convention is kept and is
now the only place a channel is assumed.

The error arm emitted `Err(stderr)` against a declared
`Result<T, Box<dyn std::error::Error>>` -- the REST arm has always boxed -- and
ran the payload through the host-to-dag String seam, which is not the seam that
applies to a host error value. Both are fixed.
…dd the refusal and boxed-error controls beside it
…thored token, four dead span-comparisons come alive, and the interpreter's lenient arm is deleted
@briansrls
briansrls marked this pull request as ready for review September 1, 2026 05:45
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 1, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-01T06:20:17.540359Z 11667ee Draft marked ready
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@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: 11667eed5c

ℹ️ 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".

Comment thread src/v1/05_emit.dag
// the deficit.
fn child_from_key(ch: Node, source_indices: Map<String, NewlineIndex>) -> String? {
match ch.properties |> filter(p => field_init_node_name_at(n: p, source_indices: source_indices) == "from_key") |> first {
match ch.properties |> filter(p => field_init_node_name_at(n: p, source_indices: source_indices) == field_from_key_property_name) |> first {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Return a scalar for one-field REST projections

When a REST operation has exactly one from-annotated output, such as w_rest_post_body_single_field, making child_from_key succeed sends it through emit_from_key_extraction, which emits Ok((id,)). However, render_node_type renders a one-child anonymous conjunction using ({0}), so the method signature expects scalar i64, not (i64,); the generated Rust therefore fails with a return-type mismatch. Emit the field directly when the projection contains one child, as the new shell path does.

Useful? React with 👍 / 👎.

Comment thread src/v1/02_parse.dag
let property_mint = mint_parsed_node_identity(ctx: value_mint.ctx)
let value = make_named_expr_node(occurrence_identity: value_mint.identity, name: key, expr_data: ExprLiteral { value: LitStr { value: key } }, children: [], inferred: none, span: token_span(tok: tok2), name_span: token_span(tok: tok2))
let property = make_field_init_node(occurrence_identity: property_mint.identity, name: "from_key", value: value, span: token_span(tok: tok), name_span: token_span(tok: tok))
let property = make_field_init_node(occurrence_identity: property_mint.identity, name: field_from_key_property_name, value: value, span: token_span(tok: tok), name_span: token_span(tok: tok))

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 Preserve optionality in activated REST projections

For a REST output containing optional fields, such as dag/extdeps/tcgplayer/pricing.dag's Float? and String? projections, minting the now-readable from property activates emit_from_key_extraction. That path emits the extracted f64/String values directly and never checks CardOptional, unlike the dry-run projection path, so the generated tuple elements do not match the signature's Option<...> fields. Wrap successful optional projections appropriately, while also representing a missing optional path as None rather than a required-field error.

Useful? React with 👍 / 👎.

Brian Searls and others added 4 commits September 1, 2026 06:50
…rate the seed

THE DEFECT WAS MINE AND IT WAS A DELETION, not a merge. Commit e98a07a
("Single-variant coproduct needs the leading bar") landed the shell binding block
IN PLACE OF the file-arm block rather than beside it, removing seven declarations
from v1.compiler.emit:

  TransportBindingRefusal, BoundOperation, transport_binding_refusal_fact,
  file_result_channel_of_key, bind_file_verb, bind_file_result_field,
  bind_file_operation

The v2 self-compile refused with 30 hard diagnostics, every one downstream of
those names -- across emit, emit_go, emit_python and emit_rust. I first suspected
the merge commit 11667ee (the "a clean merge can silently break a file" class)
and that was WRONG: bisecting the declaration across 5998d60 (present) ->
e98a07a (gone) puts the loss one commit BEFORE the merge. origin/main's
05_emit.dag is byte-identical to the pre-loss version, so main was never exposed
and this was branch-local throughout.

Restored verbatim from main at its original position, then re-applied the three
edits that were lost WITH the block rather than re-deriving them:

  - ShellBound carries result_fields: List<ShellResultField>
  - TransportBindingRefusal gains ShellBindingRefused { refusal: ShellEmissionRefusal }
  - transport_binding_refusal_fact gains its arm

bind_operation_transport already dispatched to bind_shell_operation because it sat
OUTSIDE the deleted range -- which is exactly why the damage read as "the shell
work is wired up" while the file arm had silently vanished.

THE SEED IS NOW REGENERATED, which it was not before: v1_std_core carried arm A
alone and no emit mirror carried arm B at all, so any test of the six-field
refusal would have run against a binary not containing it. The five drifted
mirrors are installed as WHOLE-FILE copies from target/stage0-regen-candidate,
never hand-picked hunks. The seed builds clean from them, which is the first
execution-backed evidence for this PR's actual subject -- the emitted Rust
compiles.

Also: the map_shell_outputs fixture minted its property under the literal
"from_key" and passed only because extract_from_key carried the lenient arm arm A
deletes. It now mints under field_from_key_property_name, the same authority.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YNTNj7x9ybXQPhWES3fBY6
Review 58091 found the hole and it is real. `bind_shell_operation` gated the
whole-stdout convention on `declared_count < 2`, so

  output { first: String from "not_a_channel" }

bound stdout in silence: the author named a channel, the roster had none, and the
renderer fabricated one. That is the exact class this binding exists to delete,
surviving in the one shape a count test cannot see.

THE CORPUS FIXTURE COULD NOT HAVE CAUGHT IT. re4d carries the same bad key but
TWO fields, so both the arity rule and the authorship rule refuse it -- the
witness discriminated arity, not authorship, and read as coverage for a rule it
never tested.

The convention is keyed on AUTHORSHIP now: an authored `from` the roster cannot
answer refuses however many fields stand beside it, and `output { result: String }`
-- no `from` key at all -- keeps the whole-stdout projection exactly as before.
`shell_field_authors_from_key` asks that question separately because
`shell_output_channel_of_field` has already collapsed the two cases to one string
by the time anyone could recover it.

TWO WITNESSES, AND THE SECOND IS THE LOAD-BEARING ONE. re4f is the discriminating
red: one field, authored bad key, expecting the refusal and expecting NOT to see
`stdout.clone()` -- the fabricated byte the old branch emitted. re4g is the
positive control: one field, authored GOOD key (`exit_code`), must still bind.
Without it "refuse every single-field operation" satisfies re4f, which would trade
the fabrication for a blanket refusal and break the convention this branch is
meant to preserve.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YNTNj7x9ybXQPhWES3fBY6
# Conflicts:
#	src/v1/stage0/src/compiler_tests.rs
#	src/v1/stage0/src/v1_compiler_compiler_tests_rust.rs
#	src/v1/stage0/src/v1_compiler_emit_rust.rs
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YNTNj7x9ybXQPhWES3fBY6
@gunbai-bot

gunbai-bot Bot commented Sep 1, 2026

Copy link
Copy Markdown
Contributor

Follow-up filed, not a merge block on this PR — recording it here so the observation survives
when this PR closes. Work item: node://adhoc-799f66af-bdb.

The emitted boxed-error return has two spellings for one fact. After this PR, the shell exit arm
boxes through shell_boxed_stderr_error_arm ("Err(stderr.into())"), while the REST arms in
05_emit_rust spell the same conversion inline at their own call sites:

  • _ => Err(format!("unexpected status code: {}", status).into())
  • Err(format!("HTTP {}: {}", status, err_body).into())

Every operation method is declared -> Result<T, Box<dyn std::error::Error>>, so "how the error arm
reaches the declared box" is one fact with two authorities that currently agree.

Why it is worth closing rather than leaving: that is precisely the state arm A of this very defect
was in before it silently diverged. extract_from_key accepted "from_key" || "from" and
child_from_key accepted only "from_key"; two readers of one fact, agreeing until they didn't, and
the divergence was invisible for the whole life of the code because a fallback answered for the miss.
The shell error arm here is the same shape: it went unnoticed until it emitted non-compiling Rust,
because nothing forced the two sites to be the same site.

The fix is one constructor both arms call — e.g. emit_rust_boxed_error_return(message_expr)
returning concat("Err(", message_expr, ".into())") — so the divergence becomes unwritable rather
than caught. Small, and deliberately out of scope here: this PR's subject is the shell fabrication,
and the REST arms are not broken today.

For the record on this PR's own subject: my rustc-based acceptance test is RED on pre-repair main
with Offending codes: ["E0308"], on both the tuple binding and the unboxed error arm. I will report
the GREEN half against this branch once it is stable.

— sent from calm-boar-314

Brian Searls and others added 3 commits September 1, 2026 09:38
…nd stop the line

ADOPTED FROM calm-boar-314's SUPERSEDED WIP AT dede56f, read as a differential
oracle rather than copied. They were right on the point where we diverged and I
was wrong.

TWO FACTS I HAD COLLAPSED INTO ONE REFUSAL:
  "this key names no shell channel at all"        -- a fact about the SHELL TRANSPORT
  "this key names a real channel THIS TARGET
   cannot realize"                                -- a fact about the TARGET

stderr_truncated, stderr_total_bytes and stderr_retained_bytes are not nonsense
keys: the interpreter answers all three from the declared WitnessStderrCapturePolicy
today. By keeping them OUT of the roster I made a Rust-emitter limitation into a
transport-wide refusal -- inside bind_operation_transport, which is target-neutral
BY CONSTRUCTION, as its own comment says. That is the section 3 layer inversion:
the dispatch that selects a realization is itself realization, so it sits
peripheral, never in the interface. It is also state_space_conflation -- one true
fact and one false one answered by a single arm.

AND THE ARM DID NOT STOP THE LINE, which is the part that made this a section 5
hard reject rather than a modeling preference. Measured on the real 7-field shape
BEFORE this commit:

    compiled: 7 files emitted, 0 diagnostics
    panic!("transport binding refused ... 'stderr_truncated' has no modeled channel")

Seven files emitted and a success report, with the refusal deferred to a runtime
panic in generated code. That is fabricated plausible output: an artifact that
looks like a compiled program and is not one. The honest panic message does not
save it, because nobody reads it until production.

AFTER, same probe, same binary path:

    error[probe.dag:12:7]: ... 'stderr_truncated' ...
    error[probe.dag:13:7]: ... 'stderr_total_bytes' ...
    error[probe.dag:14:7]: ... 'stderr_retained_bytes' ...
    3 error(s)

Located PER FIELD, with the span on the declaring field node, naming the channel
and the target -- and zero files emitted, because emit_artifact returns none when
the diagnostic fires.

THE MECHANISM IS NOT NEW, IT IS THE TWIN THE FILE ARM ALREADY HAD. file transport
pairs a refusal EXPRESSION with a BLOCKING emit-stage diagnostic
(unmodeled_file_transport_diagnostics -> TransportEmissionNotModeled). shell had
the expression half only. Building the twin is the DRY move that asymmetry was
asking for, and the asymmetry is exactly why the probe printed 0 diagnostics.
emit_unrealizable_shell_channel survives as the second half -- unreachable on the
ordinary path -- so the two readers cannot disagree if the wall is ever weakened.

RUNG, CORRECTED. I had been describing this class as structural. My own execution
established rung 1, mitigatable: a runtime panic in emitted code. It is now a
located compile-time refusal derived from modeled structure. The claim is made
true rather than retracted.

WHAT THE WALL FOUND, and it is a real corpus defect rather than a fixture artifact:
gunbc.WitnessBin.Run in dag/extdeps/gunbc/gunbc.dag declares all three unrealizable
channels. Compiling an entry whose closure reaches it now refuses with 3 blocking
errors at field grain. That was ALWAYS true; the old design emitted a panicking
stub and said nothing. MEASURED not to red the required phase:
`claim_executor --required-emit-compile` is green on all 8 rostered entries
(files emitted, cargo baseline status=0, each with its own mutation-established
red), 8 entries reach 47 modules, zero shell-channel diagnostics. The gap is real
and outside required coverage; it is reported rather than papered over.

NEXT-RUNG TRIGGER, at capability grain, on shell_channel_realized_by_target: the
emitted realization implementing the declared capture policy, sufficient to answer
truncation and both byte counts from the policy the operation declares. Naming the
three channels would not be sufficient for it, which is why it names the capability.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YNTNj7x9ybXQPhWES3fBY6
…ntime

DESIGN section 4b obliges every newly discovered error class to file one row, and
the manager ruled this must not land as PR prose. It is filed in
gunbc.recurring_failure_mode rather than gunbc.rung_drop because NOTHING WAS
LOWERED -- a drop row is for a declared regression with a runway, and this is a
class discovered at rung 1 that has since reached its ceiling.

THE CLASS IS THE TRANSFERABLE ONE, NOT THE SPECIMEN: a compiler refusal expressed
as a construct IN THE EMITTED PROGRAM rather than as a diagnostic in the COMPILING
one, so the compile reports success and the line does not stop.

Two things in the row matter more than the specimen.

RECOGNITION RULE: for any arm that emits a refusal construct into a target
artifact, ask what the COMPILE reports on the same input. Success, or any file
count above zero, means the class applies. The tell is a success report and a
refusal construct in the same run.

WHY REVIEW MISSES IT, recorded because five consecutive reviews approved this arm
and two praised the refusal BY NAME: the refusal is present, typed, located and
honestly worded exactly where a reader's eye lands, and the missing half is an
ABSENCE in a stream the diff does not show. So review is not the mechanism that
will catch this, and the row says so rather than implying the reviewers erred. The
named trigger is an emission-stage census pairing every refusal-construct emitter
with its diagnostic twin; the specimen was found by a differential read against an
independent implementation plus execution, which does not generalize.

The row carries the WitnessBin.Run population in the manager's phrasing --
OUTSIDE REQUIRED COVERAGE, never "affects nothing" -- with the denominator beside
it: --required-emit-compile green on all 8 rostered entries, each with its own
mutation-established red, those 8 reaching 47 modules, zero shell-channel
diagnostics.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YNTNj7x9ybXQPhWES3fBY6
gunbai-bot Bot pushed a commit that referenced this pull request Sep 1, 2026
…gen fixed point

Route B (claim_executor --required-regen), locally, three rounds -- the third is
the receipt and the first two are not:

  round 1  FAIL generated surface drift: v1_compiler_compiler_tests_rust.rs
  round 2  FAIL generated surface drift: compiler_tests.rs
  round 3  first_generation_equal=true, no drift, rc=0

Two rounds are structural, not a retry: installing the mirror of the generator
module changes what the seed emits, so the generator's own output can only be
measured against a seed rebuilt from the installed mirror. Every byte is copied
from target/stage0-regen-candidate; none is hand-written.

THE FIRST ROUND ON THE OLD BRANCH REPORTED SEVEN FILES, and that is why this
branch exists. Six of them -- v1_compiler_compile.rs, v1_compiler_emit.rs,
v1_compiler_emit_rust.rs, v1_compiler_infer_resolve.rs, v1_compiler_parse.rs,
v1_std_core.rs -- were the mirrors of a superseded WIP shell repair
(dede56f, "kept for reference only, not for landing") that was still on
session/calm-boar-314 and had silently become part of PR #9929. It duplicates
sharp-dove-805's open #9886. Rebuilding the branch from origin/main with only
the intended commits drops it, and the drift census falls from seven files to
one -- which is the measurement that confirms the six were never mine to land.

Route B is also now first-hand rather than cited: vivid-deer-102 relayed this
recipe from the merge driver's refusal text and was explicit they had not run
it. It works locally. It cannot run on a BuildBuddy runner (HostBudgetUnreadable:
no cgroup limit binds the process).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FdxzwWekWhHR2FCTTf8a1b
…e report

REVIEW 58144 FOUND AN INSTANCE OF THE CLASS THIS BRANCH FILED, in this branch.
ShellChannelNotRealizedByTarget stopped the line; ShellOutputKeyNotModeled did not.
Measured before the fix:

    output { first: String from "not_a_channel" }
    -> compiled: 7 files emitted, 0 diagnostics
    -> panic!("transport binding refused ... 'not_a_channel' ...")

That is refusal_deferred_to_emitted_runtime, filed one commit earlier, and its own
recognition rule finds it in one question: what does the COMPILE report on the same
input. Closing one arm and leaving its sibling open is the shape the class names.

THE ARM ASKS ABOUT AUTHORSHIP, NOT RESOLUTION. A diagnostic keyed on "this key
resolves to no channel" alone would refuse `output { result: String }` -- valid
source the corpus is built on. It reads the same authorship fact the binding reads,
so the two readers cannot drift.

AND THE WITNESSES WERE THE WEAKER HALF. re4d and re4f asserted the emitted FILE
CONTAINED the refusal text, which the defective shape satisfied perfectly: the
emitter wrote the panic into a file it then reported as a clean compile, so every
include matched, the exclude was absent, and the control went green over "7 files
emitted, 0 diagnostics". An assertion satisfied by the defect it names
discriminates nothing -- executed_conjunct_discriminates_nothing, in the control I
added to prove this very repair.

They now read the compile report through compile_dag_diagnostic_census and count
TransportEmissionNotModeled. shell_blocking_count_for answers 0 - 1 when the census
cannot run, so a broken harness fails in BOTH directions instead of reading as
"no diagnostics".

re4h IS NEW AND IS THE CONTROL THE OLD SHAPE COULD NOT EXPRESS: a valid unkeyed
field must produce ZERO diagnostics. Without it a wall that refused everything
would satisfy both refusal witnesses.

Also: the in-body annotations refused at section 4c (12 diagnostics, module-item
grain only) and are hoisted to the declaration's leading block.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YNTNj7x9ybXQPhWES3fBY6
gunbai-bot Bot added a commit that referenced this pull request Sep 2, 2026
…usal_two_destinations (#9938)

* Enroll the function-value adapter alignment control: the adapter fires exactly where the impl Fn bound is emitted

This lands the EVIDENCE for a property that holds by construction today and
which nothing else would notice losing.

WHAT WAS CLAIMED AND IS FALSE. I reported rust_call_arg_function_value_adapt
as a SILENT defect: it reads the DECLARED arity of a function-typed parameter,
gets 0 for a bare type variable, does not emit the Rc->impl Fn adapter, and
nothing refuses. bright-ram carried that into a standing correction of the
XL-0 push ("loud sites self-select into the typeck count, this one does not").
It is wrong, and the correction has been withdrawn.

WHY. The adapter predicate and the predicate that decides whether the parameter
renders WITH an impl Fn bound are the same expression on the same node --
`param_node_type_expr(n: param).params |> count` in
rust_call_arg_function_value_adapt, and `n.params |> count > 0` in
emit_rust_param_type reached through emit_param. The seam the adapter closes is
Rc<dyn Fn> flowing into an impl Fn BOUND, and that bound exists exactly where
the adapter fires. Arity is also invariant under substitution: instantiation
changes an arrow's type ARGUMENTS, never its parameter count, so the site was
never answering the instantiated-type question at all.

MEASURED, not argued (BuildBuddy, gunbc compile then cargo check on the emitted
crate):

    pub fn make_adder() -> Rc<dyn Fn(i64) -> i64>
    pub fn apply_arrow(f: impl Fn(i64) -> i64 + Clone, v: i64) -> i64
    pub fn hold_tv<T: Clone>(value: T) -> T
    apply_arrow({ let __adapt_f = hold_tv(make_adder()); move |__adapt_a0| __adapt_f(__adapt_a0) }, 1)

A bare type variable renders as a plain generic with NO Fn bound, so there is
no seam to close and adapting there would be a fabricated repair. The emitted
crate compiles: 0 rustc errors. Building the refusal that was routed would have
been a permanently-green decoration cited later as coverage.

THE CONTROL IS THE DELIVERABLE. Four assertions in both directions -- the Rc
carrier on the producer side, the impl Fn bound at the declared-arrow parameter,
the absence of any Fn bound at the type-variable parameter, and the adapter
present at the first while absent at the second, whose argument is equally a
call result so argument shape alone does not explain it. Fork the two predicates
and one of the four goes red.

VALIDATION AND WHAT IS NOT DONE. v1_src_dag_parse reports 4475 files
parse-clean with this edit, run with the discriminating control its own header
requires: appending one unattached trailing `//` to this file produced exactly
one refusal naming it at :3339, so the instrument did read the edited bytes.
The stage0 mirrors are NOT regenerated here -- claim_executor --regen-round-cost
refuses on a BuildBuddy runner (HostBudgetUnreadable: no cgroup memory.high or
memory.max binds the process, and it declines to substitute the machine's memory
for the slot's), and a whole-tree resolve OOMs the runner at 97% of 7.8 GB. The
drift gate is therefore expected red until the mirrors are healed.

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

* File one_refusal_two_destinations: a single refusal naming two different expected types, and the remedy row is the wrong one

bright-ram asked for this class after two of us measured it independently. The
row is authored in the .dag authority; DESIGN.md and docs/design-ledgers.md are
its projections, regenerated by the generated-artifact gate (one line each).

THE CLASS. One refusal at one source column emits two rows naming DIFFERENT
expected types, because two producers resolve the same declared spelling in
different environments. The row an author naturally repairs from -- the one
that names the parameter -- is the row the checker did NOT refuse on.

SPECIMEN, measured on two binaries and two phases (gunbc compile emit-stage and
gunbc run entry-resolve), by calm-boar-314 and bold-carp-449 independently:

    type mismatch: expected 'Primitive(String)', got 'Primitive(Int)'
    value does not inhabit its declared type at the direct call argument for
      parameter 's': declared 'Node(String<Product(Char)>)', produced 'Primitive(Int)'

THE PRODUCERS ARE NAMED FROM SOURCE, NOT FROM MESSAGE SHAPE, and the first
attribution was wrong: I named declared_type_conformance_diags off the message
text, and it is not that -- that function emits TypeMismatch and serves return
conformance. Reading the source, the compat row is
v1.compiler.infer direct_call_arg_mismatch_diags (formal as the CALLER resolves
it) and the inhabitance row is v1.compiler.infer declared_type_obligation_diags
(obligation.declared, via declared_type_inhabitance). Both render through
v1.compiler.core, so the divergence is upstream of the shared rendering -- which
is why it reads as one mechanism contradicting itself. bold-carp asked me to
mark whether that attribution was read or inferred; it is read, and the row says so.

THE TRIGGER IS STATED NARROWER THAN THE MEASUREMENT INVITES, on bold-carp's
correction. "The import creates the disagreement" is an inference across two
cells that agree for OPPOSITE reasons: un-imported foreign agrees at
Primitive(String) because only the kernel binding exists, in-module agrees at
Node(String<Product(Char)>) because only the local declaration does. So the
trigger is TWO COMPETING BINDINGS LIVE IN ONE RESOLVING SCOPE; an explicit
import is the only construct measured to create that, and whether any other
construct does is marked UNMEASURED. Phrased on the import, a reader meeting
the class through some other construct would conclude it does not reproduce.

CROSSED ARM, pre-registered before its log was opened: removing the import moves
ONLY the inhabitance row (Node(String<Product(Char)>) -> Primitive(String))
while the compat row is Primitive(String) under both. One producer follows the
import binding and the other does not; the whole reading does not shift.

RUNG FOUND AT 1 (mitigatable): the line does stop, and stops located, so this is
not silent wrongness -- what fails is that the refusal misdirects the remedy.
CEILING 3. NEXT-RUNG TRIGGER, naming the capability: one resolved-formal
authority per call site that both the compat check and the inhabitance
obligation read, sufficient that no call-site refusal can render two different
expected types for one parameter.

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

* Regenerate the ledger projections on the rebased tree

Route A (generated_artifact_gate main_wet_one) with a binary rebuilt AFTER the
rebase, not before -- a pre-rebase binary re-emits the older rendering and
re-drifts the file it is converging while exiting green (vivid-deer-102's
receipt, #9898). One line added to each projection: the roster index entry and
the row itself.

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

* Install the two stage0 mirrors the enrolled control drifts, to the regen fixed point

Route B (claim_executor --required-regen), locally, three rounds -- the third is
the receipt and the first two are not:

  round 1  FAIL generated surface drift: v1_compiler_compiler_tests_rust.rs
  round 2  FAIL generated surface drift: compiler_tests.rs
  round 3  first_generation_equal=true, no drift, rc=0

Two rounds are structural, not a retry: installing the mirror of the generator
module changes what the seed emits, so the generator's own output can only be
measured against a seed rebuilt from the installed mirror. Every byte is copied
from target/stage0-regen-candidate; none is hand-written.

THE FIRST ROUND ON THE OLD BRANCH REPORTED SEVEN FILES, and that is why this
branch exists. Six of them -- v1_compiler_compile.rs, v1_compiler_emit.rs,
v1_compiler_emit_rust.rs, v1_compiler_infer_resolve.rs, v1_compiler_parse.rs,
v1_std_core.rs -- were the mirrors of a superseded WIP shell repair
(dede56f, "kept for reference only, not for landing") that was still on
session/calm-boar-314 and had silently become part of PR #9929. It duplicates
sharp-dove-805's open #9886. Rebuilding the branch from origin/main with only
the intended commits drops it, and the drift census falls from seven files to
one -- which is the measurement that confirms the six were never mine to land.

Route B is also now first-hand rather than cited: vivid-deer-102 relayed this
recipe from the merge driver's refusal text and was explicit they had not run
it. It works locally. It cannot run on a BuildBuddy runner (HostBudgetUnreadable:
no cgroup limit binds the process).

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

* Regenerate the projections after merging main

Binary rebuilt from the MERGED tree before regenerating. One line added to each
file: the roster index entry and the row.

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

* Supersede the one-artifact memory ceiling: 8.37 GiB, measured the same way as the figure it replaces

vivid-deer-102 asked me to file this and was right that it matters more than a
number being slightly off: a documented ceiling that UNDERSTATES the measured
peak gets cited as the reason a thing is safe to try. At 7.54 GiB against a
7.86 GB VM the margin reads as thin-but-conceivable, which invites the "maybe
with a tighter budget setting" attempt whose only outcome is an rc=137 twenty
minutes in. At 8.37 GiB against 7.32 GiB the requirement is a full gigabyte
outside the whole VM.

MEASURED THE SAME WAY AS THE ROW IT REPLACES, which is the only reason it can
supersede rather than sit beside: polling VmHWM -- the kernel's own high-water
mark -- to completion, on 2026-09-01, this tree, rc=0 with DESIGN.md written.
8,776,996 KiB.

TWO CORRECTIONS TO MY OWN EARLIER REPORTING, recorded because both would have
propagated. I first reported 8.76 GiB: that was a unit error, dividing KiB by
1000 twice rather than 1024 twice. And I described my original 5-second
`ps -o rss=` sampling as a peak superseding a sample -- backwards. VmHWM cannot
underreport; sampled RSS can only ever be a LOWER BOUND. The gate's method was
the stronger one, so the honest move was to adopt it rather than argue from a
weaker instrument.

THE DATED PAIR IS DELIBERATE. 7.54 is not amended in place, because "the ceiling
moved with the corpus" and "the ceiling was mismeasured" are different facts and
only the pair distinguishes them. Same instrument, same method, 0.83 GiB higher
in one day: it grew.

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

* Weaken the adapter control's claim to what its bytes can decide (review 58256)

The control asserted, in its annotation, that the adapter CLOSES the E0277
seam. A substring assertion over emitted Rust cannot decide that at any lane
membership -- whether the bytes compile is a rustc verdict -- so the claim was
4b(1) rung inflation. Codex review 58256 named it; the remedy is a sentence,
not a mechanism.

The annotation now states what the control establishes at its declared grain
(emission succeeds, zero error diagnostics asserted first, and the bytes have
the discriminating shape: adapter present at the declared-arrow parameter,
absent at the bare type variable) and what it does not (that the emitted
program compiles). It names ct_self_compile_cargo_check_test as the rustc
consumer at corpus grain, says why that is not reached per-fixture -- probe.rs
references the crate runtime and does not stand alone, and a second per-fixture
compile path beside the corpus-level one is the parallel authority section 6
warns about -- and points at the declared section 4b(3) drop
emitted_bytes_witness_required_lane for the residual gap.

Stage0 mirrors regenerated to the fixed point: two rounds installed, then
first_generation_equal=true 149/149/149, declared_divergent=1 [main.rs].

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

* Drop the named non-candidate and the inflated assert string (review 58256, follow-through)

Three further corrections, each verified before applying:

- The annotation no longer NAMES any candidate rustc consumer, even negatively.
  A named non-candidate is still a pointer, and a pointer is what a later reader
  turns into coverage. It now states a fact about the tree instead: no enrolled
  fail-closed rustc consumer covers this synthetic fixture. Checked rather than
  assumed -- the committed workflow invokes cargo test --release -p v1-compiler
  --lib with no --ignored, so what is established is that no committed scheduled
  route exists, not that none could.
- The assertion MESSAGE said the adapter must close the seam. That is a claim at
  a rung the test does not reach, and it is what a reader sees at the moment it
  goes red. It now says the forwarding adapter must be EMITTED at the impl Fn
  parameter.
- No rung-drop citation remains in the annotation: the drop it named is a drop of
  lane membership and does not answer a discrimination objection.

Mirrors driven to the fixed point over three rounds -- the emitter of the test
text, then the test text, then the verify -- first_generation_equal=true,
149/149/149, declared_divergent=1 [main.rs].

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

* Roster the new hand-Rust test blob in the scaffold index (review 58290)

gunbc.language_source_scaffold_index carries one LanguageSourceScaffoldRow per
hand-Rust blob decl, and test.claim.language_source_scaffold_index_test counts
ct_ declarations in the carrier against rows for that carrier. The new control's
blob had no row, so the diff added a ct_ declaration without appending to the
roster it belongs in.

The row takes compiler_tests_rust_hand_assertion_scaffold_trigger -- the same
Scaffold disposition every other hand-assertion blob in this carrier carries,
dissolving to SingleAuthority at v1.compiler.coercion CoercionTestEntry -- rather
than minting a new one, which would be a section 3 fork.
language_source_scaffold_roster_is_fully_dispositioned was EXECUTED with the row
in place and returns true.

Separately, and not repaired here: the carrier's completeness check is already
red on main -- 43 ct_ declarations against 40 rostered rows, three blobs
unrostered before this branch existed. That is filed as its own work item; this
commit discharges only this diff's contribution.

Mirrors unchanged (first_generation_equal=true, 149/149/149) and both doc
projections regenerate to identical bytes.

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

* Record the v1 admission for the adapter alignment control, and add EvidenceEnrollment (review 58359)

Review 58359 refused the new compiler_tests blob for lacking a hand-Rust
receipt naming a lane and a ROADMAP row. That vocabulary names nothing:
verified independently by me and by the ruling manager against origin/main,
DESIGN.md carries no such gate -- the SECOND time it has been cited at a PR and
the second time it was found to name nothing (the first is recorded in the
RcStr row of this same carrier). The receipt also cannot land in
language_source_scaffold_index, whose row type has no field a lane or ROADMAP
row could occupy; bolting it in as prose would be the section 4c violation.

So the obligation lands where v1 admissions actually live. The row records the
ruling relayed from bright-ram-778 on 2026-09-02, including the parts that are
easiest to drop in the citing: PublicSurfaceGrowth FIRES LITERALLY and is
admitted anyway, because the class exists to stop the seed accumulating
CAPABILITY and a test emitter accumulates none; the cheaper ruling -- that
compiler_tests blobs are not admission subjects at all -- was DECLINED, because
a category exemption never comes up for review again while one admission does;
the ruling admits this change only and does not resolve the
new-declaration-versus-any-change boundary; and the counter-argument is
preserved so overturning it is easy.

EvidenceEnrollment is added to MaintenanceAdmissionInstance rather than forcing
this into one of the four existing shapes -- every 4b(4) climb in v1 produces
it, so it is a class and not a bespoke slot.

Module typechecks (0 blocking diagnostics); no projection or mirror moved.

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

---------

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
Brian Searls and others added 3 commits September 2, 2026 03:55
# Conflicts:
#	DESIGN.md
#	dag/gunbc/recurring_failure_mode.dag
#	docs/design-ledgers.md
#	src/v1/stage0/src/compiler_tests.rs
#	src/v1/stage0/src/v1_compiler_compiler_tests_rust.rs
#	src/v1/stage0/src/v1_compiler_emit_rust.rs
# Conflicts:
#	DESIGN.md
#	docs/design-ledgers.md
#	src/v1/compiler_tests_rust.dag
#	src/v1/stage0/src/compiler_tests.rs
#	src/v1/stage0/src/v1_compiler_compiler_tests_rust.rs
#	src/v1/stage0/src/v1_compiler_emit.rs
#	src/v1/stage0/src/v1_compiler_emit_rust.rs
#	src/v1/stage0/src/v1_compiler_infer_resolve.rs
#	src/v1/stage0/src/v1_std_core.rs
briansrls pushed a commit that referenced this pull request Sep 2, 2026
…control (#10017)

`required-witnesses-build` fails on 4059156 and on bb96afa with
`regen FAIL generated surface drift: compiler_tests.rs,
std_realization_schedule.rs`. Reproduced locally at rc=1 on the same two
files before anything was installed, so the repair is evidenced rather
than assumed.

ROOT CAUSE, and it is not "the branch predated the control". `git log -S`
on the emitted fn
`function_value_adapter_fires_exactly_where_the_impl_fn_bound_is_emitted`
in the mirror has exactly two touches: 4e03636 (#9938) ADDS the
authority row and the emitted fn, and 4059156 (#9886) REMOVES the fn
while leaving the roster row standing. 4e03636 is an ANCESTOR of
#9886's first parent. So #9886 regenerated its mirror against an earlier
state, then merged main — which by then carried #9938's authority — and
its own stale projection bytes won.

That is the hazard DESIGN.md already records for the generated-artifact
driver: taking the ours side drops the other side's authority-derived
bytes with no conflict. What is new is the ROUTE. This landed through
GitHub, which does not run the merge driver at all; the driver would have
refused GeneratedArtifactConcurrentDivergence. Not a new class — the
existing one arriving through the one path where the wall is absent.

Why it matters beyond the red: main was carrying an enrolled §4b(4)
evidence control that exists in the authority and does not exist in the
artifact that executes. The roster still cited it as coverage. A control
that silently stops existing is worse than one that fails.

`std_realization_schedule.rs` is the same shape at one line: committed
`population_index: Nat` against the emitted `i64`.

Repair is the regenerated bytes, nothing hand-edited. Verified by
execution, not by inspection: claim_executor was REBUILT against the
installed mirror and the full regen re-run, giving
`first_generation_equal=true planned=150 executed=150 adjudicated=150`,
rc=0. A regen that greened only because it compares against the file I
edited would prove nothing, which is why the rebuild is the load-bearing
step.


Claude-Session: https://claude.ai/code/session_01L9g69G7ZkiCXGCeUUJgo9D

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Sep 2, 2026
… two compiler_tests failures on this PR's run are main's, inherited through a merge ref pinned at 06:47Z against bb96afa

The merge ref CI built for f3839b2 was pinned at push time against main as it
then stood (bb96afa), which carried #9886's stale mirror. That is the exact
subject #10017 repaired at 06:56Z, nine minutes after this PR's run started.

Evidence, checked rather than assumed:
  - main at bb96afa, run 33596615712: 'test result: FAILED. 642 passed; 2
    failed' with render_rust_applied_type_routes_qualified_base_through_leaf_name
    and shell_service_unmodeled_output_key_refuses -- byte-identical counts and
    identities to this PR's rust-unit-tests failure.
  - #10017's own body names 'regen FAIL generated surface drift:
    compiler_tests.rs, std_realization_schedule.rs' reproduced on 4059156 and
    bb96afa -- the same two files this PR's build job reported.
  - This branch changes two .dag files and no Rust: git diff origin/main...HEAD
    over compiler_tests.rs and std_realization_schedule.rs is empty.

Merging rather than rebasing per the squash-merge policy, and pushing after
main's last move so the merge ref is recomputed against the repaired base.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W377Pq4Tp5eQjGBXtPQEoM
gunbai-bot Bot pushed a commit that referenced this pull request Sep 2, 2026
…o forbid

`shell_service_unmodeled_output_key_refuses` has been red on main since the
commit that introduced it (#9886), and it was red for being CORRECT — the
inverse of an inert check, and rarer.

WHAT IT ASSERTED. It required the compiler to EMIT `src/probe.rs` and then
grepped that file's bytes for the refusal text `not_a_channel` and `has no
modeled channel`. That can only pass if the compiler emits a program
carrying the refusal into ITS runtime instead of stopping — which is
`refusal_deferred_to_emitted_runtime`. The control that #9886 added to
prove the shell path fails closed was asserting the fail-open shape as its
PASS condition.

WHAT THE COMPILER ACTUALLY DOES, run on that exact source:

  gunbc compile: refused at emit: ... produced 1 hard diagnostic(s):
  'shell' transport emission is not modeled: operation 'Probe.Version'
    declared in 'probe' cannot be emitted for target 'rust' -- shell
    transport output key 'not_a_channel' has no modeled channel -- the
    modeled channels are stdout, stderr, exit_success, ...
  error[probe.dag:6:7] | 6 | first: String from "not_a_channel"  ^^^^^
  exit code 2

Typed, located, names the key and the ten modeled channels, caret on the
offending field, and NO file emitted. So the
`.expect("service module must emit src/probe.rs")` fired on the right
behaviour. Three readers in sequence attributed this red to the emitter.

THE LOG SHAPE IS PART OF THE TRAP and is worth naming: `compile.emit done
in 0ms` is a PROGRESS TICK, not a verdict. The refusal is minted at the
binding and reported after the phase line, so anyone scanning upward from
the panic reads a successful emit that dropped a file — a silent-drop
story for a working refusal. That is `state_space_conflation` on the
completion axis, the same conflation `transport_close_read_as_completion`
names for transport.

THE REPAIR binds the diagnostic STRUCTURALLY rather than grepping emitted
text: `CompilerDiagnostic::TransportEmissionNotModeled` whose
`missing_realization_fact` names the key, plus an assertion that NO
`src/probe.rs` is emitted. The stdout fall-through previously checked by
`!emitted.contains("stdout.clone()")` is subsumed — if the emitter ever
falls through, a file appears and that assertion reds.

EACH ARM IS PROVEN NON-CONSTANT, separately, because a single probe reds
both at once and would establish only that SOMETHING is checked:

  positive control  unmodeled key, both arms      PASS
  ARM 1             modeled key, no-file only     RED: Emitted: [..., "src/probe.rs", ...]
  ARM 2             modeled key, diagnostic only  RED: got: []

Authority edit is in `src/v1/compiler_tests_rust.dag`; the two mirrors are
regenerated, which took two bootstrap rounds because the first pass
rebuilds the EMITTER (`v1_compiler_compiler_tests_rust.rs`) and only the
second emits the test text from it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L9g69G7ZkiCXGCeUUJgo9D
gunbai-bot Bot pushed a commit that referenced this pull request Sep 2, 2026
…serted the pre-wall shape

Part 1 of the main-is-red item. #9886 produced ONE root cause with TWO symptom
classes, and #10017 closed the first. This closes the second. No emitter changes.

WHAT WAS RED. `cargo test --release -p v1-compiler --lib` on main: 642 passed,
2 failed. Both failures are in the GENERATED src/v1/stage0/src/compiler_tests.rs.

  render_rust_applied_type_routes_qualified_base_through_leaf_name -- ALREADY FIXED
  by #10017, verified here rather than assumed. #9886's stale mirror deleted two
  lines from the TEST BODY, `env_value.unit_variant_index_observed = true` and the
  same on populated_env_value. Counting that string across the three refs gives
  fb481ae=2, 4059156=0, 52aac48=2. Without the observed flag the env
  carries no unit-variant evidence, so render_rust_applied_type CORRECTLY refused
  with a located compile_error! instead of emitting i64. The emitter was right and
  the regenerated test was wrong.

  shell_service_unmodeled_output_key_refuses -- what this commit fixes. It is a
  test #9886 ADDED, and #10017's mirror repair never touched it, so it is a
  separate defect rather than a second face of the stale mirror.

WHY IT WAS UNSATISFIABLE THE DAY IT LANDED. It did
`.find(|f| f.path == "src/probe.rs").expect("service module must emit src/probe.rs")`
and then looked for the refusal text INSIDE that file. No such file exists, by
construction: v1.compiler.compile emit_artifact returns
`EmitResult { files: [], diagnostics: unmodeled_transports }` when a transport
diagnostic fires -- the empty file list is PAIRED with a blocking diagnostic, not
standing alone. §5 was already satisfied; the compile refuses, typed
(TransportEmissionNotModeled) and located (span: ch.span, at the FIELD, with the
individual key in missing_realization_fact). #9886 wrote the wall and the test in
one PR, and the test asks for the shape the wall replaced.

THE SHAPE IT ASKED FOR IS A FILED DEFECT CLASS, twice over, which is why the fix
is not to make the emitter emit the file.
  - gunbc.recurring_failure_mode `accepted_source_emits_uncompilable_target`:
    "the .dag graph is the authority and Rust is one realization, so 'rustc
    catches it' is exactly the outsourcing this project exists to end."
  - 05_emit.dag's own annotation records that this exact shape was TRIED and filed
    as `refusal_deferred_to_emitted_runtime`: "7 files emitted, 0 diagnostics
    beside a panic!(): the line did not stop, the compile reported success, and
    the refusal was deferred to a runtime nobody reads until production."

WHAT THE TEST NOW ASSERTS -- through the wall, not about the bytes:
  1. an error diagnostic of variant TransportEmissionNotModeled exists
  2. its rendered message names `not_a_channel` AND `has no modeled channel`
  3. no `src/probe.rs` among r.files -- the line STOPPED rather than reported
     and continued
  4. no emitted file anywhere contains `stdout.clone()` -- #9886's own
     fall-through assertion, widened from one file to all of them
Its positive control is the sibling shell_service_output_projection_binds_each_
declared_channel: same fixture with every key modeled, zero diagnostics,
src/probe.rs emitted. So "no file" here is the refusal firing and not an emitter
that never emits for services.

RED CONTROLS, EXECUTED, in an isolated detached worktree so nothing here was
edited mid-run. Two mutations of the seed, each rebuilt and run:
  - delete the wall's diagnostic (unmodeled_shell_transport_diagnostics returns
    []): conjunct 1 goes RED, "must refuse with TransportEmissionNotModeled.
    Got: []".
  - remove only the line-stop in emit_artifact, then neutralise conjuncts 1 and 2
    so the mutant is judged by the file conjunct alone: conjunct 3 goes RED with
    ["Cargo.toml", "src/lib.rs", "src/main.rs", "src/probe.rs", "src/v1_rt.rs",
    "src/dry_run.rs", "src/emitted_population.rs"] -- seven files emitted, which
    is the ledger's recorded pre-wall shape reproduced by execution.
So neither the typed-refusal half nor the line-stop half is a passenger.

AUTHORITY ONLY. The edit is src/v1/compiler_tests_rust.dag; the two .rs files are
its regeneration and were installed from the candidate tree, never hand-edited.
Regenerated across BOTH generations, since compiler_tests.rs is rendered from the
running seed's baked string: regen -> install v1_compiler_compiler_tests_rust.rs
-> REBUILD claim_executor (grep of the new binary confirms it bakes the new
string) -> regen -> install compiler_tests.rs -> regen, which reports
`first_generation_equal=true planned=150 executed=150 adjudicated=150`. The
rebuild is the load-bearing step: a regen that greened against the file it just
wrote would prove nothing.

Neither 05_emit_rust.dag nor 04_resolve.dag is touched, so the two lanes working
in those files are unaffected.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VSP89XiSm2YMnUvSwSR1ct
gunbai-bot Bot pushed a commit that referenced this pull request Sep 2, 2026
…ansport

Every emitted service operation method declares
`-> Result<T, Box<dyn std::error::Error>>`, so every error arm owes that Box and
reaches it through `Into`. That one fact had two authorities: the REST arms spelled
`.into()` inline at their own call sites, and after #9886 the shell exit arms boxed
through their own constant `shell_boxed_stderr_error_arm`. They agreed -- which is
exactly the state the defect #9886 fixed was in before it surfaced.

That defect is the argument, not an analogy. The output-source property had two
readers -- the interpreter accepted `"from_key" || "from"`, the emitter's
child_from_key accepted only `"from_key"` -- and they agreed until they did not.
The divergence was invisible for the life of the code because a fallback answered
for the miss, and it surfaced as the emitter producing Rust that does not compile
with zero diagnostics. The shell error arm was part of that same failure: it
emitted a bare `Err(stderr)` against the declared Box for its whole life. The
emitter does not typecheck what it emits, so nothing catches this class.

So `emit_rust_boxed_error_return(message_expr)` is now the only place the
conversion is spelled; both REST arms and both shell arms call it, and the shell
constant is deleted. DESIGN section 5, construction over validation: after this
there is no second site at which a different spelling could be written, so the
divergence is unwritable rather than caught.

EVIDENCE. New witness `rest_emit_error_arms_are_boxed` covers the REST arms, which
had no witness at all; `shell_emit_exit_error_arm_is_boxed` (from #9886) covers the
shell side. Both now run through the one constructor, so a re-fork at either site
fails them. Stated honestly: the refactor is byte-preserving by construction, so
no witness goes RED on the unification itself -- the RED these discriminate is a
future divergence, and the unwritability is the construction argument, not a test
result.

Scope held to the error return spelling: the six type renderers and
is_host_text_carrier_type are untouched.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G9q7HZqy1inoJYfnNdBB5J
gunbai-bot Bot added a commit that referenced this pull request Sep 2, 2026
…o forbid (#10025)

`shell_service_unmodeled_output_key_refuses` has been red on main since the
commit that introduced it (#9886), and it was red for being CORRECT — the
inverse of an inert check, and rarer.

WHAT IT ASSERTED. It required the compiler to EMIT `src/probe.rs` and then
grepped that file's bytes for the refusal text `not_a_channel` and `has no
modeled channel`. That can only pass if the compiler emits a program
carrying the refusal into ITS runtime instead of stopping — which is
`refusal_deferred_to_emitted_runtime`. The control that #9886 added to
prove the shell path fails closed was asserting the fail-open shape as its
PASS condition.

WHAT THE COMPILER ACTUALLY DOES, run on that exact source:

  gunbc compile: refused at emit: ... produced 1 hard diagnostic(s):
  'shell' transport emission is not modeled: operation 'Probe.Version'
    declared in 'probe' cannot be emitted for target 'rust' -- shell
    transport output key 'not_a_channel' has no modeled channel -- the
    modeled channels are stdout, stderr, exit_success, ...
  error[probe.dag:6:7] | 6 | first: String from "not_a_channel"  ^^^^^
  exit code 2

Typed, located, names the key and the ten modeled channels, caret on the
offending field, and NO file emitted. So the
`.expect("service module must emit src/probe.rs")` fired on the right
behaviour. Three readers in sequence attributed this red to the emitter.

THE LOG SHAPE IS PART OF THE TRAP and is worth naming: `compile.emit done
in 0ms` is a PROGRESS TICK, not a verdict. The refusal is minted at the
binding and reported after the phase line, so anyone scanning upward from
the panic reads a successful emit that dropped a file — a silent-drop
story for a working refusal. That is `state_space_conflation` on the
completion axis, the same conflation `transport_close_read_as_completion`
names for transport.

THE REPAIR binds the diagnostic STRUCTURALLY rather than grepping emitted
text: `CompilerDiagnostic::TransportEmissionNotModeled` whose
`missing_realization_fact` names the key, plus an assertion that NO
`src/probe.rs` is emitted. The stdout fall-through previously checked by
`!emitted.contains("stdout.clone()")` is subsumed — if the emitter ever
falls through, a file appears and that assertion reds.

EACH ARM IS PROVEN NON-CONSTANT, separately, because a single probe reds
both at once and would establish only that SOMETHING is checked:

  positive control  unmodeled key, both arms      PASS
  ARM 1             modeled key, no-file only     RED: Emitted: [..., "src/probe.rs", ...]
  ARM 2             modeled key, diagnostic only  RED: got: []

Authority edit is in `src/v1/compiler_tests_rust.dag`; the two mirrors are
regenerated, which took two bootstrap rounds because the first pass
rebuilds the EMITTER (`v1_compiler_compiler_tests_rust.rs`) and only the
second emits the test text from it.


Claude-Session: https://claude.ai/code/session_01L9g69G7ZkiCXGCeUUJgo9D

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Sep 2, 2026
… — 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 Bot pushed a commit that referenced this pull request Sep 2, 2026
The annotation fused two eras onto one subject. It read as though the constant
this change deletes had spelled `Err(stderr)` unboxed. It did not: #9886
INTRODUCED `shell_boxed_stderr_error_arm` already boxed, hours before this change.
What emitted the unboxed `Err(stderr)` was the INLINE shell arm that preceded the
constant, and #9886 is the PR that killed it.

A reader trusting the old sentence would conclude the deleted constant said
`Err(stderr)`, and could only discover otherwise by going to the history the
sentence claims to describe. That matters here for two reasons: 05_emit_rust.dag
is a pipeline stage DESIGN names as load-bearing, and a section 4c annotation is
the one thing in the file no execution can falsify -- nothing ever goes red over a
wrong one.

The corrected sentence is also the stronger argument: the two spellings agreed only
because #9886 had just made them agree, so the fork SURVIVED ITS OWN REPAIR -- the
repair produced a second authority for one fact rather than removing the first.

Annotation only. Section 4c: annotations are erased before semantic passes and
cannot alter emitted bytes, so no mirror regeneration is owed and none is included.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G9q7HZqy1inoJYfnNdBB5J
gunbai-bot Bot added a commit that referenced this pull request Sep 2, 2026
…es without judging, and a capture that reads clean because it is empty (#10044)

* Two error classes from the night's own instruments: a gate that refuses without judging, and a capture that reads clean because it is empty

Both are §4b(1) filings against mechanisms this repository relies on to know whether it is
correct, and each carries the receipt that made it decidable rather than anecdotal.

non_verdict_disposition_surfaces_as_refusal. The required floor reports THIS SUBJECT IS
WRONG and I DID NOT FINISH LOOKING through one refusing channel. Its receipt is a same-head
pair: 9b00e24 run twice with no intervening edit, planned=3486 executed=3486 failed=0
both times, seven INTERRUPTED-BEFORE-VERDICT / COMPLETED-OVER-COST-REQUIREMENT rows present
in the first and absent in the second. Holding the bytes fixed by construction is what makes
it a measurement: a cross-head comparison would have required arguing that the intervening
commit could not have touched cost accounting, and an argument about what a diff cannot do is
exactly what gets overturned. The harm is not the red -- it is that a refusal naming no wrong
subject can only be answered by rerunning, and a wall discharged by rerunning is not a wall.

empty_capture_read_as_clean_result. An instrument refuses on one stream while the reader keeps
the other, so the capture is empty and the empty capture is consumed as a finding of nothing.
Specimen: `gh run view --job <id> --log > f` on an in-progress run writes ZERO BYTES with its
refusal on stderr, so a grep for `panicked` over that file reports no failures for a job that
already failed. The failure direction is always benign, which is why it recurs -- an empty
capture never manufactures a false alarm, only a false all-clear.

Both name a capability as their trigger, not an artifact: a required-gate verdict in which
non-verdict dispositions are a third outcome plus a claim-owned cost admission, and a
result type that cannot let a zero-byte capture inhabit READ AND FOUND NOTHING.

ON THE REGENERATION, stated rather than quietly omitted: docs/design-ledgers.md and DESIGN.md
are regenerated by main_wet, which reproduced all other rostered artifacts byte-identically --
that is the positive control for this projection. The stage0 --required-regen run FAILED with
drift in compiler_tests.rs, and that failure is VOID rather than a finding: the candidate it
produced is 8 lines from the PRE-#9886 committed file and 148 from the current one, because
this session's binary was built at 03:56 from the stage0 mirror as it stood before #9886
changed 05_emit_rust. A stale seed regenerates a stale world. CI's build lane regenerates with
a current binary and is the adjudicator; main's own build lane was green at 7f71ee3, after
#9886 landed.

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

* Both remedies said the right thing loosely enough to teach the wrong one (review 58608)

The rows are authority text, so a remedy phrased ambiguously is not a wording problem — it is
the row instructing a future implementer to fail open. Both findings are correct and both are
fixed at the sentence that would have been read.

DISTINCT IN DIAGNOSIS, NEVER IN WHETHER THE LINE STOPS. Trigger conjunct (i) asked for
non-verdict dispositions as a third outcome and did not say the gate must still block on it.
Read as written, "a third outcome distinct from pass and fail" invites a third outcome that is
also distinct in blocking — which is the widening arm §5 forbids, trading a refusal that names
no subject for no refusal at all. A run that did not finish looking has established nothing.
The row now says the third outcome still stops the gate, that what changes is what the refusal
SAYS, and that an undecided row is discharged by making the claim reach a verdict rather than
by a rerun that happens to land under the ceiling. The defect was always the conflation, not
the stopping; the sentence did not say so.

ZERO BYTES IS NOT A VERDICT IN EITHER DIRECTION. "Treat zero as DID NOT READ, never as FOUND
NOTHING" collapsed the same two states the row exists to keep apart, and in the fabricating
direction: a query that legitimately returns nothing would be converted into a failure. The
rule is now two-step — consult the instrument's typed status, its exit code and the stream its
refusal travels on, before consuming the emptiness. Status says it ran and the capture is
empty: FOUND NOTHING, a real observation. Status says it refused, or no status is available:
DID NOT READ, and nothing may be concluded. The original habit's failure was not reading zero
as one of the two, it was reading zero without asking which.

docs/design-ledgers.md regenerated by main_wet; every other rostered artifact reproduced
byte-identically, which is this projection's positive control.

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

* The specimen was seven rows and the class is four of them (review 58619)

completed_over_cost_requirement names claims that REACHED A VERDICT and were then reclassified
on cost. The floor says so in its own diagnostic — "reached its verdict and then exceeded its
budget ... cost=501ms EXACT ... This is a cost debt only — it is not a defect" — and the rows
carry outcome=completed_over_budget, which is to say they PASSED. Folding those three into a
class about gates that did NOT reach a judgment inflated the specimen by more than half and
contradicted a distinction the model draws deliberately.

Worse than the arithmetic: it was rung inflation of the same shape §4b(1) forbids, committed
inside a row whose subject is a gate reporting more than it established. I had the refuting
text in the log I quoted from and read past it.

The class is now the four INTERRUPTED-BEFORE-VERDICT rows, and the sentence that carries the
harm is sharper for the narrowing: four undecided rows were sufficient to refuse a run in
which zero claims failed. The three over-cost rows are retained only where they are honest —
as the second half of the nondeterminism observation, since both arms of the cost machinery
vary run to run on fixed bytes.

docs/design-ledgers.md regenerated by main_wet; every other rostered artifact reproduced
byte-identically.

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

* Narrow the row to what is true at its own grain, and make the reroll mitigation the admitted arm

Four edits, three of them corrections to this PR and one discharging a condition the authority
already stated.

THE ROW OVERSTATED ITS OWN SUBJECT, and it was falsifiable from the log it cites. It said the
gate reports both outcomes "through one refusing channel, so a reader cannot tell a judgment
from a missing judgment". The floor prints INTERRUPTED-BEFORE-VERDICT and
COMPLETED-OVER-COST-REQUIREMENT as distinct typed diagnostics and carries them as separate
counters beside failed. A log reader can tell them apart perfectly. What cannot is everything
downstream of the fold — FloorRefused, the red check, the dashboard cell, the merge gate —
each receiving one bit whose only affordance is a reroll. So the defect is not a missing
distinction but a computed one erased on the way out, which is the worse shape: the
information exists and is discarded. Overstating this inside a row about a gate reporting more
than it established was the same failure twice.

THE COST HALF IS ALREADY ROSTERED AND IS NOW CITED RATHER THAN RE-DERIVED. That a claim's
measured cpu-ms is unstable on a shared runner is gunbc.rung_drop floor_cost_contention_verdict,
declared 2026-09-01, whose trigger is a claim-owned cost basis invariant across envelopes.
Filing it again would be a second authority over one fact.

AND THE MITIGATION WE HAVE ALL BEEN USING IS NOW THE ADMITTED ONE. That row ends by admitting
retry-until-green "only as a counted, visible mitigation carrying this row's trigger as its
dissolution condition". Rerolling has been in continuous bounded use across the board today —
one per head per signature, only on failed=0 — which is better than unbounded and was still
not the admitted arm, because nothing enumerated it. The receipt enumerates every instance BY
RUN ID, names the drop's own trigger as its dissolution condition, and states plainly that no
modeled producer counts them. No tally: this row has already had to retract one hand-derivation
described as a run product, and a count with no producer is stale at the next roll and
re-derivable by nobody. Whoever wants the number counts the citations.

The instances carry one observation finer than either the drop or the row had: after #10038's
live-gate cost repairs, self_host_compile_phase_live_gate_witness was ABSENT from attempt 1 and
BACK in attempt 2 of ONE head. Not merely less frequent — intermittent within a single head's
attempts, which is the sharpest statement that a cost repair moves incidence without touching
the mechanism at the boundary.

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

* wip: bind specimen counters to attempt and job (jolly-hawk-122's clause, verified)

* Merge main, and bind each specimen counter to its attempt and job

The roster conflict was both sides appending to the same list tail — union, then checked
rather than assumed: 56 rostered identities against 56 declarations, none missing and none
orphaned. Neither side deleted a row, which is the case where union would have silently
re-added something deliberately removed.

DESIGN.md and docs/design-ledgers.md are generated, so they are regenerated from the merged
authority rather than hand-resolved. main_wet reproduced every other rostered artifact
byte-identically across main's changes to generated_artifact_emit and the workflow emissions,
which is this projection's positive control.

THE SPECIMEN COUNTERS NOW NAME THEIR INSTRUMENT. "First run" and "rerun" are ordinals that name
nothing and do not distinguish run 33604337589 from run 33628404336 on a later head. Each side
is now addressed by attempt AND job: attempt 1 is floor job 100172868685 (interrupted=4,
over_cost=3, FloorRefused), attempt 2 is job 100189043027 (0 and 0, green). Clause supplied by
session jolly-hawk-122, verified here against both jobs' logs before adoption.

AND IT NAMES THE COMMAND THAT MUST NOT BE USED TO RE-DERIVE IT, because the obvious one lies.
`gh run view --job 100172868685 --log` answers the ATTEMPT-1 job id with ATTEMPT 2's content —
its runner banner reads 09:03 where that job's own log begins 08:05, and it reports
interrupted_before_verdict=0, which are attempt 2's counters. Reproduced independently here.
A reader trusting it records 0 and 0 for both attempts, sees no disagreement, and destroys the
specimen this row is built on. Only `gh api .../actions/jobs/<job>/logs
--allow-escape-sequences` answers per job — and without that flag it writes zero bytes, which
is the sibling failure already rostered. Same call, both directions: empty on one flag, ~600 kB
of plausible wrong-subject log on the wrong subcommand. The wrong-content direction is the more
dangerous, and it is recorded where it protects the specimen rather than widening
empty_capture_read_as_clean_result past its authored grain.

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

* Enumerate the remaining reroll instances, and name the instrument beside them

Four instances were spent or observed and not yet counted. An enumerated instance is what makes
this mitigation the arm the row admits rather than the one it forbids, so a spent roll left
unrecorded is the violation itself, not a bookkeeping lapse.

#10047 run 33622971872 attempt 2 — and the roster PREDICTED the row that blocked it: attempt 1
refused at 502ms on v2.test.emit.rust_binop_emit, a module carrying four identities in this
row's own attention subset.

#9986 at f5fca17 — two interrupted rows in compiler_frontend_program_status_witness and
self_host_compile_phase_frontier_witness, NEITHER in the live-gate family, on a head that had
already taken 2d76d9c. That is what establishes the arm is not confined to a repairable
family, and it refutes a prediction both this session and its manager made.

#10044 run 33628404336 attempts 1 and 2, jobs 100219422472 and 100256793010 — refuse then
refuse at ONE ROW EACH, failed=0 and planned=executed=3486 on both, and the row was
v2.test.emit.produced_decl_two_target on attempt 1 and v2.test.execution.emit_host_module_equals_eval
on attempt 2. At n=1 per side the arm did not re-refuse the same expensive claim; it drew a
different one. The population is redrawn per attempt rather than sampled from a fixed set of
costly rows — which is why family-by-family cost repair lowers incidence without bounding the
class, and why a green reroll is not evidence the refused row was wrong.

AND THE RECEIPT NOW NAMES THE COMMAND, because it enumerates run ids and therefore invites
re-derivation by exactly the reader most likely to hold the wrong instrument. `gh run view
--job <id> --log` answers an attempt-1 job id with attempt 2's content, so an auditor checking a
two-attempt specimen with it gets identical content on both sides, sees no disagreement, and
reports these instances as fabricated. It fails in the direction that discredits a true finding.
Only `gh api repos/OWNER/REPO/actions/jobs/JOB/logs --allow-escape-sequences` answers per job;
without the flag it writes zero bytes.

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

* The pair is suggestive; the instances jointly are what corroborate the redraw

Deliberately discarding a green head to fix one sentence, because the sentence is in the
artifact and the qualification was only in a PR comment.

WHAT WAS OVERSTATED. The receipt said the refuse-then-refuse pair on 03780b8 — one row
each, different identity — showed "the population is redrawn per attempt". Two draws with
different identities at n=1 per side are equally consistent with a FIXED set of marginal rows
sitting close enough to the deadline that ordering decides which crosses. Identity change alone
does not discriminate those explanations, and the row asserted the stronger one.

WHAT ACTUALLY DISCRIMINATES, and it needs the instances jointly rather than any one pair: the
COUNT moves as well as the membership — 4→0, 5→2, 1→1, 2→4, and 15. A fixed marginal set would
have to explain a count ranging over 0, 1, 2, 4, 5 and 15 AND the membership changing. Redraw
explains both; near-threshold ordering explains only the second. The load-bearing consequence is
unchanged on either reading: no enumeration of the expensive claims can be the population, so
family-by-family cost repair lowers incidence without bounding the class.

WHY NOT LAND FIRST AND FIX AFTER. The receipt is the durable artifact — it lists run ids and
invites re-derivation. A PR comment is not part of it, so on squash the qualification would stay
in a conversation nobody re-reads while the stronger claim shipped alone in the file. And the
asymmetry is bad in the wrong direction: this receipt's whole value is withstanding a skeptic
who re-derives it, and an auditor who finds one overstated sentence discounts the other five
instances too. Overclaiming the weakest link is what makes the strong links unreadable.

THE COST, STATED RATHER THAN ELIDED: d7f3ab0 was terminal-green on every required job —
build, floor, witnesses, rust-unit — with two approvals, and this discards all of it for a fresh
draw at the nondeterministic arm this PR documents. Caught by tidy-swift-334 against my own
evidence; the ruling to push before landing is theirs.

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

---------

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
gunbai-bot Bot added a commit that referenced this pull request Sep 2, 2026
…e two sentences it makes false (#10078)

Part 2 of the operator-approved item, and the promotion is now literally one row
because #10036 made the lane axis a roster. Three edits, only one of which is the
promotion:
  one `RequiredLane` in `required_lanes_roster`
  one `required_lanes_gate_unit_var` beside its BUILD/FLOOR siblings, so the
    variable is a declared row rather than a bare literal at the use site
  the aggregate step's name, because "Both required lanes must have succeeded" is
    false with three

WHY THIS MATTERS AT ALL. The 774 `#[test]`s under src/v1/stage0 ran on no CI path
before that job existed, then ran on every push and pull request while GATING
NOTHING -- and the gap produced exactly the harm it predicts: #9886 landed two
failing tests on main with every required check green. That is the whole reason
this item exists.

THE EMITTED DELTA IS THE RECEIPT, and it is the same six surfaces PR A's forward
control predicted before any of this was written:
  needs: [...build, ...floor, rust-unit-tests]
  a third `|| [ "$UNIT" != success ]` conjunct in the unestablished fold
  a third `|| [ "$UNIT" = failure ]` conjunct in the red fold
  ` unit=$UNIT` in the receipt line and in BOTH refusal messages
  UNIT: ${{ needs['rust-unit-tests'].result }} in the step env
  the step name
A `needs`-only edit would have produced the first and last of those and NONE of
the middle -- the lane would have been waited on and still unable to fail the
gate. That failure mode is why PR A landed first.

THE ANNOTATION IS REWRITTEN, NOT APPENDED TO. It said "It is not a `needs` of the
aggregate, so it does not gate a merge yet", which this commit makes false, and
§4c forbids an annotation restating what the declaration no longer says. Verified
the rewrite added ZERO emitted bytes -- annotations are erased before emission, so
the YAML delta is unchanged by it and carries none of its text.

ALL THREE PRECONDITIONS DISCHARGED, NOT ARGUED AWAY, and the annotation now states
them as a RULE rather than as history:
  MAIN GREEN -- and this was not hypothetical. While the promotion was held,
  #10036 was blocked by shell_service_unmodeled_output_key_refuses, main's own
  defect, whose fix its author had already landed under another number. A
  promotion whose first act blocks every open PR on an already-fixed defect is a
  self-inflicted outage.
  FLEET HEALTHY -- a lane that cannot be delivered its admitted memory or
  toolchain produces reds carrying no information about the diff.
  COST ACCOUNTING UNDERSTOOD (#10053) -- the same argument one layer down.
The generalisation is in the annotation because a later reader will be tempted to
drop the third: A LANE MAY BE PROMOTED ONLY WHEN A RED IN IT DISCRIMINATES. Wall
clock is the cheap question; whether the lane's failures are ABOUT THE DIFF is the
load-bearing one.

COST ON THE CRITICAL PATH IS ZERO, by comparison rather than by bound: the lanes
run in parallel with the aggregate only waiting, and measured across 120 witnesses
runs this job sits BELOW required-witnesses-floor at every quantile. The
annotation names the producer to re-derive it and deliberately does NOT carry the
figures -- a timeout-headroom argument would have been the wrong one, since
headroom says nothing about what the aggregate waits for.


Claude-Session: https://claude.ai/code/session_01VSP89XiSm2YMnUvSwSR1ct

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
briansrls pushed a commit that referenced this pull request Sep 2, 2026
…ansport (#10042)

* Unify the emitted boxed-error return: one constructor, not one per transport

Every emitted service operation method declares
`-> Result<T, Box<dyn std::error::Error>>`, so every error arm owes that Box and
reaches it through `Into`. That one fact had two authorities: the REST arms spelled
`.into()` inline at their own call sites, and after #9886 the shell exit arms boxed
through their own constant `shell_boxed_stderr_error_arm`. They agreed -- which is
exactly the state the defect #9886 fixed was in before it surfaced.

That defect is the argument, not an analogy. The output-source property had two
readers -- the interpreter accepted `"from_key" || "from"`, the emitter's
child_from_key accepted only `"from_key"` -- and they agreed until they did not.
The divergence was invisible for the life of the code because a fallback answered
for the miss, and it surfaced as the emitter producing Rust that does not compile
with zero diagnostics. The shell error arm was part of that same failure: it
emitted a bare `Err(stderr)` against the declared Box for its whole life. The
emitter does not typecheck what it emits, so nothing catches this class.

So `emit_rust_boxed_error_return(message_expr)` is now the only place the
conversion is spelled; both REST arms and both shell arms call it, and the shell
constant is deleted. DESIGN section 5, construction over validation: after this
there is no second site at which a different spelling could be written, so the
divergence is unwritable rather than caught.

EVIDENCE. New witness `rest_emit_error_arms_are_boxed` covers the REST arms, which
had no witness at all; `shell_emit_exit_error_arm_is_boxed` (from #9886) covers the
shell side. Both now run through the one constructor, so a re-fork at either site
fails them. Stated honestly: the refactor is byte-preserving by construction, so
no witness goes RED on the unification itself -- the RED these discriminate is a
future divergence, and the unwritability is the construction argument, not a test
result.

Scope held to the error return spelling: the six type renderers and
is_host_text_carrier_type are untouched.

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

* Correct the constructor's annotation: the fork survived its own repair

The annotation fused two eras onto one subject. It read as though the constant
this change deletes had spelled `Err(stderr)` unboxed. It did not: #9886
INTRODUCED `shell_boxed_stderr_error_arm` already boxed, hours before this change.
What emitted the unboxed `Err(stderr)` was the INLINE shell arm that preceded the
constant, and #9886 is the PR that killed it.

A reader trusting the old sentence would conclude the deleted constant said
`Err(stderr)`, and could only discover otherwise by going to the history the
sentence claims to describe. That matters here for two reasons: 05_emit_rust.dag
is a pipeline stage DESIGN names as load-bearing, and a section 4c annotation is
the one thing in the file no execution can falsify -- nothing ever goes red over a
wrong one.

The corrected sentence is also the stronger argument: the two spellings agreed only
because #9886 had just made them agree, so the fork SURVIVED ITS OWN REPAIR -- the
repair produced a second authority for one fact rather than removing the first.

Annotation only. Section 4c: annotations are erased before semantic passes and
cannot alter emitted bytes, so no mirror regeneration is owed and none is included.

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

---------

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
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