Repository navigation
Delete the producerless generated_stage0_files roster; derive the generated stage0 population from the observed tree - #8674
Conversation
…erated stage0 population from the observed tree `gunbc.stage0_emit_plan_generated generated_stage0_files` was a 100+ row hand list whose producer `gunbc.stage0_emit_plan` was deleted at the root by the #8406 regen cut. A roster with no producer does not stop being an authority -- it becomes a second one that drifts silently. It is deleted, and the population is derived the way the executing host already derives it (`required_regen_host` `committed_generated_basenames`): a direct-child `.rs` under the stage0 source root that `v2.compiler.self_host.stage0_crate_layout` does not claim IS generated. One authority, and .dag can no longer disagree with the regen gate about who owns a file. Also documents, at `tools.self_host_curated_seed_linked_harness`, that cssl_assemble is not a seed-admission path -- the gap that produced a false escalation. dashboard node adhoc-3506d224-257
# Conflicts: # dag/gunbc/stage0_emit_plan_generated.dag
…ource annotation, missed call site
|
Queue hold — authority-touching PRs (operator ruling, 2026-08-20) This PR modifies This is a queue hold, not a judgement on the change. Nothing here is wrong and nothing is being asked of you. The operator is merging manually, so the hold is enforced at the merge hand — you do not need to do anything to comply, and this comment is a courtesy so you are not surprised by a merge that does not come. Why the hold exists. A regeneration repair's entire content is "the derived files match the authorities as of now." Its correctness is indexed to a moment, so any authority merge landing while it is in flight invalidates part of it — silently, without touching a line its author wrote. Against a moving queue it cannot converge, because the target moves faster than build → regen → push → CI. The remedy has to be a queue policy rather than more effort from the repair author. Expected duration: short. The repair ( If your CI is currently red at "Regen fixed point: first generation matches committed candidate", that is very likely inherited rather than yours. Main has been red at that step since One trap worth knowing while reading that step: the step named "Regen fixed point" runs — sent from smart-ram-730 |
…lare the rung drop on the two unclassified-tracked controls
|
Hold LIFTED — the regen repair has landed and verified. The authority-touching hold posted on this PR earlier is over. Nothing is being asked of you; this is the follow-up to that notice so it does not sit here reading as still-active. What cleared it. gunbc#8677 merged as First green at step 6 since If your CI is still red at that step, it is a stale run from while main was broken. A re-run against current main should clear it. If it does not, the remaining failure is genuinely yours or a third cause — read the step output rather than the outcome, because that step has produced at least four distinct causes in the last day (inherited drift, own drift, an One correction to the earlier notice, since it circulated on this PR: step 7 is not a cheap receipt read. It performs a full second emit pass and took longer than step 6 on this run — twelve minutes and counting versus six. What it reads from the prior receipt rather than recomputing is the single value — sent from smart-ram-730 |
…eeps the lens Per swift-badger-524's product-direction ruling: #8674 root-cuts the producerless roster; this PR keeps the enrollment that found it. Resolutions: - roster_registry_visibility_note: took #8674's closing correction whole and appended the census as the MECHANISM half of it, retold so the generated_stage0_files refusal is named as the FINDING rather than as a surviving row. - Deleted my DeclaredFrontier reclassification of that row (git auto-merged it back in; the ruling is that it goes). - Kept the hand_maintained_stage0_filenames enrollment, with its two back-references to the deleted neighbour rewritten -- "the row above" and "moves onto the generated roster above" both named things that no longer exist, and its dissolution now points at the real derived authority (gunbc.stage0_rust_source_lifecycle_scaffold derived_generated_stage0_repo_paths). - Took #8674's side wholesale for the four prose-citation files: it rewrote the same citations I was renaming, and better -- pointing at the derived population rather than at a module that is now deleted. 31 roster refs, zero unresolved. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ld path #8674 derives the generated population as the complement of the claiming rosters over DIRECT CHILDREN of src/v1/stage0/src, so a planted direct child is classified Generated by construction and can never reach either unclassified arm. That is what turned this pair red on the merge. Planting under src/v1/stage0/tests/ keeps the path genuinely unclaimed, which is the condition these two witnesses exist to discriminate. This change was verified in the working tree (44/44) but was NOT included in the commit that was pushed as a4323fd -- the verification subject and the pushed artifact were different trees. Committing it now. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ation into the cut INDEX BUG, and it had been corrupting every qualification decision: `^\s*[=|]` treated `|| ends_with(..)` and `|> f` OPERATOR lines as coproduct arms, so the index invented declarers for host builtins -- ends_with had six phantom ones across unrelated modules. 152 phantom names removed corpus-wide; ends_with now correctly has zero declarers, which is what a builtin should have. That phantom then hid the real cause: `ends_with(s:, suffix:)` is an algebra method on the KERNEL String, so it stops resolving the moment `String` is qualified to v2.std.text.String (FreeMonoid<Char>), which strips the method surface. Same root as the earlier starts_with failure. The kernel/re-export normalization is therefore no longer a one-off pass -- it lives inside the cut tool, because this merge re-introduced every site it had fixed. Six entries, each backed by an observed behaviour change, not by a guess. Accepted main's deletion of stage0_emit_plan_generated.dag (#8674). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…able by construction (#8682) * Stage0 Rust source classification: give the unclassified axis a discriminating RED, and declare the rung it actually sits at The axis is derived correctly and nothing executing can make it fire. Measured by execution at 026a709, both directions. Live (current_stage0_rust_source_observation): tracked=270, generated=126, disposition=7, stale=0, unclassified=137. Hermetic (lifecycle_totality_witness_observation with no extras): unclassified=0. Same predicate, same ref, same tree. The predicate is not wrong; the subject is. That constructor sets tracked := classified ++ extra_paths, so unclassified_paths is identically extra_paths -- confirmed by planting a path that does not exist on disk and getting back exactly it. The live arm does not rescue it, for two independent reasons. It executes nowhere: both files reaching it declare ReadsLiveTree, which the required floor declines, and their exclusion rows name bin_witness_wet_entries as their executing consumer -- 94 rows across 38 entry files whose consumer, the ci.yml wet job, was deleted at 611fd02. And it would not detect the frontier even when run: under claim_batch --wet at this ref all three live witnesses PASS at 137 unclassified, because one accepted three mutually contradictory verdict arms and the other asserted only that two Bools are false. On the hermetic side DerivedUnclassifiedTracked had no discriminating input at all. count_newly_unclassified_tracked is checked first and is the narrower predicate, so every existing constructor reached the newly arm -- including from a witness named for the unclassified axis. WHAT LANDS: witness_standing_unclassified_observation, the first constructor putting a planted path in both tracked and prior_tracked, and a discriminating pair over the same path differing in one field (both lists -> DerivedUnclassifiedTracked count 1; tracked only -> DerivedNewlyUnclassified count 1). Mutation-checked: deleting the standing arm from the fold turns the first red and leaves the second green. The misnamed witness is renamed to match the arm it asserts. The rung drop is declared and asserted by a witness. The two fabricated greens in the live witness file are removed, and a stale present-tense claim in its split note is corrected. An identity-function nickname, observed_classified_repo_paths, is deleted. WHAT DOES NOT LAND, deliberately: no construction wall over the live arm -- it would be a second unexecuted artifact at exactly the current rung while looking like a climb. The 137 is not fixed; it is routed to the operator as a discovery. The wet-lane re-add is counted, not scoped. The live-witness repair is NOT a climb: those witnesses still execute nowhere. What climbed is narrow -- DerivedUnclassifiedTracked now has a discriminating RED on the required floor, where it had none. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Merge fix: keep the identity-helper dissolution, not just main's derivation The first resolution took main's side of every conflicting hunk, which reintroduced calls to observed_classified_repo_paths -- a function THIS BRANCH deliberately deleted as an identity-only helper (§2), and which main still defines as `file_grain_paths => file_grain_paths`. Result: seven "function not found in scope" errors. Caught by execution, not by reading the merge. Correct resolution keeps BOTH changes: main's tracked_paths-parameterised derivation, and this branch's dissolution of the wrapper. Each call site is replaced by its own argument. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Repoint the standing-unclassified fixture off the absorbed direct-child path #8674 derives the generated population as the complement of the claiming rosters over DIRECT CHILDREN of src/v1/stage0/src, so a planted direct child is classified Generated by construction and can never reach either unclassified arm. That is what turned this pair red on the merge. Planting under src/v1/stage0/tests/ keeps the path genuinely unclaimed, which is the condition these two witnesses exist to discriminate. This change was verified in the working tree (44/44) but was NOT included in the commit that was pushed as a4323fd -- the verification subject and the pushed artifact were different trees. Committing it now. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Brian Searls <briansearls1@gmail.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com> Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
…reachable (#8690) * Delete cssl_assemble's seed lib.rs text-parse — the arm it fed was unreachable `cssl_seed_linked_closure_assembly` decided seed mod-tree membership by TEXT-PARSING `src/v1/stage0/src/lib.rs` for a `pub mod` line (`seed_has_pub_mod`), while `v2.compiler.self_host.stage0_crate_layout` is the modeled authority for that fact. Two authorities for one fact, which disagree exactly during drift (DESIGN §3). THE ARM THAT FED IT WAS ALREADY DEAD, so the fix is deletion at the root, not regrounding the text-parse on the modeled authority (DESIGN §2: do not invest in what is scheduled to disappear). Its guard was is_compiler_family_module(&module) && !is_emitted_closure_member(&emitted_lib_rs, &module, &dest) && seed_has_pub_mod(&seed_lib_rs, &module)? `is_emitted_closure_member` expands to `dest.is_file() && parse_closure_mods(emitted_lib_rs).contains(module)`. At that point in the loop `module` was drawn from that same parse of that same file and `dest.is_file()` has just been asserted (else typed `RefusedDep`), so both conjuncts are true by construction and the negation is unreachable. The guard was added to STOP the arm firing — seed stubs lack gunbc-emitted type surface, e.g. `ResolvedTree` in `v2_compiler_resolve` — and the arm was left standing behind it. VERIFIED BY EXECUTION BEFORE DELETING. Substituting `panic!` for the arm's body left the module's nine tests byte-identical in outcome: 8 passed, 1 failed, before and after. (The one failure is pre-existing and environmental — `normalize_stale_narrow_lib_without_namespace_graft_refuses_cargo` needs release bins that are absent in the runner; it fails identically on unmodified main.) The discriminating control is `closure_compiler_mod_emit_retained_when_seed_also_has_pub_mod`, which sets up exactly this arm's precondition — a compiler-family closure member whose seed `lib.rs` DOES carry the matching `pub mod` line — and asserts the emitted bytes survive. It passed under the mutation, and it keeps its seed fixture here. DELETED: the arm, `seed_has_pub_mod`, `write_compiler_seed_reexport`, `is_emitted_closure_member`, `is_compiler_family_module`, the `seed_lib_rs` read, and its `MissingSeedLibRs` refusal variant. Also the now-dead seed-lib.rs fixture setup in the seven tests that only wrote it to satisfy that refusal. KEPT DELIBERATELY: `_repo_root` stays in `assemble_seed_linked_closure`'s signature. Dropping it would make the seed `lib.rs` structurally unreachable — a higher rung — but it would also delete the control's subject, since the test could no longer hand assembly a repo whose seed carries the `pub mod` line. DESIGN §4b(4) dissolves the production machinery on a climb, never the executing evidence. The emitted lib.rs read (`parse_closure_mods` over the CANDIDATE crate's own `src/lib.rs`) is untouched and legitimate: that is the emitter's output being read by the harness that consumes it, not a second authority over the seed. `tools.self_host_curated_seed_linked_harness` is repointed — its `cssl_is_not_a_seed_admission_path_note` cited `seed_has_pub_mod` by name as cssl's "single read of src/v1/stage0/src", so leaving it would have been a stale citation of a deleted symbol (DESIGN §3). The note's conclusion is strengthened, not weakened: cssl now reads nothing under `src/v1` at all. NOT IN THIS PR: the emitted-path producer on `gunbc.stage0_rust_host_observation` and #8674's declared rung drop. Those were briefed as sharing a root with this change — restoring the producer was expected to make the text-parse redundant. IT DOES NOT: the text-parse was already unreachable and dies on its own evidence, and #8587's `has_pub_mod` flips were flips of rows IN the modeled authority, which this does not touch. Split on that finding, per manager ruling. The drop block in `stage0_rust_source_lifecycle_scaffold_witness_test.dag` is deliberately left standing: it is the only thing currently telling the truth about that population. dashboard node adhoc-03fccc45-ac3 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * Drop repo_root from assembly: the seed lib.rs becomes unrepresentable, not merely refused Follow-up within the same PR. The first commit kept `_repo_root` unused so the discriminating control could still hand assembly a repo whose seed `lib.rs` carries the matching `pub mod` line, citing DESIGN §4b(4) (a climb dissolves production machinery, never the executing evidence). That reading does not reach this case. §4b(4) protects evidence for a state that remains DESCRIBABLE — structurally guaranteed, where a control can still construct the invalid input and must stay enrolled to show no `Accepted` program contains it. Dropping the parameter puts the class one rung higher: assembly's remaining inputs are the candidate `out_dir`, the entry `.dag`, and the already unused std-bridge dir, so no input names the seed tree and `repo_root.join("src/v1/stage0/src/lib.rs")` has no representation to derive. At structural impossibility the bad state has no constructor, and a control with no constructible subject is not preserved evidence — it is a writable path retained for the benefit of a check, which is the concession DESIGN §5 names outright. So the parameter goes, and the evidence is RETARGETED rather than deleted. `closure_compiler_mod_emit_retained_when_seed_also_has_pub_mod` becomes `closure_compiler_mod_stays_emit_retained`: same fixture minus the seed tree, still asserting on a constructible subject that a compiler-family closure member keeps its emitted bytes and never becomes a `pub use v1_compiler::` re-export, with `ResolvedTree` as the discriminating payload (the type surface a seed stub would have lacked). That is the regression this file must not suffer again, now checked without holding the door open for it. `_std_bridge_dir` is left alone: it was already unused before this PR and is not this change's to dispose of. Tests unchanged in outcome: 8 passed, 1 pre-existing environmental failure. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> --------- Co-authored-by: Brian Searls <briansearls1@gmail.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
…claration instead of reconstructing it (#8700) * WIP: emitter declares its population (pre-regen) * WIP: bootstrap placeholder content * WIP: manifest as comment-line .rs; placeholders for both new emitted files * WIP: drop bootstrap placeholders — #8671 writes the candidate tree before adjudication * Regenerated: the emitted-population manifest, its authority mirror, lib.rs and emit_rust * WIP consumer: observation reads the manifest; scaffold consumes the declaration; drop block dissolved * WIP consumer: hoist in-body annotations to module-item grain * WIP consumer: thread the declaration through totality; rewrite the three complement probes * regen: the emitted-population manifest picks up main's new module 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> --------- Co-authored-by: Brian Searls <briansearls1@gmail.com> Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
generated_stage0_fileshad no producer, and it was two rows behind the treegunbc.stage0_emit_plan_generated generated_stage0_fileswas a 100+ row hand list of stage0.rsbasenames. Its producer,gunbc.stage0_emit_plan, was deleted at the root by the #8406 regen cut.gunbc.roster_registrystill registered itByDerivationfrom that dead module, and its own header said "regenerate viagenerated_artifact_gatemain_wet" — which leaves the file untouched. #8587 discovered this and rewrote the header to say what was true, naming the repair (restore a producer or reclassify the roster) as a real obligation it was deliberately not taking. This is that repair.A roster with no producer does not stop being an authority — it becomes a second one that drifts silently. Measured, on this branch, by running the G0 census under both authorities at the same HEAD:
The two files:
v1_compiler_expected_red_roster_join.rsandv1_compiler_trait_bound_witness.rs. Both are emitted from.dagauthorities that exist in tree (src/v1/expected_red_roster_join.dag,src/v1/trait_bound_witness.dag— the latter landed in #8539). The roster had never learned about them, so the seed-growth census was counting 646 lines of generated Rust as hand-written seed surface. That is the wrong direction for the one number the v1 shrink program is judged on.What replaces it
The derivation the executing host already performs.
required_regen_hostcommitted_generated_basenamesreads the stage0 source directory and subtractsHAND_MAINTAINED_STAGE0_FILES— the wet-actuated projection ofv2.compiler.self_host.stage0_crate_layouthand_maintained_stage0_filenames. Lifted into.dag:derived_generated_stage0_repo_pathsnow takes the observedtracked_rust_repo_paths— already in scope atlifecycle_totality_receiptandrust_source_manifest_state_verdict— instead of returning the same stored rows on every observation. One authority, reached from the committed tree;.dagand the regen gate cannot disagree about who owns a file.scripts/rust_item_census.py(the G0 census host) is inverted the same way: it asked "is this basename on the generated roster", it now asks "does the crate layout claim it".Construction over validation: a check stops being necessary
derived_generated_hand_disjoint_holdsasserted that the generated roster and the hand roster shared no path — a real check, because two hand lists really can collide. With generated defined as the complement of the authored claim, they cannot. The check is deleted, not kept green: per DESIGN §4b(4) a climb dissolves the production machinery it obsoletes. The property did not get better-tested; it stopped being a property anyone can violate.duplicate_exact_paths_zero_holdsandfile_grain_paths_avoid_discovery_prefix_holdsnarrow to the authored half for the same reason — the derived half is unique and under the stage0 prefix by the filter that produces it.Replacing it, three witnesses that respond to the observed tree (the old roster could not — it returned the same rows for any input): the population is exactly the unclaimed direct children of the stage0 root, it is empty on an empty observation, and it is disjoint from every claiming authority.
What this arm cannot decide, named rather than absorbed
A newly hand-added stage0 file that nobody registered now lands in
generatedinstead of surfacing asunclassified. That class is not lost — it is decided one rung up.claim_executor --required-regencompares against the real emit population and refuses such a file ascommitted_not_emitted; it is enrolled inwitnesses.ymlas of 2026-08-20. No at-rest.dagfact carries the emit population, so the stale roster could only catch that class by being stale, and could not catch the converse — a file the emit stopped producing — at all, which is precisely how it fell two rows behind. The lower-rung machinery dissolves; its evidence stays enrolled. This is written into the carrier beside the derivation, not only here.The other half of the work item, and why no code changed for it
The item asked to consolidate "two paths for adding a v1 seed-closure module —
cssl_assembleand--required-regen". The premise does not survive reading whatcssl_assemblewrites, and the parent lane has withdrawn it.assemble_seed_linked_closurewrites intoout_dironly — the gunbc-emitted candidate crate. Its single read ofsrc/v1/stage0/srcisseed_has_pub_mod, an oracle deciding whether a compiler-family module in the candidate should become a re-export of the seed. No arm writes any path undersrc/v1. It is the probe path, not an admission path.There is one way a module enters the seed:
compile_stage0emits it and the bytes are committed, orstage0_crate_layoutregisters it.--required-regenrefusing an unregistered file is that path working, not a second mechanism disagreeing with it.What was real is that this is written down nowhere:
cssl_closure_assembly_notedescribes the assembly rule correctly and never says what the rule is not. That gap produced an escalation claiming the repository had lost the ability to add a seed module, a dispatched lane, a retraction, and a re-scoped work item carrying the false premise forward. It is now a paragraph at the carrier (cssl_is_not_a_seed_admission_path_note), which is where it stops costing work items.A finding recorded, deliberately not acted on here
cssl_assembledecides seed mod-tree membership by text-parsinglib.rs(parse_closure_mods,seed_has_pub_mod) while the modeled authority isstage0_crate_layout'shas_pub_modrows. Reading the emitted artifact is defensible when the artifact is current; it fails exactly when it is not, and the two readers then disagree during drift — the moment the answer matters most. The measured cost is #8587's nine handhas_pub_modflips, discovered by joining shim directories against disk andlib.rsby hand. Left out of this PR on the parent's instruction: one body of code inside two subjects has cost hours twice this week. It is a separate decision.Merge receipt: it happened again while this PR was open
#8666landed on main during review and had to hand-edit the producerless roster a third time, removingstd_iteration.rsafter deleting the module. That produced the modify/delete conflict this branch just resolved in favour of the deletion — and the resolution is verified, not assumed:src/v1/stage0/src/std_iteration.rsis absent from disk and from the index, so the derived population never names it and #8666's roster edit was bookkeeping the derivation makes unnecessary by construction. Post-merge census: 5305 hand items / 111476 hand LOC / 140 files.Verification
.dagauthority verified present in tree.scripts/rust_item_census.pycrashed on the missing path rather than going quiet. Every.dagconsumer was located by symbol grep before the delete and is repointed; the stale prose citations that came with it (several already naminggunbc.stage0_emit_model, a module path that was dead before it was written) are corrected in place.claim_batchoverdag/test/claim/stage0_rust_source_lifecycle_scaffold_witness_test.dag.dashboard node adhoc-3506d224-257