Repository navigation
Join the OCI model to the fleet: dissolve the ContainerRuntime nickname and make a customer-supplied container image expressible - #9394
Merged
Conversation
added 5 commits
August 27, 2026 02:05
gunbai-bot Bot
pushed a commit
that referenced
this pull request
Aug 27, 2026
…ed generated-artifact population as a required CI phase
`gunbc.generated_artifact_emit` `generated_artifact_body_for_path` is a pure
projection over the three authorities `main_wet` folds -- the committed-artifact
roster, `artifact_path`, and the single `artifact_generate` dispatch -- and it
answers, for any repo-relative path, exactly what the tree ought to hold there.
THE PRODUCER WAS NEVER MISSING. THE CALLER WAS.
From the 2026-08-15 floor cut until this change, the only route that ASKED it was
`claim_executor`'s behavioural-receipt census, which asks only about paths of the
form `src/v1/stage0/src/<mirror>` because its subject is emitted Rust mirrors.
Every committed artifact that is not a Rust mirror -- `DESIGN.md`, `ROADMAP.md`,
the workflow YAML, `.gitignore`, `.gitattributes`, the githooks, the plans -- was
computed by nothing and compared by nothing. DESIGN's own CI paragraph named the
generated-artifact drift gates on the re-add queue that cut created; this is the
first item taken off it.
WHAT THE PHASE FOUND ON ITS FIRST EXECUTION, which is the argument for it. Green
over an unguarded corpus would have been the more suspicious result:
rostered=72 adjudicated=72 matches=68 drifted=2 absent=2 unadjudicated=0
drifted DESIGN.md (this change's own authority edit)
drifted docs/plans/realization-measurement-loop.md (an authority change never installed:
#9394 dissolved the ContainerRuntime
nickname and the projection still
named it)
absent docs/plans/v2-corpus-self-host.md (rostered, never written)
absent docs/plans/import-namespace-program.md (rostered, never written)
All four are regenerated here by the sanctioned route (`main_wet` on
`dag/tools/generated_artifact_gate.dag`), and the phase is green after.
CONSTRUCTION, not another roster. The host resolves `generated_artifact_emit`
once and asks it for BOTH the roster (`committed_generated_artifact_paths`) and
each body, so an artifact added to `generated_artifact_registry` is enrolled with
no edit to the host and a path list in Rust -- the second roster DESIGN 3
forbids -- does not exist. Production precedes adjudication in the TYPE: every
verdict is reached through the produced population, so "refused, having compared
nothing" has no spelling outside the arms that carry no population.
TWO COUNTS, NEVER ONE. A rostered member that reaches no verdict is reported and
stops the line SEPARATELY from a drifted one. `0 drifted` over a population
nothing asked about is the execution-provenance loss DESIGN names -- an unreached
observation reading as a pass -- and the discriminating unit test asserts exactly
that: an outcome whose every verdict matched is NOT clean while one member is
unadjudicated, and is still not reported as drift.
READ-ONLY BY CONSTRUCTION: no write path, no flag that opens one. Installing a
regenerated artifact stays `main_wet`'s job, because a gate that can also write
its own subject is a gate whose green proves nothing.
The bridge `claim_executor` had declared privately (`GeneratedArtifactPathBody`,
`generated_artifact_ctx`, `generated_artifact_body_for_path`) is hoisted into
`v1_compiler::cli_run::generated_artifact_boundary_host` and re-exported through
`cli_run`, the way the regen and partition-crate producers already are, rather
than copied -- two hosts asking one projection is the forked dispatch DESIGN 3
forbids.
The refusal names a route that EXISTS, in one place
(`GENERATED_ARTIFACT_PRODUCING_COMMAND`), because a stop whose only sanctioned
move is unavailable does not stop the line, it launders a hand edit -- the trap
this repository has now recorded three times.
`gunbc.design_document` records the phase and takes the generated-artifact drift
gates off the unguarded list; DESIGN.md is its regenerated projection.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbai-bot Bot
pushed a commit
that referenced
this pull request
Aug 27, 2026
…nrol the whole committed generated-artifact population as a required CI phase `gunbc.generated_artifact_emit` `generated_artifact_body_for_path` is a pure projection over the three authorities `main_wet` folds -- the committed-artifact roster, `artifact_path`, and the single `artifact_generate` dispatch -- and it answers, for any repo-relative path, exactly what the tree ought to hold there. THE PRODUCER WAS NEVER MISSING AND NEITHER WAS THE WRITER. THE CHECKER WAS. (Premise correction from warm-hawk-909, who wrote the brief: the work item's title says no route REGENERATES these files, and that is false -- `tools.generated_artifact_gate` `main_wet` is a declared writer. Nothing here adds a second one; every repair below was installed by invoking that one.) From the 2026-08-15 floor cut until this change, the only route that ASKED the projection anything was `claim_executor`'s behavioural-receipt census, which asks only about paths of the form `src/v1/stage0/src/<mirror>` because its subject is emitted Rust mirrors. Every committed artifact that is not a Rust mirror -- `DESIGN.md`, `ROADMAP.md`, the workflow YAML, `.gitignore`, `.gitattributes`, the githooks, the plans -- was compared by nothing. DESIGN's own CI paragraph named the generated-artifact drift gates on the re-add queue that cut created; this is the first item taken off it. WHAT THE PHASE FOUND ON ITS FIRST EXECUTION, measured at 441ce5c (stated with its subject sha because the gate's whole purpose is to make this number zero, so it is not re-derivable from a later tree): rostered=72 adjudicated=72 matches=68 drifted=2 absent=2 unadjudicated=0 TWO WERE DRIFT AND ARE REGENERATED HERE: DESIGN.md this change's own authority edit docs/plans/realization-measurement-loop.md #9394 dissolved the ContainerRuntime nickname in the authority and the projection still named it The second is the headline: an authority-side divergence with a provenance I did not author, wrong since #9394, invisible to everything. It is also what proves the generator READS the authority -- a checker comparing a file to itself cannot produce it. THE OTHER TWO WERE NOT DRIFT AND ARE NOT REGENERATED. `docs/plans/v2-corpus-self-host.md` was DELETED ON PURPOSE by a295e17, whose entire subject is the ruling that the .dag carrier is the authority and the markdown should not exist; `docs/plans/import-namespace-program.md` has never existed at that path. An earlier revision of this branch regenerated both. That was wrong, and the way it was wrong is the most dangerous shape this phase can have: a drift gate makes whatever it adjudicates BINDING, so an absence that was inert before becomes a line-stop, and the cheapest way to move the line is to regenerate -- converting a dormant registry mistake into a standing obligation to recreate deleted files, green either way. Caught in review by warm-hawk-909. THE STALE HALF WAS THE REGISTRY ROW, NOT THE MISSING FILE, so the repair runs the other way: `gunbc.plan` gains `PlanProjection`, a plan declares whether its markdown is a committed artifact at all, and `artifact_commit_policy` asks the plan instead of answering `CommitRequired` for every slug. `PlanIsAuthorityOnly` carries the ruling that removed the projection, so the row cannot drift from its reason. It is NOT an exemption list and NOT a shrink: both plans stay rostered, stay generated, and still refuse if generation refuses -- only whether their bytes are expected on disk changes. The field is required, so a new plan cannot omit the decision. CONSTRUCTION, not another roster. The host resolves `generated_artifact_emit` once and asks it for BOTH the roster (`committed_generated_artifact_paths`) and each body, so an artifact added to `generated_artifact_registry` is enrolled with no edit to the host, and a path list in Rust -- the second roster DESIGN 3 forbids -- does not exist. Production precedes adjudication in the TYPE: every verdict is reached through the produced population, so "refused, having compared nothing" has no spelling outside the arms that carry no population. TWO COUNTS, NEVER ONE. A rostered member that reaches no verdict is reported and stops the line SEPARATELY from a drifted one. `0 drifted` over a population nothing asked about is the execution-provenance loss DESIGN names, and the discriminating unit test asserts exactly that: an outcome whose every verdict matched is NOT clean while one member is unadjudicated, and is still not reported as drift. READ-ONLY BY CONSTRUCTION: no write path, no flag that opens one. Installing a regenerated artifact stays `main_wet`'s job, because a gate that can also write its own subject is a gate whose green proves nothing. The bridge `claim_executor` had declared privately (`GeneratedArtifactPathBody`, `generated_artifact_ctx`, `generated_artifact_body_for_path`) is hoisted into `v1_compiler::cli_run::generated_artifact_boundary_host` and re-exported through `cli_run`, the way the regen and partition-crate producers already are, rather than copied -- two hosts asking one projection is the forked dispatch DESIGN 3 forbids. The new file is registered as seed-retained hand Rust in `v2.compiler.self_host.stage0_crate_layout`, beside `partition_crate_boundary_host`; its layout projections are regenerated. The refusal names a route that EXISTS, in one place (`GENERATED_ARTIFACT_PRODUCING_COMMAND`), because a stop whose only sanctioned move is unavailable does not stop the line, it launders a hand edit. EXECUTED, whole build lane, from binaries built out of this tree: regen first_generation_equal=true v2-emission EmissionCompleted blocking=0 partition-crates rendered=14 matches=14 generated-artifact rostered=70 adjudicated=70 matches=70 drifted=0 absent=0 unadjudicated=0 lane=build phases_run=4 failed=0 WHAT IS NOT CLAIMED: `main_wet` generates and writes one artifact at a time, so a refusal partway would install a mixed projection epoch. That is a mechanism read, not an executed receipt -- no generation refused here -- and it is left to its own PR with its own receipt rather than repaired on a hypothesis. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbai-bot Bot
pushed a commit
that referenced
this pull request
Aug 27, 2026
…nrol the whole committed generated-artifact population as a required CI phase `gunbc.generated_artifact_emit` `generated_artifact_body_for_path` is a pure projection over the three authorities `main_wet` folds -- the committed-artifact roster, `artifact_path`, and the single `artifact_generate` dispatch -- and it answers, for any repo-relative path, exactly what the tree ought to hold there. THE PRODUCER WAS NEVER MISSING AND NEITHER WAS THE WRITER. THE CHECKER WAS. (Premise correction from warm-hawk-909, who wrote the brief: the work item's title says no route REGENERATES these files, and that is false -- `tools.generated_artifact_gate` `main_wet` is a declared writer. Nothing here adds a second one; every repair below was installed by invoking that one.) From the 2026-08-15 floor cut until this change, the only route that ASKED the projection anything was `claim_executor`'s behavioural-receipt census, which asks only about paths of the form `src/v1/stage0/src/<mirror>` because its subject is emitted Rust mirrors. Every committed artifact that is not a Rust mirror -- `DESIGN.md`, `ROADMAP.md`, the workflow YAML, `.gitignore`, `.gitattributes`, the githooks, the plans -- was compared by nothing. DESIGN's own CI paragraph named the generated-artifact drift gates on the re-add queue that cut created; this is the first item taken off it. WHAT THE PHASE FOUND ON ITS FIRST EXECUTION, measured at 441ce5c (stated with its subject sha because the gate's whole purpose is to make this number zero, so it is not re-derivable from a later tree): rostered=72 adjudicated=72 matches=68 drifted=2 absent=2 unadjudicated=0 TWO WERE DRIFT AND ARE REGENERATED HERE: DESIGN.md this change's own authority edit docs/plans/realization-measurement-loop.md #9394 dissolved the ContainerRuntime nickname in the authority and the projection still named it The second is the headline: an authority-side divergence with a provenance I did not author, wrong since #9394, invisible to everything. It is also what proves the generator READS the authority -- a checker comparing a file to itself cannot produce it. THE OTHER TWO WERE NOT DRIFT AND ARE NOT REGENERATED. `docs/plans/v2-corpus-self-host.md` was DELETED ON PURPOSE by a295e17, whose entire subject is the ruling that the .dag carrier is the authority and the markdown should not exist; `docs/plans/import-namespace-program.md` has never existed at that path. An earlier revision of this branch regenerated both. That was wrong, and the way it was wrong is the most dangerous shape this phase can have: a drift gate makes whatever it adjudicates BINDING, so an absence that was inert before becomes a line-stop, and the cheapest way to move the line is to regenerate -- converting a dormant registry mistake into a standing obligation to recreate deleted files, green either way. Caught in review by warm-hawk-909. THE STALE HALF WAS THE REGISTRY ROW, NOT THE MISSING FILE, so the repair runs the other way: `gunbc.plan` gains `PlanProjection`, a plan declares whether its markdown is a committed artifact at all, and `artifact_commit_policy` asks the plan instead of answering `CommitRequired` for every slug. `PlanIsAuthorityOnly` carries the ruling that removed the projection, so the row cannot drift from its reason. It is NOT an exemption list and NOT a shrink: both plans stay rostered, stay generated, and still refuse if generation refuses -- only whether their bytes are expected on disk changes. The field is required, so a new plan cannot omit the decision. CONSTRUCTION, not another roster. The host resolves `generated_artifact_emit` once and asks it for BOTH the roster (`committed_generated_artifact_paths`) and each body, so an artifact added to `generated_artifact_registry` is enrolled with no edit to the host, and a path list in Rust -- the second roster DESIGN 3 forbids -- does not exist. Production precedes adjudication in the TYPE: every verdict is reached through the produced population, so "refused, having compared nothing" has no spelling outside the arms that carry no population. TWO COUNTS, NEVER ONE. A rostered member that reaches no verdict is reported and stops the line SEPARATELY from a drifted one. `0 drifted` over a population nothing asked about is the execution-provenance loss DESIGN names, and the discriminating unit test asserts exactly that: an outcome whose every verdict matched is NOT clean while one member is unadjudicated, and is still not reported as drift. READ-ONLY BY CONSTRUCTION: no write path, no flag that opens one. Installing a regenerated artifact stays `main_wet`'s job, because a gate that can also write its own subject is a gate whose green proves nothing. The bridge `claim_executor` had declared privately (`GeneratedArtifactPathBody`, `generated_artifact_ctx`, `generated_artifact_body_for_path`) is hoisted into `v1_compiler::cli_run::generated_artifact_boundary_host` and re-exported through `cli_run`, the way the regen and partition-crate producers already are, rather than copied -- two hosts asking one projection is the forked dispatch DESIGN 3 forbids. The new file is registered as seed-retained hand Rust in `v2.compiler.self_host.stage0_crate_layout`, beside `partition_crate_boundary_host`; its layout projections are regenerated. The refusal names a route that EXISTS, in one place (`GENERATED_ARTIFACT_PRODUCING_COMMAND`), because a stop whose only sanctioned move is unavailable does not stop the line, it launders a hand edit. EXECUTED, whole build lane, from binaries built out of this tree: regen first_generation_equal=true v2-emission EmissionCompleted blocking=0 partition-crates rendered=14 matches=14 generated-artifact rostered=70 adjudicated=70 matches=70 drifted=0 absent=0 unadjudicated=0 lane=build phases_run=4 failed=0 WHAT IS NOT CLAIMED: `main_wet` generates and writes one artifact at a time, so a refusal partway would install a mixed projection epoch. That is a mechanism read, not an executed receipt -- no generation refused here -- and it is left to its own PR with its own receipt rather than repaired on a hypothesis. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbai-bot Bot
pushed a commit
that referenced
this pull request
Aug 27, 2026
…nrol the whole committed generated-artifact population as a required CI phase `gunbc.generated_artifact_emit` `generated_artifact_body_for_path` is a pure projection over the three authorities `main_wet` folds -- the committed-artifact roster, `artifact_path`, and the single `artifact_generate` dispatch -- and it answers, for any repo-relative path, exactly what the tree ought to hold there. THE PRODUCER WAS NEVER MISSING AND NEITHER WAS THE WRITER. THE CHECKER WAS. (Premise correction from warm-hawk-909, who wrote the brief: the work item's title says no route REGENERATES these files, and that is false -- `tools.generated_artifact_gate` `main_wet` is a declared writer. Nothing here adds a second one; every repair below was installed by invoking that one.) From the 2026-08-15 floor cut until this change, the only route that ASKED the projection anything was `claim_executor`'s behavioural-receipt census, which asks only about paths of the form `src/v1/stage0/src/<mirror>` because its subject is emitted Rust mirrors. Every committed artifact that is not a Rust mirror -- `DESIGN.md`, `ROADMAP.md`, the workflow YAML, `.gitignore`, `.gitattributes`, the githooks, the plans -- was compared by nothing. DESIGN's own CI paragraph named the generated-artifact drift gates on the re-add queue that cut created; this is the first item taken off it. WHAT THE PHASE FOUND ON ITS FIRST EXECUTION, measured at 441ce5c (stated with its subject sha because the gate's whole purpose is to make this number zero, so it is not re-derivable from a later tree): rostered=72 adjudicated=72 matches=68 drifted=2 absent=2 unadjudicated=0 TWO WERE DRIFT AND ARE REGENERATED HERE: DESIGN.md this change's own authority edit docs/plans/realization-measurement-loop.md #9394 dissolved the ContainerRuntime nickname in the authority and the projection still named it The second is the headline: an authority-side divergence with a provenance I did not author, wrong since #9394, invisible to everything. It is also what proves the generator READS the authority -- a checker comparing a file to itself cannot produce it. THE OTHER TWO WERE NOT DRIFT AND ARE NOT REGENERATED. `docs/plans/v2-corpus-self-host.md` was DELETED ON PURPOSE by a295e17, whose entire subject is the ruling that the .dag carrier is the authority and the markdown should not exist; `docs/plans/import-namespace-program.md` has never existed at that path. An earlier revision of this branch regenerated both. That was wrong, and the way it was wrong is the most dangerous shape this phase can have: a drift gate makes whatever it adjudicates BINDING, so an absence that was inert before becomes a line-stop, and the cheapest way to move the line is to regenerate -- converting a dormant registry mistake into a standing obligation to recreate deleted files, green either way. Caught in review by warm-hawk-909. THE STALE HALF WAS THE REGISTRY ROW, NOT THE MISSING FILE, so the repair runs the other way: `gunbc.plan` gains `PlanProjection`, a plan declares whether its markdown is a committed artifact at all, and `artifact_commit_policy` asks the plan instead of answering `CommitRequired` for every slug. `PlanIsAuthorityOnly` carries the ruling that removed the projection, so the row cannot drift from its reason. It is NOT an exemption list and NOT a shrink: both plans stay rostered, stay generated, and still refuse if generation refuses -- only whether their bytes are expected on disk changes. The field is required, so a new plan cannot omit the decision. CONSTRUCTION, not another roster. The host resolves `generated_artifact_emit` once and asks it for BOTH the roster (`committed_generated_artifact_paths`) and each body, so an artifact added to `generated_artifact_registry` is enrolled with no edit to the host, and a path list in Rust -- the second roster DESIGN 3 forbids -- does not exist. Production precedes adjudication in the TYPE: every verdict is reached through the produced population, so "refused, having compared nothing" has no spelling outside the arms that carry no population. TWO COUNTS, NEVER ONE. A rostered member that reaches no verdict is reported and stops the line SEPARATELY from a drifted one. `0 drifted` over a population nothing asked about is the execution-provenance loss DESIGN names, and the discriminating unit test asserts exactly that: an outcome whose every verdict matched is NOT clean while one member is unadjudicated, and is still not reported as drift. READ-ONLY BY CONSTRUCTION: no write path, no flag that opens one. Installing a regenerated artifact stays `main_wet`'s job, because a gate that can also write its own subject is a gate whose green proves nothing. The bridge `claim_executor` had declared privately (`GeneratedArtifactPathBody`, `generated_artifact_ctx`, `generated_artifact_body_for_path`) is hoisted into `v1_compiler::cli_run::generated_artifact_boundary_host` and re-exported through `cli_run`, the way the regen and partition-crate producers already are, rather than copied -- two hosts asking one projection is the forked dispatch DESIGN 3 forbids. The new file is registered as seed-retained hand Rust in `v2.compiler.self_host.stage0_crate_layout`, beside `partition_crate_boundary_host`; its layout projections are regenerated. The refusal names a route that EXISTS, in one place (`GENERATED_ARTIFACT_PRODUCING_COMMAND`), because a stop whose only sanctioned move is unavailable does not stop the line, it launders a hand edit. EXECUTED, whole build lane, from binaries built out of this tree: regen first_generation_equal=true v2-emission EmissionCompleted blocking=0 partition-crates rendered=14 matches=14 generated-artifact rostered=70 adjudicated=70 matches=70 drifted=0 absent=0 unadjudicated=0 lane=build phases_run=4 failed=0 WHAT IS NOT CLAIMED: `main_wet` generates and writes one artifact at a time, so a refusal partway would install a mixed projection epoch. That is a mechanism read, not an executed receipt -- no generation refused here -- and it is left to its own PR with its own receipt rather than repaired on a hypothesis. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbai-bot Bot
pushed a commit
that referenced
this pull request
Aug 27, 2026
…nrol the whole committed generated-artifact population as a required CI phase `gunbc.generated_artifact_emit` `generated_artifact_body_for_path` is a pure projection over the three authorities `main_wet` folds -- the committed-artifact roster, `artifact_path`, and the single `artifact_generate` dispatch -- and it answers, for any repo-relative path, exactly what the tree ought to hold there. THE PRODUCER WAS NEVER MISSING AND NEITHER WAS THE WRITER. THE CHECKER WAS. (Premise correction from warm-hawk-909, who wrote the brief: the work item's title says no route REGENERATES these files, and that is false -- `tools.generated_artifact_gate` `main_wet` is a declared writer. Nothing here adds a second one; every repair below was installed by invoking that one.) From the 2026-08-15 floor cut until this change, the only route that ASKED the projection anything was `claim_executor`'s behavioural-receipt census, which asks only about paths of the form `src/v1/stage0/src/<mirror>` because its subject is emitted Rust mirrors. Every committed artifact that is not a Rust mirror -- `DESIGN.md`, `ROADMAP.md`, the workflow YAML, `.gitignore`, `.gitattributes`, the githooks, the plans -- was compared by nothing. DESIGN's own CI paragraph named the generated-artifact drift gates on the re-add queue that cut created; this is the first item taken off it. WHAT THE PHASE FOUND ON ITS FIRST EXECUTION, measured at 441ce5c (stated with its subject sha because the gate's whole purpose is to make this number zero, so it is not re-derivable from a later tree): rostered=72 adjudicated=72 matches=68 drifted=2 absent=2 unadjudicated=0 TWO WERE DRIFT AND ARE REGENERATED HERE: DESIGN.md this change's own authority edit docs/plans/realization-measurement-loop.md #9394 dissolved the ContainerRuntime nickname in the authority and the projection still named it The second is the headline: an authority-side divergence with a provenance I did not author, wrong since #9394, invisible to everything. It is also what proves the generator READS the authority -- a checker comparing a file to itself cannot produce it. THE OTHER TWO WERE NOT DRIFT AND ARE NOT REGENERATED. `docs/plans/v2-corpus-self-host.md` was DELETED ON PURPOSE by a295e17, whose entire subject is the ruling that the .dag carrier is the authority and the markdown should not exist; `docs/plans/import-namespace-program.md` has never existed at that path. An earlier revision of this branch regenerated both. That was wrong, and the way it was wrong is the most dangerous shape this phase can have: a drift gate makes whatever it adjudicates BINDING, so an absence that was inert before becomes a line-stop, and the cheapest way to move the line is to regenerate -- converting a dormant registry mistake into a standing obligation to recreate deleted files, green either way. Caught in review by warm-hawk-909. THE STALE HALF WAS THE REGISTRY ROW, NOT THE MISSING FILE, so the repair runs the other way: `gunbc.plan` gains `PlanProjection`, a plan declares whether its markdown is a committed artifact at all, and `artifact_commit_policy` asks the plan instead of answering `CommitRequired` for every slug. `PlanIsAuthorityOnly` carries the ruling that removed the projection, so the row cannot drift from its reason. It is NOT an exemption list and NOT a shrink: both plans stay rostered, stay generated, and still refuse if generation refuses -- only whether their bytes are expected on disk changes. The field is required, so a new plan cannot omit the decision. CONSTRUCTION, not another roster. The host resolves `generated_artifact_emit` once and asks it for BOTH the roster (`committed_generated_artifact_paths`) and each body, so an artifact added to `generated_artifact_registry` is enrolled with no edit to the host, and a path list in Rust -- the second roster DESIGN 3 forbids -- does not exist. Production precedes adjudication in the TYPE: every verdict is reached through the produced population, so "refused, having compared nothing" has no spelling outside the arms that carry no population. TWO COUNTS, NEVER ONE. A rostered member that reaches no verdict is reported and stops the line SEPARATELY from a drifted one. `0 drifted` over a population nothing asked about is the execution-provenance loss DESIGN names, and the discriminating unit test asserts exactly that: an outcome whose every verdict matched is NOT clean while one member is unadjudicated, and is still not reported as drift. READ-ONLY BY CONSTRUCTION: no write path, no flag that opens one. Installing a regenerated artifact stays `main_wet`'s job, because a gate that can also write its own subject is a gate whose green proves nothing. The bridge `claim_executor` had declared privately (`GeneratedArtifactPathBody`, `generated_artifact_ctx`, `generated_artifact_body_for_path`) is hoisted into `v1_compiler::cli_run::generated_artifact_boundary_host` and re-exported through `cli_run`, the way the regen and partition-crate producers already are, rather than copied -- two hosts asking one projection is the forked dispatch DESIGN 3 forbids. The new file is registered as seed-retained hand Rust in `v2.compiler.self_host.stage0_crate_layout`, beside `partition_crate_boundary_host`; its layout projections are regenerated. The refusal names a route that EXISTS, in one place (`GENERATED_ARTIFACT_PRODUCING_COMMAND`), because a stop whose only sanctioned move is unavailable does not stop the line, it launders a hand edit. EXECUTED, whole build lane, from binaries built out of this tree: regen first_generation_equal=true v2-emission EmissionCompleted blocking=0 partition-crates rendered=14 matches=14 generated-artifact rostered=70 adjudicated=70 matches=70 drifted=0 absent=0 unadjudicated=0 lane=build phases_run=4 failed=0 WHAT IS NOT CLAIMED: `main_wet` generates and writes one artifact at a time, so a refusal partway would install a mixed projection epoch. That is a mechanism read, not an executed receipt -- no generation refused here -- and it is left to its own PR with its own receipt rather than repaired on a hypothesis. THE SEED-GROWTH OBLIGATION FOR THE NEW HOST RUST (codex/gpt-5.6-sol, review 56588). The registration in `stage0_crate_layout` acknowledges the file; it does not reconcile it with DESIGN 7's shrinking-seed mandate, and that reconciliation is what the gate requires. `gunbc.generated_artifact_boundary_seed_growth` now carries it, joined into `gunbc.seed_growth_admission`'s roster: 19 declarations enumerated at identity grain rather than counted, the reason Rust is needed at all (the comparison is against BYTES ON DISK, a host effect the hermetic floor refuses by construction), the rejected alternative and why (running the existing gate through the interpreter in Wet mode makes the interpreter load-bearing for a NEW required phase while two lanes delete it, and would drag in `artifact_extra_valid`'s `ci_yml_parses` as a second unasked subject), the owning lane (`v1-hand-queue-drain`), and a trigger that names the capability rather than an artifact: delete all 19 when a modeled operation can read a committed file's bytes inside the required envelope. THE FOUR INHERENT METHODS BECAME FREE FUNCTIONS TO PAY THAT OBLIGATION HONESTLY. `std.decl_ref` offers `WholeDeclaration` or `NamedField` and neither names a method on an `impl` block, so every method would have been an item this roster could not cite -- growing exactly the uncitable-item class `gunbc.seed_growth_admission` counts. There is now no `impl` block in the file and zero of the 19 rows are uncitable. NET, STATED SO THE ROSTER IS NOT MISREAD AS A DIFF: three of the 19 (`GeneratedArtifactPathBody`, `generated_artifact_ctx`, `generated_artifact_body_for_path`) are DELETED from `bin/claim_executor.rs` in this same change, so the corpus-wide delta for those three is zero and only their home moved. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
gunbai-bot Bot
pushed a commit
that referenced
this pull request
Aug 27, 2026
…nrol the whole committed generated-artifact population as a required CI phase `gunbc.generated_artifact_emit` `generated_artifact_body_for_path` is a pure projection over the three authorities `main_wet` folds -- the committed-artifact roster, `artifact_path`, and the single `artifact_generate` dispatch -- and it answers, for any repo-relative path, exactly what the tree ought to hold there. THE PRODUCER WAS NEVER MISSING AND NEITHER WAS THE WRITER. THE CHECKER WAS. (Premise correction from warm-hawk-909, who wrote the brief: the work item's title says no route REGENERATES these files, and that is false -- `tools.generated_artifact_gate` `main_wet` is a declared writer. Nothing here adds a second one; every repair below was installed by invoking that one.) From the 2026-08-15 floor cut until this change, the only route that ASKED the projection anything was `claim_executor`'s behavioural-receipt census, which asks only about paths of the form `src/v1/stage0/src/<mirror>` because its subject is emitted Rust mirrors. Every committed artifact that is not a Rust mirror -- `DESIGN.md`, `ROADMAP.md`, the workflow YAML, `.gitignore`, `.gitattributes`, the githooks, the plans -- was compared by nothing. DESIGN's own CI paragraph named the generated-artifact drift gates on the re-add queue that cut created; this is the first item taken off it. WHAT THE PHASE FOUND ON ITS FIRST EXECUTION, measured at 441ce5c (stated with its subject sha because the gate's whole purpose is to make this number zero, so it is not re-derivable from a later tree): rostered=72 adjudicated=72 matches=68 drifted=2 absent=2 unadjudicated=0 TWO WERE DRIFT AND ARE REGENERATED HERE: DESIGN.md this change's own authority edit docs/plans/realization-measurement-loop.md #9394 dissolved the ContainerRuntime nickname in the authority and the projection still named it The second is the headline: an authority-side divergence with a provenance I did not author, wrong since #9394, invisible to everything. It is also what proves the generator READS the authority -- a checker comparing a file to itself cannot produce it. THE OTHER TWO WERE NOT DRIFT AND ARE NOT REGENERATED. `docs/plans/v2-corpus-self-host.md` was DELETED ON PURPOSE by a295e17, whose entire subject is the ruling that the .dag carrier is the authority and the markdown should not exist; `docs/plans/import-namespace-program.md` has never existed at that path. An earlier revision of this branch regenerated both. That was wrong, and the way it was wrong is the most dangerous shape this phase can have: a drift gate makes whatever it adjudicates BINDING, so an absence that was inert before becomes a line-stop, and the cheapest way to move the line is to regenerate -- converting a dormant registry mistake into a standing obligation to recreate deleted files, green either way. Caught in review by warm-hawk-909. THE STALE HALF WAS THE REGISTRY ROW, NOT THE MISSING FILE, so the repair runs the other way: `gunbc.plan` gains `PlanProjection`, a plan declares whether its markdown is a committed artifact at all, and `artifact_commit_policy` asks the plan instead of answering `CommitRequired` for every slug. `PlanIsAuthorityOnly` carries the ruling that removed the projection, so the row cannot drift from its reason. It is NOT an exemption list and NOT a shrink: both plans stay rostered, stay generated, and still refuse if generation refuses -- only whether their bytes are expected on disk changes. The field is required, so a new plan cannot omit the decision. CONSTRUCTION, not another roster. The host resolves `generated_artifact_emit` once and asks it for BOTH the roster (`committed_generated_artifact_paths`) and each body, so an artifact added to `generated_artifact_registry` is enrolled with no edit to the host, and a path list in Rust -- the second roster DESIGN 3 forbids -- does not exist. Production precedes adjudication in the TYPE: every verdict is reached through the produced population, so "refused, having compared nothing" has no spelling outside the arms that carry no population. TWO COUNTS, NEVER ONE. A rostered member that reaches no verdict is reported and stops the line SEPARATELY from a drifted one. `0 drifted` over a population nothing asked about is the execution-provenance loss DESIGN names, and the discriminating unit test asserts exactly that: an outcome whose every verdict matched is NOT clean while one member is unadjudicated, and is still not reported as drift. READ-ONLY BY CONSTRUCTION: no write path, no flag that opens one. Installing a regenerated artifact stays `main_wet`'s job, because a gate that can also write its own subject is a gate whose green proves nothing. The bridge `claim_executor` had declared privately (`GeneratedArtifactPathBody`, `generated_artifact_ctx`, `generated_artifact_body_for_path`) is hoisted into `v1_compiler::cli_run::generated_artifact_boundary_host` and re-exported through `cli_run`, the way the regen and partition-crate producers already are, rather than copied -- two hosts asking one projection is the forked dispatch DESIGN 3 forbids. The new file is registered as seed-retained hand Rust in `v2.compiler.self_host.stage0_crate_layout`, beside `partition_crate_boundary_host`; its layout projections are regenerated. The refusal names a route that EXISTS, in one place (`GENERATED_ARTIFACT_PRODUCING_COMMAND`), because a stop whose only sanctioned move is unavailable does not stop the line, it launders a hand edit. EXECUTED, whole build lane, from binaries built out of this tree: regen first_generation_equal=true v2-emission EmissionCompleted blocking=0 partition-crates rendered=14 matches=14 generated-artifact rostered=70 adjudicated=70 matches=70 drifted=0 absent=0 unadjudicated=0 lane=build phases_run=4 failed=0 WHAT IS NOT CLAIMED: `main_wet` generates and writes one artifact at a time, so a refusal partway would install a mixed projection epoch. That is a mechanism read, not an executed receipt -- no generation refused here -- and it is left to its own PR with its own receipt rather than repaired on a hypothesis. THE SEED-GROWTH OBLIGATION FOR THE NEW HOST RUST (codex/gpt-5.6-sol, review 56588). The registration in `stage0_crate_layout` acknowledges the file; it does not reconcile it with DESIGN 7's shrinking-seed mandate, and that reconciliation is what the gate requires. `gunbc.generated_artifact_boundary_seed_growth` now carries it, joined into `gunbc.seed_growth_admission`'s roster: 19 declarations enumerated at identity grain rather than counted, the reason Rust is needed at all (the comparison is against BYTES ON DISK, a host effect the hermetic floor refuses by construction), the rejected alternative and why (running the existing gate through the interpreter in Wet mode makes the interpreter load-bearing for a NEW required phase while two lanes delete it, and would drag in `artifact_extra_valid`'s `ci_yml_parses` as a second unasked subject), the owning lane (`v1-hand-queue-drain`), and a trigger that names the capability rather than an artifact: delete all 19 when a modeled operation can read a committed file's bytes inside the required envelope. THE FOUR INHERENT METHODS BECAME FREE FUNCTIONS TO PAY THAT OBLIGATION HONESTLY. `std.decl_ref` offers `WholeDeclaration` or `NamedField` and neither names a method on an `impl` block, so every method would have been an item this roster could not cite -- growing exactly the uncitable-item class `gunbc.seed_growth_admission` counts. There is now no `impl` block in the file and zero of the 19 rows are uncitable. NET, STATED SO THE ROSTER IS NOT MISREAD AS A DIFF: three of the 19 (`GeneratedArtifactPathBody`, `generated_artifact_ctx`, `generated_artifact_body_for_path`) are DELETED from `bin/claim_executor.rs` in this same change, so the corpus-wide delta for those three is zero and only their home moved. THE PROJECTION DECISION DESCENDS INSTEAD OF COLLAPSING (codex/gpt-5.6-sol, review 56610). The first cut of `PlanProjection` carried a `plan_projects_committed_markdown(p) -> Bool` predicate that matched the coproduct into true/false, and `artifact_commit_policy` then branched on the Bool. That is the predicate residue DESIGN 6 forbids, and it is also the "total at the level examined, blind one level down" shape one entry over: a second projection state would have had to pick an existing Bool rather than failing to compile at the decision. The predicate is DELETED and `artifact_commit_policy` matches `plan.projection` directly, so a new `PlanProjection` variant fails to compile exactly where the commit policy is decided. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
briansrls
pushed a commit
that referenced
this pull request
Aug 27, 2026
…a required CI phase — the writer exists and is run by hand, so the gap is enrolment, not a missing regenerator (#9415) * No route checked DESIGN.md or ROADMAP.md against their authorities: enrol the whole committed generated-artifact population as a required CI phase `gunbc.generated_artifact_emit` `generated_artifact_body_for_path` is a pure projection over the three authorities `main_wet` folds -- the committed-artifact roster, `artifact_path`, and the single `artifact_generate` dispatch -- and it answers, for any repo-relative path, exactly what the tree ought to hold there. THE PRODUCER WAS NEVER MISSING AND NEITHER WAS THE WRITER. THE CHECKER WAS. (Premise correction from warm-hawk-909, who wrote the brief: the work item's title says no route REGENERATES these files, and that is false -- `tools.generated_artifact_gate` `main_wet` is a declared writer. Nothing here adds a second one; every repair below was installed by invoking that one.) From the 2026-08-15 floor cut until this change, the only route that ASKED the projection anything was `claim_executor`'s behavioural-receipt census, which asks only about paths of the form `src/v1/stage0/src/<mirror>` because its subject is emitted Rust mirrors. Every committed artifact that is not a Rust mirror -- `DESIGN.md`, `ROADMAP.md`, the workflow YAML, `.gitignore`, `.gitattributes`, the githooks, the plans -- was compared by nothing. DESIGN's own CI paragraph named the generated-artifact drift gates on the re-add queue that cut created; this is the first item taken off it. WHAT THE PHASE FOUND ON ITS FIRST EXECUTION, measured at 441ce5c (stated with its subject sha because the gate's whole purpose is to make this number zero, so it is not re-derivable from a later tree): rostered=72 adjudicated=72 matches=68 drifted=2 absent=2 unadjudicated=0 TWO WERE DRIFT AND ARE REGENERATED HERE: DESIGN.md this change's own authority edit docs/plans/realization-measurement-loop.md #9394 dissolved the ContainerRuntime nickname in the authority and the projection still named it The second is the headline: an authority-side divergence with a provenance I did not author, wrong since #9394, invisible to everything. It is also what proves the generator READS the authority -- a checker comparing a file to itself cannot produce it. THE OTHER TWO WERE NOT DRIFT AND ARE NOT REGENERATED. `docs/plans/v2-corpus-self-host.md` was DELETED ON PURPOSE by a295e17, whose entire subject is the ruling that the .dag carrier is the authority and the markdown should not exist; `docs/plans/import-namespace-program.md` has never existed at that path. An earlier revision of this branch regenerated both. That was wrong, and the way it was wrong is the most dangerous shape this phase can have: a drift gate makes whatever it adjudicates BINDING, so an absence that was inert before becomes a line-stop, and the cheapest way to move the line is to regenerate -- converting a dormant registry mistake into a standing obligation to recreate deleted files, green either way. Caught in review by warm-hawk-909. THE STALE HALF WAS THE REGISTRY ROW, NOT THE MISSING FILE, so the repair runs the other way: `gunbc.plan` gains `PlanProjection`, a plan declares whether its markdown is a committed artifact at all, and `artifact_commit_policy` asks the plan instead of answering `CommitRequired` for every slug. `PlanIsAuthorityOnly` carries the ruling that removed the projection, so the row cannot drift from its reason. It is NOT an exemption list and NOT a shrink: both plans stay rostered, stay generated, and still refuse if generation refuses -- only whether their bytes are expected on disk changes. The field is required, so a new plan cannot omit the decision. CONSTRUCTION, not another roster. The host resolves `generated_artifact_emit` once and asks it for BOTH the roster (`committed_generated_artifact_paths`) and each body, so an artifact added to `generated_artifact_registry` is enrolled with no edit to the host, and a path list in Rust -- the second roster DESIGN 3 forbids -- does not exist. Production precedes adjudication in the TYPE: every verdict is reached through the produced population, so "refused, having compared nothing" has no spelling outside the arms that carry no population. TWO COUNTS, NEVER ONE. A rostered member that reaches no verdict is reported and stops the line SEPARATELY from a drifted one. `0 drifted` over a population nothing asked about is the execution-provenance loss DESIGN names, and the discriminating unit test asserts exactly that: an outcome whose every verdict matched is NOT clean while one member is unadjudicated, and is still not reported as drift. READ-ONLY BY CONSTRUCTION: no write path, no flag that opens one. Installing a regenerated artifact stays `main_wet`'s job, because a gate that can also write its own subject is a gate whose green proves nothing. The bridge `claim_executor` had declared privately (`GeneratedArtifactPathBody`, `generated_artifact_ctx`, `generated_artifact_body_for_path`) is hoisted into `v1_compiler::cli_run::generated_artifact_boundary_host` and re-exported through `cli_run`, the way the regen and partition-crate producers already are, rather than copied -- two hosts asking one projection is the forked dispatch DESIGN 3 forbids. The new file is registered as seed-retained hand Rust in `v2.compiler.self_host.stage0_crate_layout`, beside `partition_crate_boundary_host`; its layout projections are regenerated. The refusal names a route that EXISTS, in one place (`GENERATED_ARTIFACT_PRODUCING_COMMAND`), because a stop whose only sanctioned move is unavailable does not stop the line, it launders a hand edit. EXECUTED, whole build lane, from binaries built out of this tree: regen first_generation_equal=true v2-emission EmissionCompleted blocking=0 partition-crates rendered=14 matches=14 generated-artifact rostered=70 adjudicated=70 matches=70 drifted=0 absent=0 unadjudicated=0 lane=build phases_run=4 failed=0 WHAT IS NOT CLAIMED: `main_wet` generates and writes one artifact at a time, so a refusal partway would install a mixed projection epoch. That is a mechanism read, not an executed receipt -- no generation refused here -- and it is left to its own PR with its own receipt rather than repaired on a hypothesis. THE SEED-GROWTH OBLIGATION FOR THE NEW HOST RUST (codex/gpt-5.6-sol, review 56588). The registration in `stage0_crate_layout` acknowledges the file; it does not reconcile it with DESIGN 7's shrinking-seed mandate, and that reconciliation is what the gate requires. `gunbc.generated_artifact_boundary_seed_growth` now carries it, joined into `gunbc.seed_growth_admission`'s roster: 19 declarations enumerated at identity grain rather than counted, the reason Rust is needed at all (the comparison is against BYTES ON DISK, a host effect the hermetic floor refuses by construction), the rejected alternative and why (running the existing gate through the interpreter in Wet mode makes the interpreter load-bearing for a NEW required phase while two lanes delete it, and would drag in `artifact_extra_valid`'s `ci_yml_parses` as a second unasked subject), the owning lane (`v1-hand-queue-drain`), and a trigger that names the capability rather than an artifact: delete all 19 when a modeled operation can read a committed file's bytes inside the required envelope. THE FOUR INHERENT METHODS BECAME FREE FUNCTIONS TO PAY THAT OBLIGATION HONESTLY. `std.decl_ref` offers `WholeDeclaration` or `NamedField` and neither names a method on an `impl` block, so every method would have been an item this roster could not cite -- growing exactly the uncitable-item class `gunbc.seed_growth_admission` counts. There is now no `impl` block in the file and zero of the 19 rows are uncitable. NET, STATED SO THE ROSTER IS NOT MISREAD AS A DIFF: three of the 19 (`GeneratedArtifactPathBody`, `generated_artifact_ctx`, `generated_artifact_body_for_path`) are DELETED from `bin/claim_executor.rs` in this same change, so the corpus-wide delta for those three is zero and only their home moved. THE PROJECTION DECISION DESCENDS INSTEAD OF COLLAPSING (codex/gpt-5.6-sol, review 56610). The first cut of `PlanProjection` carried a `plan_projects_committed_markdown(p) -> Bool` predicate that matched the coproduct into true/false, and `artifact_commit_policy` then branched on the Bool. That is the predicate residue DESIGN 6 forbids, and it is also the "total at the level examined, blind one level down" shape one entry over: a second projection state would have had to pick an existing Bool rather than failing to compile at the decision. The predicate is DELETED and `artifact_commit_policy` matches `plan.projection` directly, so a new `PlanProjection` variant fails to compile exactly where the commit policy is decided. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Regenerate two plan projections the merge left behind `docs/plans/budget-tree.md` and `docs/plans/ci-humming.md` are projections of `gunbc.plans.budget_tree` and `gunbc.plans.ci_humming`, both of which git auto-merged when main came in. The regeneration ran, but its output was left UNSTAGED and `git commit` on a merge commits the index -- so the merge commit carried the merged authorities and the pre-merge projections. Caught by the `generated-artifact` phase this branch adds, on its own branch, naming both paths. That is the phase doing exactly what it exists for, on the class it exists for, against its own author. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * An empty roster reported clean: refuse it at the producer and at the predicate Found in review (codex/gpt-5.6-sol, review 56696), and it is a real defect in exactly the class this phase exists to close. `boundary_is_clean` required that every verdict matched and nothing was unadjudicated -- both VACUOUSLY TRUE of an outcome carrying zero members. So a run that adjudicated NOTHING rendered identically to a run that adjudicated seventy paths and found them all correct, and neither reporting branch in the phase body fired, so the line did not stop. That is the empty-observation narrow DESIGN names -- bottom-as-answer conflated with bottom-as-ignorance -- and it is strictly worse than the widen 5 already forbids: a widen is merely expensive, a narrow is silently uncovered. The PR body claimed "nothing was asked cannot appear clean". It could. CLOSED AT THREE LEVELS, none of them redundant with the others because each is reachable where the next is not: PRODUCER. `run_generated_artifact_boundary` refuses an empty roster with a typed cause. `committed_generated_artifacts` filters a module-scope literal, so empty is never a fact about the tree -- it means the projection or this bridge lost sight of the population, which is ignorance and must refuse. PREDICATE. `boundary_is_clean` no longer admits an empty population. This covers any outcome VALUE, including one a caller or a fixture builds by hand, which is the only boundary at which the state is still expressible now that the producer refuses it -- and therefore the only boundary at which its RED is authorable, which is what 4b requires before a check is worth writing. PHASE. The phase's verdict now derives from `boundary_is_clean` alone; the two reporting branches name WHAT went wrong, they no longer decide WHETHER anything did. A state neither branch happens to describe refuses with an explicit unnamed-cause line rather than falling between them. A second definition of clean beside the carrier's is the fork that lets a ledger and a gate disagree about one run. THE DISCRIMINATING RED IS AUTHORED AND CARRIES ITS POSITIVE CONTROL: `an_empty_population_is_not_clean_even_though_no_verdict_disagreed` asserts the empty outcome is not clean AND that a single matching member still is, so the conjunct is emptiness rather than a blanket refusal. It returns green under the previous code, which is the state it exists to forbid. Five tests pass. The seed-growth roster grows by one to 20 and its trigger is re-counted. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Regenerate DESIGN.md against main's recurring-failure-mode addition #9414 added a row to `gunbc.recurring_failure_mode` on main. That module is an input to `gunbc.design_document`, so the merge result's authority no longer matches the committed projection. WORTH RECORDING BECAUSE IT IS A PROPERTY OF THE PHASE AND NOT A ONE-OFF: CI adjudicates the PULL REQUEST MERGE COMMIT, not the branch head, so the phase compares the projection against the MERGED authorities. A branch that is internally consistent goes red the moment main lands an authority change under it -- which is correct, since the post-merge tree is what would sit on main -- and the remedy is always the same: merge and regenerate, never hand-edit. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Install the regenerated stage0 layout mirror: the merge resolution took main's copy, which predates this branch's host registration Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
gunbc had two container vocabularies. The good one — nine OCI modules under
dag/extdeps/container/oci, cited to the spec, closed coproducts with typed accept/reject — was consumed by nothing that ships. The one everything used wasgunbc.fleet_intent'sThis joins the first and deletes the second.
The nickname, and why five members were three concepts
ContainerRuntimefused container engines (Docker, Podman), a sandbox whose entire value is the isolation guarantee it adds (gVisor), and two companies that rent you a machine (Ubicloud, Google Cloud Run). Adding an engine and adding a supplier both widened one enum — the case DESIGN's external-upstream-decomposition section rules out with "adding Opera must not widen a generic browser-product enum".The dissolution splits it along the seams that were already there:
extdeps.container.engine— the agnostic hub. Defines what a container engine is and enumerates no product; adding one is a new file, never an edit here.extdeps.container.docker_engine— the one member that had a live consumer, as a cited product row (extdeps.vendor.docker_inc, andextdeps.softwarefor theVendor<Software>domain the tree lacked). Its Ubuntu apt distribution keeps its own module: how you install it is not what it is.product.fabric.isolationalready owns what a tenant is promised and deliberately names no mechanism.extdeps.cloud.ubicloud/product.supplier.Four members get no replacement row, and that is delete-first working rather than a loss: Podman, gVisor, Ubicloud and GcloudRun had zero constructors anywhere in the corpus, so nothing refused when they went. Inventing four uncited catalog rows to preserve the shape would have been re-invention, not decomposition.
The surface now carries strictly more truth than
Dockerdid.ExecutionSurface.container_engine: ContainerEngineDeployment?is the cited product plus the privilege mode this host runs it in — the property that decides whether a job escaping its container owns the machine, and the one thing the old enum could not say. srv1 runs rootless. A mode the product does not declare yields no deployment, not a surface asserting one.The customer-supplied image
product.fabric.customer_imageis the first executing consumer of the OCI model. ACustomerSuppliedImageis a reference, a manifest and a configuration;admit_customer_imagefolds it against anExecutionTargetand returns admitted-or-a-typed-cause.The isolation mechanism is not in that file, and its absence is the point.
CustomerSuppliedImagehas no field naming a runtime or a boundary and no constructor that could carry one — a tenant cannot select the mechanism because there is nowhere to put the selection. The mechanism arrives on the target side, chosen by us.New in extdeps:
extdeps.container.oci.reference, because nothing modelled how a party refers to an image — the only spelling available was a String. It carries the distribution-spec grammar (path-component separators enumerated exactly:.,_,__,-+, soa..banda___brefuse) and both identifier arms including the mutable one. A tag is a real thing the spec defines; refusing to run one is policy, and policy in an extdeps module is a layer inversion. The spec says what may be written;product.fabric.customer_imagesays what it will accept.The refusal that justifies the join module existing at all is
LayerCountDisagreement. image-spec requiresrootfs.diff_idsto correspond one-for-one with the manifest's layers;accept_image_manifestsees only the first list andaccept_image_configurationonly the second, so each accepts a pair that disagrees — which is what a substituted layer looks like. Only the join sees it.Green by execution, with discriminating reds
dag/test/claim/customer_image_admission_witness_test.dagdrives the real fold. The target is the real fleet (fleet_container_execution_target()— architecture read from srv1's declared Ampere CPU, engine from the surface), not a target authored to make the test pass, so the amd64 refusal is a claim about what this fleet would actually do. Each refusal case differs from the admitted case in exactly the fact its refusal names.A fixture that cannot be built returns
Absentand every witness fails on it rather than passing vacuously.Measured, not asserted —
claim_batch --claim-runover the 13 rows, all PASS, and the entry closure compiles with 0 blocking diagnostics. Re-derive with:The reds were executed, not assumed. Three separate deletions in the admission fold — the layer-count join always agreeing, the digest-pin test skipped, the architecture comparison skipped — each turned exactly one witness red and left the other twelve green. Nothing agrees with the fold's shape instead of testing its decision, and no single defect is reported three times. The procedure is recorded in the witness module so it can be re-derived rather than trusted.
What the first executing consumer immediately found
image_config_entrypointwas written asmatch c.config { null => [] ; cfg => match cfg.Entrypoint { ... } }. The bare arm binds the Optional, not its payload, so the inner field read refuses at runtime withNoSuchField { type_name: "Optional", field: "Entrypoint" }. It typechecked, it had witnesses, and it was wrong — surfaced the first time anything called it.image_config_first_exposed_portandimage_config_has_exposed_portcarried the identical defect and are repaired in the same change rather than left for the next consumer.That is the point of the caution in the brief, arriving on schedule: a join that only typechecked would have reproduced the condition it was fixing.
Named residue, not claimed closed
IsolationBoundaryinfleet_intentstill describes our own surface besideproduct.fabric.isolation's guarantee vocabulary. That is a separate question and is untouched here.KernelFamily/Osfork is compiler-enforced and could not be bridged. An image config'sosisextdeps.toolchain.typesOs; aComputeHost's surface carriesstd.os.typesKernelFamily. Any module importing both is refused:variant 'Linux' appears in both 'Os' and 'KernelFamily'. So the bridging match cannot be written anywhere. I did not route around it — the target OS is stated by the caller in the vocabulary the image speaks, the mismatch still refuses loudly, nothing widens silently, and the residue is named ingunbc.fleet_containerwith the exact diagnostic. Dissolving that fork is a real change and is not this one.