Repository navigation
The emitter declares the population it produced: one at-rest authority for which stage0 .rs files it owns - #8696
Merged
Conversation
added 7 commits
August 20, 2026 22:08
…fore adjudication
…ib.rs and emit_rust
This was referenced Aug 21, 2026
Merging main added `extdeps_languages_rust_derive_contracts` to the emitted population, so the committed manifest no longer equalled what the emitter declares and `--required-regen` refused with `generated surface drift: emitted_population.rs`. The candidate tree is installed verbatim (one added line, diff-verified against `target/stage0-regen-candidate/src/emitted_population.rs`); nothing here is hand-authored. This is the artifact reporting its own staleness on the first main merge after it landed, which is what it exists to do. Co-Authored-By: Claude Opus 5 <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.
The emitter declares the population it produced
v1.compiler.emit_rusthas the complete emitted population in hand at exactly one point, as avalue:
And then discarded it. Every consumer downstream rebuilt that fact from whatever residue it
could see — the
// Generated by v1 compilerbanner, the complement of the crate-layout claim,a directory listing,
lib.rs. Those reconstructions agree until they drift, which is when theyare load-bearing. #8674 deleted a producerless roster and replaced it with one such
reconstruction; the rung drop it declared exists because none of them can separate the emitter
produces this from nobody registered this.
This PR writes the fact down.
src/v1/stage0/src/emitted_population.rsis emitted by theemitter, from
files, listing every path it produced.lib.rsis not this fact and never was. It is one projection of the same value — thetop-level
pub modblock of one crate — which is why nine live stage0 modules are absent fromit (reached by
modfrom a parent, by cross-crate#[path], or by a non-pub mod). Themanifest is a second projection, and a total one. That measurement is wise-boar-649's and it is
what killed the
lib.rs-as-manifest design before it was built.Declared unfiltered
Every path in
files, not "the generated ones". Consumers cut it to their own question(
required_regen_hostdrops non-.rsand hand-maintained; the lifecycle scaffold will want adifferent cut). Filtering at the write would bake one consumer's question into the fact and
guarantee the next consumer reconstructs — which is the failure this ends.
The manifest lists itself, because the emitter does produce it. That is a fixed point, not a
circularity: the content is a function of the paths, and the manifest's own path is known
before its content is rendered.
Why it is a
.rsof comment lines, and why that is not debrisThis shape is load-bearing in both directions, and both halves were established by execution.
Comments, because it must be Rust. Every member of the compared population is
rustfmt-normalized before its digest is taken. An earlier revision made the manifest a
.txtand named it in the membership predicate as an exception; the gate refused it, located:
The compared population is Rust-shaped end to end, so an artifact that wants its gating has to
be Rust. As a
.rsit enterscommitted_generated_basenamesandgenerated_basenames_from_emitwith nothing named and no exception — population check,drift comparison, tree digest and candidate verification all cover it because it is a
.rsunder the stage0 root. A comments-only file is also already a rustfmt fixed point, which is the
property DESIGN's two-consumer rule demands of any artifact two consumers normalize.
cargo fmt --all --checkis clean on it.Not a
const &[&str], because recovering one requires parsing Rust. The read side issplit-on-separator then strip a literal prefix — no Rust grammar involved. A generated const
would put a Rust parse back on the read path, which is exactly the class #8690 deleted four
hours ago (
cssl_assemble's seedlib.rsoracle). The write isprefix ++ pathjoined by theseparator; the read is split-then-strip. One grammar, both directions.
Deliberately not a module. It is appended to the emitted file list after
lib.rsisrendered, so no
pub modnames it and nothing compiles it.Dissolution is declared on the carrier: when the compared population becomes medium-agnostic
— when the comparison normalizes by declared medium rather than assuming Rust — the manifest
becomes the line-delimited text it wants to be and the
.rsgoes with it. Until then theextension is load-bearing, and "cleaning it up" into a const is a silent regression.
The gate needs no new path
generated_basenames_from_emitandcommitted_generated_basenameseach carried their owncopy of the
.rs-and-not-hand-maintained membership rule — two readers of one fact, sittinginside the file whose job is detecting that class. They now share
is_compared_generated_basename. The manifest is admitted by the rule rather than exceptedinto it, so there is no second gate for anyone to forget to keep enrolled.
The basename has one authority
gunbc.stage0_emitted_population_manifestis a leaf module holding the basename, line prefixand separator. The emitter writes target-relative and the observation will read
repository-relative, so only the parts that are genuinely one fact are shared — hoisting a whole
path would force one end to hold a path in a space it does not speak. Without it the artifact
would have two names for one file, which is the nicknaming failure the manifest exists to end.
Convergence: stable by round 3, fixed point verified
Measured on BuildBuddy, install-and-rebuild to stability:
Two rounds of install, no rounds of propagation, and the distinction matters for whoever
edits
emit_rustnext. Rounds 1 and 2 each introduce one genuinely new emitted file, and #8671'srefusal names one class at a time — that is the sanctioned first-mirror path doing its job, not
the mirror chasing itself. The content never propagated: the binary built from the round-3
mirror emits that same mirror. That is why this differs from #8652/#8677, where main sat
mid-convergence across two PRs: #8614 changed how modules render, so every mirror moved and
the movement re-entered the compiler through its own mirror. This change alters what the
emitter produces, not how it renders, so the fixed point is reached as soon as the mirror
carrying the new function is installed.
This PR is built on #8671 (
666f984ca7), which re-derived the first-mirror producer so thecandidate tree is written before adjudication. An earlier revision of this branch worked around
its absence with committed placeholders; that scaffolding is deleted, not left standing.
Behavioral receipt: EQUIVALENT over 36 derived calls
This PR is the first non-zero selection the per-PR behavioral receipt (#8657) has made, so the
composition — select changed authority → compile candidate → run a derived call corpus against
the committed seed → verdict — executed end to end here for the first time:
The denominator is quoted with the verdict deliberately: this change adds a projection function
and appends one element to the emitted file list, so nothing in the 36 should have moved and
nothing did — but 598 functions are refused as non-derivable (unbounded
Stringdomains,Nodeimport-closure gaps) and the equivalence says nothing about them.The
receiptphase is nevertheless RED, and not because of anything in this diff. The otherselected authority is
gunbc.stage0_emitted_population_manifest— the three-data-row leafmodule this PR adds — which declares zero functions, so there is no corpus to derive and the
mechanism refuses rather than reporting equivalence over zero calls. That refusal is correct as a
statement about coverage; the error is one level up, in selection: a module with no declared
functions has no behaviour that could diverge, so it belongs in
excluded=with a typed reasonrather than being selected and then refused. Measured blast radius: 533 of 3740
.dagmodules(14%) declare zero functions, including core substrate — any diff touching any of them
hard-fails required CI with no author-side remedy short of a model change.
Converting the three
datarows to zero-argfns would green the phase in minutes — zero-argfunctions are exactly the
exhaustive(|domain|=1)shape the 36 derived calls are made of — andthat is precisely why it is not done here: a model change made solely to satisfy a gate, with no
reader benefit and no modelling argument, is the workaround class DESIGN §5 names as a line-stop
signal rather than a landing state. The selection defect is routed to the mechanism's lane.
The manifest paid for itself before it had a consumer
Two independent numbers over the same population, which nobody had before:
Those 35 are exactly
HAND_MAINTAINED_STAGE0_FILES(36) minus one. The single residue ismain.rs: the crate-layout authority claims it as hand-maintained, and the emitter emits it.That is not a defect this PR introduces or fixes.
required_regen.dagalready notes"hand-maintained DRIFT is expected on a clean tree (main.rs and known emitter gaps)" — and that
sentence is the finding. The emitter produces a
main.rsthat differs from the committed one,and membership in
HAND_MAINTAINED_STAGE0_FILESis what stops the difference from being seen.So it is not merely a not-compared list wearing the name of a hand-authored list: it is a
suppressed drift with no counter — a known divergence between authority and artifact, held
quiet by a switch spelled as an authorship claim. Nothing counts it, nothing reports it, its
frequency is zero by construction, and so it can never rank for repair.
The remedy is not to drop
main.rsfrom the list, which would turn the drift red with no fixavailable; it is to split the two facts — what is hand-authored, and a separate counted,
declared set of known emitter gaps with per-entry triggers. That is a separate subject with
separate consumers and it is being dispatched as its own lane, not carried here.
This is the manifest's first dividend, and it arrived before the manifest had a consumer. A
real divergence between an authority and the artifact it claims became visible on the day the
declaration landed, using no new machinery — just two independent numbers over one population,
which nobody could take before. Independently corroborated from the other direction:
main.rscarries the emitter's own
// Generated by v1 compilerbanner while sitting on thehand-maintained roster.
What is deliberately NOT here
The consumer wiring:
RustManifestObservedgaining the emitted population,gunbc.stage0_rust_source_lifecycle_scaffold's derivation switching onto it, the two REDcontrols returning to a direct-child subject, and #8674's declared rung drop deleting. That
is 30 constructor sites across 13 files, each a witness fixture that must state what emit
population it assumes, and it does not belong in the same diff as a regenerated mirror.
The drop block stays standing until a production path reads this manifest. A carrier that
can receive the emit population is not the carrier having it; deleting the block now would
leave green controls implying a closure that does not exist. It is the only thing currently
telling the truth about that population, and it keeps telling it until the follow-up lands.
dashboard node adhoc-03fccc45-ac3