Repository navigation
namespace-structural-observations: the closing check first, then one ordinary compiled file answering all four through it - #9554
Merged
Conversation
…ordinary compiled file answering all four through it WHAT THE ROW ASKED. Make an ordinary compiled path produce, for each name written in a file, the declarations actually in view from that position: an earlier neighbour is in view, a declaration in another decision branch is not, one written further down is not, and two same-spelled declarations at different positions stay distinct. Write the closing check FIRST, then make ONE file answer all four through it. THE CLOSING CHECK, WRITTEN BEFORE THE PRODUCTION THAT SATISFIES IT. gunbc.namespace_structural_observations_contract requires four capabilities, each ESTABLISHED only by assessing a typed production observation through the one authority that already owns that judgement (assess_reference_binding_observation), never by counting variants -- so four StructuralBindingProductionRefused observations green nothing. The set difference is the parent row's own fold, parameterized in its required population rather than copied, so this row cannot drift from the parent's dominance rule. SUBJECT PROVENANCE IS THE HALF THE 2026-08-04 RETRACTION SAID WAS MISSING. Every admission carries the module path THE PARSE DECLARED -- read out of ParsedOccurrenceBindingSourceReady, never echoed from the caller's file argument -- and the check refuses unless all four name the one declared subject. Four admissions from four hand-built sources satisfy the capabilities and fail this check, which is exactly the difference between the row as written and the fixture suite that preceded it. ONE FILE, AND THE FOUR HARD-CODED FIXTURE SOURCES ARE DELETED. The v1 producer no longer knows any fixture text: it takes one subject and four probe spellings from its caller, and reads all four observations out of a single parse. Its own note already recorded that four independent strings could not satisfy this row; keeping them beside a subject-parameterized producer would have left two ways to answer one question and made the easier one the one that cannot close the row. EACH CASE SHOWN FAILING ON ITS OWN. Four red controls, each a SINGLE `replace` on the accepted subject text, so a control cannot quietly become a different program: the neighbour stops being earlier, the else arm loses its own binder, the later declaration is hoisted into view, the two homonyms merge into one. Each asserts the missing-capability set is EXACTLY the capability whose rule the edit broke -- a control asserting only "the contract is false" would pass just as well if the bridge returned nothing. A fifth control changes only the module declaration: all four capabilities still establish and the row still refuses, which is the provenance clause failing on its own. THE HOST BRIDGE, AND WHY IT EXISTS. The observations come from v1.compiler.parse and the required floor resolves `dag` and `src/v2` only; measured over the corpus, NO dag module imports v1, so a dag witness cannot name the producer. namespace_structural_observation_admissions is a hermetic transport across that boundary: one in-memory source, no repository file read, no module index, so the witness declares SubstrateInputsOnly truthfully and executes in the floor rather than landing in its DeclinedLiveTree arm. It decides nothing -- subject from the caller, observations composed in .dag, judgement by the shared authority. Declared and enrolled as seed growth (2 hand items) with a trigger naming the CAPABILITY it must be sufficient for, not an artifact that would contribute to one. MEASURED, NOT ASSERTED. All six witnesses PASS through the bridge from a dag-only witness (roots dag + src/v2), and independently on both architectures via the direct v1 route before the bridge existed. required-regen: first_generation_equal=true, EXIT=0. ONE SUBSTRATE LIMITATION FOUND BY EXECUTION AND RECORDED RATHER THAN ROUTED AROUND: a .dag record embedding a sole_constructor-bearing coproduct emits Serialize-only with a private field, so the seed does not compile (E0277, E0616). That is why the producer exports the compiled module and the admissions separately; both are pure functions of (file, source), so one pair of strings cannot pair a module path with admissions from another subject. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012nRBJLauCBLwBH8inAFHje
gunbai-bot Bot
pushed a commit
that referenced
this pull request
Aug 28, 2026
…refused, correctly The workaround row cited namespace_structural_observation_admissions, which does not exist on main -- it lands with #9554. The declaration index resolves every authored citation on every required run, so this PR's parse phase would have refused it. Caught by checking origin/main for the symbol rather than by CI. It now cites namespace_structural_binding_observations_a_through_d, which is real in both trees and is the half the two-export split was taken FROM, so the citation resolves today and stays true after #9554 lands. The sibling export is named in prose, where nothing can mistake a description for a resolvable symbol, and a comment records why the citation points where it does. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012nRBJLauCBLwBH8inAFHje
Brings the three main-side causes this branch was failing on, all closed on main: gunbc#9535 the barren test sidecar (BarrenTestSidecar) gunbc#9541 the 53 stale namespace-transition admissions gunbc#9551 restore the four emit mirrors to what the closure emits (regen drift) The branch was behind main and inherited all three; the merge is clean and carries no content change of its own. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013crMNyLvjKC2Q5UF851PKy
…Debug (review 57100)
review 57100 approved and flagged the Debug-formatted variant encoding in
reference_derived_closure_admission_value as mildly fragile. It is, and the fix is
cheap: all three enums are spelled by a total match returning the name.
WHAT THE FRAGILITY ACTUALLY IS, measured rather than assumed. All three enums --
Capability, ScenarioFailure, Trigger -- are nullary today, so Debug prints exactly the
variant name and the seam is correct. It stops being correct the moment any variant
gains a payload: Debug would print `Foo { .. }` and this seam would mint a variant name
no .dag match accepts. That fails LOUDLY rather than silently, so the objection is not
that it hides a defect -- it is that the failure lands at runtime on a name. A total
match makes the same mistake a compile error at this seam, which is the
construction-over-validation direction, and it stops the Rust identifier from standing
as a second representation of the variant's identity.
All six witnesses re-run PASS through the bridge after the change.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012nRBJLauCBLwBH8inAFHje
Base update: this branch predated gunbc#9560 (ba27746), which brackets the diagnostic-census memo fill out of CPU. The floor row refusing every run in this lane -- callable_candidate_ambiguity_witness, COMPLETED-OVER-COST-REQUIREMENT -- is dominated by four nested compiles through that memo. Verified with git merge-base --is-ancestor before merging, not assumed.
…eProductionRefused
The compiled-module result was a String with EMPTY standing for "the parse refused" --
the empty-observation narrow, in a carrier that had a typed absence available. Ruled
fixable HERE rather than in a follow-up, on a fact I verified before acting: git grep
nrdfc_compiled_module is ABSENT at this PR's merge base and absent on main, so this PR
INTRODUCES the conflation. Landing a new one knowingly and scheduling its repair is the
deferred-refactor pattern, and registering a future fix is not a permit.
WHY "FAIL-CLOSED TODAY" WAS NOT SUFFICIENT: '' never equalling the declared subject is a
property of what the one current consumer does with the string, not of the carrier. The
next consumer gets no help from the type, and the conflation is invisible exactly where
it would go wrong. The module note said "a source that does not parse reports no module
at all" -- true of the VALUE, false of the CARRIER. Both are true now.
WHERE THE TYPE LIVES: std.reference_binding_observation, the neutral carrier both sides
already share, so there is one authority rather than a v1 spelling and a dag spelling of
one concept; and the refusal reuses ReferenceBindingProductionGap rather than minting a
second gap vocabulary beside it.
TWO OF THE THREE RULED CONTROLS, both authored and both discriminating by construction --
delete the conjunct each targets and it goes red:
a_row_nobody_produced_does_not_close_this_row
the authorable projection of "bridge registration removed -> witness cannot execute".
A witness cannot unregister a builtin; it can assert what that state looks like here --
no rows offered -- and that a contract closing on zero rows would be green for a row
nothing produced. It is the only thing that fails if count(rows) > 0 is removed.
established_capabilities_with_an_unproduced_subject_still_refuse
the carrier-shape control. Flattening to Bool keeps the capability half and loses the
subject half, so the discriminating input is rows whose four capabilities ALL establish
over a subject identity that was not produced. It also pins that the refusal reports its
own reason rather than an empty path.
THE THIRD CONTROL IS NOT HERE AND IS NOT FAKED. "Live-tree acquisition introduced ->
SubstrateInputsOnly refuses" needs a mutant that actually performs a live read, which is
not authorable from inside a hermetic witness. Raised separately rather than allowed to
hold the other two.
MEASURED: all six original witnesses PASS on the typed carrier, plus the two new controls.
required-regen first_generation_equal=true EXIT=0; generated-artifact gate EXIT=0.
Seed-growth roster updated to +3 with subject_module_value enumerated.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012nRBJLauCBLwBH8inAFHje
… test asserted literally
review 57241 approved and flagged, as nit-quality, that structural_admission_subject_mismatch
reported an unproduced subject as the literal "<subject module not produced>" and the
acceptance test asserted that exact spelling. The observation is right and the fix is the
same one this PR already made one level up, so leaving it would have been inconsistent with
its own argument: a coproduct that already has names does not need a string that repeats one
of them, and a test coupled to the spelling would go green on any other sentinel.
StructuralAdmissionSubjectMismatch
= AdmissionNamesAnotherModule { module_path }
| AdmissionSubjectNotProduced { gap }
The gap travels through rather than being flattened, so the reason the subject was not
produced survives to the consumer instead of stopping at "not produced". The control now
counts the AdmissionSubjectNotProduced variant rather than matching text.
No mirror or regen impact: the contract module is not in the seed's emit closure, and the
type is contract-local rather than another row in the neutral std carrier -- a subject
mismatch is this contract's judgement, not a neutral observation about a parse.
MEASURED: all eight witnesses PASS.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012nRBJLauCBLwBH8inAFHje
briansrls
pushed a commit
that referenced
this pull request
Aug 28, 2026
* File the emitted-record Deserialize gap as its own class row, with both rustc codes and the minimal shape DESIGN 4b asks every discovered error class to file one row. This one was found by execution while building namespace-structural-observations (#9554) and was recorded only as a note inside the producer that worked around it, which is found solely by someone already editing that producer. THE CLASS: a .dag record embedding a coproduct whose variant carries a sole_constructor type emits a Rust record deriving Deserialize over a Serialize-only private-field struct. Two rules that are each individually correct compose into a shape the author cannot write. MEASURED, not recalled: E0277 on the outer record's derived Deserialize, E0616 on a read of the carried field. They are separate rows because they land on different constructs and either can appear without the other. RUNG: mitigatable, and stated as such. Nothing in the ordinary .dag compile path refuses the shape; the refusal arrives as generated-Rust build failures at maximum distance from their cause. NO EXECUTING RED IS ENROLLED, and the reason is the fixture boundary rather than a saving: the only way to author the shape today is inside the seed's emit closure, where it stops the required build for every subject at once rather than going red on its own. That missing harness is named as the next-rung trigger, and the trigger states the CAPABILITY -- emitting and compiling a module the seed does not import -- rather than an artifact that would contribute to one. The carried predicate asserts only that the finding is recorded with its codes and its shape, never that the gap is closed; a closure predicate would be satisfiable by editing this file. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012nRBJLauCBLwBH8inAFHje * Measure the premise the trigger's refusal clause rested on: it is false, and the clause is narrowed The refusal clause said an added emit-compile roster entry could never retire this row because "every rostered entry is a seed-closure entry". Nobody had checked that, and snappy-dove-250 flagged the premise rather than the form. MEASURED: computing the transitive IMPORT closure from every module under src/v1 over src/v1 + dag -- the most generous seeding, so an OUTSIDE answer is robust -- three of the eight rostered entries are outside it (gunbc.ci_layer_roots, gunbc.scm.load_standing, std.abi). A second independent instrument agrees exactly: those three are the three with no committed mirror under src/v1/stage0/src, while extdeps.uri and std.logic are inside and have one. The phase already compiles non-seed modules. So isolation from the seed was never the missing capability, and the trigger no longer claims it is. The capability is an EXPECTED-RED COMPILE ARM: every route we have treats a compile failure as a line stop, so authoring this shape anywhere reachable makes a gate permanently red instead of producing an enrolled red. A rostered entry is still not sufficient -- for that reason, not the one previously given. WHY AN OVER-STRONG TRIGGER IS NOT THE SAFE ERROR: it is the mirror of the 4b(3) failure. A trigger unsatisfiable while the capability is alive fails as quietly as one satisfied while it is dead, because a row that never retires reads as diligence. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012nRBJLauCBLwBH8inAFHje * Cite an export that exists on main: the forward reference would have refused, correctly The workaround row cited namespace_structural_observation_admissions, which does not exist on main -- it lands with #9554. The declaration index resolves every authored citation on every required run, so this PR's parse phase would have refused it. Caught by checking origin/main for the symbol rather than by CI. It now cites namespace_structural_binding_observations_a_through_d, which is real in both trees and is the half the two-export split was taken FROM, so the citation resolves today and stays true after #9554 lands. The sibling export is named in prose, where nothing can mistake a description for a resolvable symbol, and a comment records why the citation points where it does. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012nRBJLauCBLwBH8inAFHje * The rung stands at mitigatable, and the sentence that made it look wrong is deleted (review 57088) review 57088 requested changes: the row declares mitigatable while a comment said the required seed build reliably refuses the shape, and a mechanism that exposes and blocks a writable invalid state is mechanically preventable under DESIGN 4b. THE OBJECTION WAS FAIR AND THE SENTENCE IT READ WAS FALSE. That comment said "the only way to author this shape today is to put it in the seed's emit closure". Measured over 4234 modules under src/v1 + dag + src/v2: the seed closure is 134 and the emit-compile roster's closures add 5, so 139 are covered and 4095 ARE NOT. On those 4095 the shape is accepted, the bad state is written, and no build ever fails. The false sentence is deleted rather than softened, and the measurement is carried as its own data row. WHY THE RUNG DOES NOT MOVE. 4b(1) sets a class's rung at the MINIMUM across its in-scope paths, so the uncovered majority decides it. And on the 139 covered modules the refusal is still not prevention: a build break at a distance from its cause, in generated code the author did not write, with no typed located diagnostic naming the source construct, is containment after failure. The invalid state stays writable on every path. The no-executing-red justification now follows from the same split rather than from the deleted claim: on 4095 modules the shape produces no signal for a probe to observe, and on 139 it stops the required build rather than asserting a red. Neither yields an enrollable red -- which is the capability the trigger already names. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012nRBJLauCBLwBH8inAFHje --------- 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.
Closes the roadmap row
namespace-structural-observationsin the order its own first slice prescribes: the closing check first, then one ordinary compiled file producing all four in-file visibility observations through it.The closing check (written before the production that satisfies it)
gunbc.namespace_structural_observations_contractrequires four capabilities, each ESTABLISHED only by assessing a typed production observation through the single authority that already owns that judgement (gunbc.namespace_reference_derived_closure_admissionassess_reference_binding_observation) — never by counting variants, so fourStructuralBindingProductionRefusedobservations green nothing. The set difference is the parent row's own fold, parameterized in its required population rather than copied, so this row cannot drift from the parent's dominance rule and the parent's closing predicate is unchanged.Subject provenance is the half the 2026-08-04 retraction named as missing. Every admission carries the module path THE PARSE DECLARED — read out of
ParsedOccurrenceBindingSourceReady.module_path, never echoed from the caller's file argument — and the check refuses unless all four name the one declared subject. Four admissions from four hand-built sources satisfy the capabilities and fail this check, which is exactly the difference between the row as written and the fixture suite that preceded it.One ordinary compiled file
The four hard-coded per-clause fixture sources in the v1 producer are deleted. It now takes one subject plus four probe spellings from its caller and reads all four observations out of a single parse; it knows no fixture text. One ordinary module carries all four cases: an earlier neighbour called from a later sibling, one
letname in both arms of a decision, a callee declared further down, and a parameter plus aletof one spelling at two positions.Each case shown failing on its own
Four red controls, each a single
replaceon the accepted subject text, so a control cannot quietly become a different program. Each asserts the missing-capability set is EXACTLY the capability whose rule the edit broke — a control asserting only "the contract is false" would pass equally well if the bridge returned nothing at all. A fifth control changes only the module declaration: all four capabilities still establish and the row still refuses, which is the provenance clause failing on its own.The typed subject carrier, and the two ruled controls that came with it
The compiled-module result was a
Stringwith EMPTY standing for "the parse refused" — the empty-observation narrow, in a carrier that had a typed absence available.git grep nrdfc_compiled_moduleis absent at this PR's merge base and absent on main, so this PR introduces it; fixing an inherited defect in a follow-up is ordinary, landing a new one knowingly and scheduling its repair is not. It is nowStructuralObservationSubjectModule = SubjectModuleProduced { module_path } | SubjectModuleProductionRefused { gap }, declared instd.reference_binding_observation— the neutral carrier both sides already import, so there is one authority rather than a v1 spelling and a dag spelling of one concept — with the refusal reusingReferenceBindingProductionGaprather than a second gap vocabulary. "Fail-closed today" was not sufficient:""never equalling the declared subject was a property of what the one current consumer did with the string, not of the carrier.Two further controls, each discriminating by construction — delete the conjunct it targets and it reds:
a_row_nobody_produced_does_not_close_this_row. Stated honestly: this is the authorable projection of the ruled control "bridge registration removed → closing witness cannot execute", not that control itself. A witness cannot unregister a host builtin, so it asserts what that state looks like to this contract — no rows offered — and that a contract closing on zero rows would be green for a row nothing produced. Weaker than the ruled version, and discriminating: it is the only thing that fails ifcount(rows) > 0is deleted.established_capabilities_with_an_unproduced_subject_still_refuse. The carrier-shape control. Flattening the result toBoolkeeps the capability half and loses the subject half, so the discriminating input is rows whose four capabilities all establish over a subject identity that was not produced.A third ruled control is deliberately absent, and reading the producer made the reason stronger than "wrong owner". The ruled control is "live-tree acquisition introduced →
SubstrateInputsOnlyrefuses".v2.std.live_treelive_tree_disposition_notestates in the tree, at length, that a row declaringSubstrateInputsOnlywhile actually reading live state is re-checked by nothing — the enforcement it used to name (the nightly affected-set falsifier's predict-only cold run) died withfalsifier.ymlin the 2026-08-15 floor cut, and its re-add sits on DESIGN's unguarded list. So the control would not be testing a wall I do not own; it would be asserting a wall the corpus documents as absent, which is worse than the permanently-green decoration it superficially resembles, because it would be cited as coverage of a known no-wall.One qualification, because "nothing checks it" is very slightly too strong and the difference is load-bearing:
v2.std.effect_reachreads_live_tree_effectivetakes the declared answer first and falls through to a derivation only when the row saysSubstrateInputsOnly— so a partial backstop does fire on exactly the lying case. Its ceiling is declared ateffect_reach_detection_ceilingand executed by a planted fixture pair: it classifies a closure as host-reading only when a repository path literal and a host-sink call shape both occur, so a closure performing a real read while naming no path derives NOT-live. That is a declared, executed ceiling — not an enforcement a control could stand on, and not nothing either.A control asserting merely that the disposition field reads
SubstrateInputsOnlyis not written here on purpose: its red is unreachable by construction, which §4b calls worse than absent. The disposition of this gap is an obligation, not a ceiling — the named next-rung capability is call-reachability-grade classification (fn-arrowDependencyViewover lowered bodies), and it is unbuilt.The host bridge, and why it exists
The observations come from
v1.compiler.parse, and the required floor resolvesdagandsrc/v2only; measured over the corpus, no dag module imports v1, so a dag witness cannot name the producer.namespace_structural_observation_admissionsis a hermetic transport across that boundary — one in-memory source, no repository file read, no module index — so the witness declaresSubstrateInputsOnlytruthfully and executes in the floor rather than landing in itsDeclinedLiveTreearm. It decides nothing: subject from the caller, observations composed in.dag, judgement by the shared authority. Declared and enrolled as seed growth (gunbc.namespace_structural_observation_bridge_seed_growth, 2 hand items), with a trigger naming the CAPABILITY it must be sufficient for rather than an artifact that would contribute to one.The two rejected alternatives are recorded in that row: a witness under
src/v1/testswould bind the contract to evidence no required run executes (coverage by illusion), and rebuilding the observations on the v2 pipeline would put a second resolution authority beside the P2a/P1 kernel.Measured
--source-root dag --source-root src/v2), and independently on both architectures via the direct v1 route before the bridge existed.claim_executor --required-regen:first_generation_equal=true, EXIT=0.generated_artifact_gate main_wet(ROADMAP.md, the dispatch surface).One substrate limitation found by execution and recorded rather than routed around
A
.dagrecord embedding asole_constructor-bearing coproduct emits Serialize-only with a private field, so the seed does not compile (E0277 on the record, E0616 on the receipt field). That is why the producer exports the compiled module and the admissions separately; both are pure functions of(file, source), so one pair of strings cannot pair a module path with admissions from a different subject.Note for review
Four emitted mirrors (
v1_compiler_emit_{core_support,go,python,rust}.rs) are not this change's — they are a pre-existing regen drift on main that my regen correctly picked up, already in flight as #9537. Measured by hash, all four are byte-identical to #9537's (6317702515,e4e4fd9bd2,705cfab2ca,8abac9e235), so this change contributed no qualification of its own; had it, the bytes would differ. Its cause (established by smart-ram-730 and clever-boar-140) is a composition of #9486 and #9461, merged three minutes apart from an identical base with no textual conflict for any gate to see. Identical bytes cannot conflict, so #9554 and #9537 may land in either order. Installed from the regen candidate, never hand-edited;--required-regenis the adjudicator and it is green.🤖 Generated with Claude Code
https://claude.ai/code/session_012nRBJLauCBLwBH8inAFHje