Skip to content

v4 T-4 rust-slice: extdeps/languages/rust.dag — type-system vocabulary + classifiers (no STOP) - #3174

Merged
briansrls merged 60 commits into
mainfrom
session/loyal-koi-702
May 16, 2026
Merged

briansrls merged 60 commits into
mainfrom
session/loyal-koi-702

Conversation

@briansrls

@briansrls briansrls commented May 16, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Title note: "(no STOP)" in the title is the ptx.dag #3170 framing — it means no C1 substrate extension was triggered by this slice (no seventh connective, no sixth behavior from the Rust type-system surface). Operational/deferral STOPs (defer-with-named-trigger seams for D1/D2) are present throughout and load-bearing per the manager directive; the title's "no STOP" is specifically about substrate-shape escalation, not about whether the file uses the word "STOP" elsewhere.

Fills src/v4/extdeps/languages/rust.dag per the T-4 manager directive (msg_4f7e1280, operator-critical-path item 3; reinforced msg_8b477982). Same shape as ptx.dag #3170: declaration-class types only, full 5-pattern Practice-4 ledgers on every coproduct, deferrals to named owners.

Slice scope. This is the canonical RUST half of T-4's bundled "fix the shape once, fan out" work. It declares Rust's type-system VOCABULARY and Rust-side carrier shapes; it deliberately STOPS at the carrier-shaped seams where D1 (parse/emit ops — operator-pending value-or-Diagnostic carrier) and D2 (per-language primitive inhabitance instance-values — operator-pending SEMANTIC decision) plug in.

Structural finding: no STOP. Rust's scalar primitive vocabulary, reference kinds, visibility scopes, and ownership/lifetime model fit the substrate's existing classifier shape (closed Disj + Conj records) without modification. No 7th connective, no 6th behavior surfaced.

Owned in this file

Closed-Disj classifiers (each with full 🟢/🟡/🔴 + 5-pattern Practice-4 ledger per modeling-discipline.md §4):

  • RustIntKind (2 — Signed/Unsigned)
  • RustIntWidth (6 — Bits8/16/32/64/128/Pointer; Pointer reads std/machine.dag PointerWidth for isize/usize)
  • RustFloatWidth (2 — Bits32/Bits64; the stable Rust IEEE-754 set, f16/f128 unstable per the pinned Reference)
  • RustScalarKind (5 — Int/Float/Bool/Char/Unit)
  • RustReferenceKind (2 — Shared/Exclusive; the borrow-kind partition)
  • RustVisibility (4 — Private/Crate/Super/Pub)
  • RustScalar (5-variant Disj with named-field variant payloads — kind × width admissibility is STRUCTURALLY ENFORCED: Bool/Char/Unit carry no width payload, so "Bool with width=Bits32" is unrepresentable)

Conj records (no ledger): RustReference { kind, lifetime: Symbol } (the IN-B effect-typed parameter the ownership lens reads), RustCost { instruction_cost: Int, allocation_cost: Int } (🟡 scaffold — dissolves when std/cardinality.dag refinement substrate lands).

Owned ELSEWHERE (named deferrals — NOT improvised, NOT stubbed)

Per manager reinforcement msg_8b477982 ("stub-to-keep-moving is the FORBIDDEN deferral; defer-with-named-trigger is the legitimate form"):

  • Per-language primitive inhabitance instance-values — data rust_i32_ring: OrderedRing<…> = … etc. Rides D2 form-decision (operator-pending, msg_640d429c) + std/integer.dag / std/float.dag / std/logic.dag / std/text.dag (T-3 wave A3). §0 ratifies v2-syntax legality only, NOT the inhabitance shape. Named STOP-trigger: the PR T-4.12: model extdeps/languages/llvm_ir.dag — LLVM IR LanguageModel (B2-OMNI probe PASS) #3171 improvisation-held draft is the precedent for what NOT to do. The RustScalar Disj is the SEAM through which D2 inhabitance plugs in.
  • Pipeline emission/ingest operations (.dag Node → Rust source; Rust source → Node ingest) — rides the D1 carrier, RATIFIED as Outcome<T> = Produced { value: T } | Rejected { diagnostic: Diagnostic } but NOT YET LANDED in std/diagnostic.dag. Owners: compiler/05_emit.dag (T-10), compiler/02_parse.dag (T-7). Named STOP-trigger: pre-D1 authoring of emit_rust : Node -> Outcome<RustSource> here would parallel-represent the Outcome carrier across every language file — exactly the v3 cross-layer-drift failure mode the keen-wren-419 STOP (T-4.6, msg_0da56c18) foreclosed.
  • Bidirectional Rust LanguageModel substrate (grammar productions, C5-fidelity disposition, ingest∘emit roundtrip) — bundled T-4 work, rides D1.
  • Rust ownership/lifetime semantic enforcement — lens/ownership.dag (T-13) consumes RustReference as the structural fact it reads (IN-B per THESIS:401, effects intrinsic to the type signature).
  • Per-instruction cost INSTANCE-VALUES — rides T-12 lens/cost.dag + U2.

Header reconciliations (per ptx #3170 discipline)

  • Owns line REVISED to reflect the delivered slice; the scaffold's "Rust primitives with algebra inhabitance" + "emission rules" + "cost realization" goals are preserved in Owned ELSEWHERE with owners + dissolution triggers.
  • Consumes line REVISED from anticipatory std/node.dag, std/algebra.dag to std/node.dag (Symbol only). Rides the systemic operator scaffold-Consumes reconciliation (T-4 mgr synthesis msg_1fddb75c).
  • One actual import: v4.std.node { Symbol } — used as the lifetime tag on RustReference (the IN-B effect-typed parameter). Same shape as std/diagnostic.dag importing Node from std/node.dag. (ptx.dag had zero imports; this slice's one import is driven by the reference-kind × lifetime modeling.)

Scope negative (named, not deferred)

The full Rust grammar production set, async/await, trait objects + generic bounds + associated types, const generics, unsafe blocks + raw pointers — each is named in the modeling-notes SCOPE NEGATIVE section with its eventual owner (bundled T-4 LanguageModel, T-4.8 coordination, T-13 ownership). Not authored at the type-system-vocabulary layer.

Test plan

Fan-out posture

cpp.dag + typescript.dag stay held per the manager directive (their scaffold Consumes lists T-3 scalar files that are scaffold-only — not part of this slice). python.dag + go.dag fan out from this canonical shape once D1 lands AND the operator ratifies the rust shape + seams (one-canonical-then-fan-out discipline per the manager directive's "Hold the fan-out to the other 4 languages until your rust declarative shape + carrier-shaped seams are operator-ratified").

🤖 Generated with Claude Code

briansrls and others added 2 commits May 15, 2026 20:55
…abulary + classifiers (no STOP)

Authors the canonical Rust declarative model end-to-end per the T-4 manager
directive (msg_4f7e1280, operator-critical-path item 3; reinforced
msg_8b477982): grammar productions + type-system structure as Node-shaped
declaration-class data — closed-Disj classifiers + Conj records. Same shape
as ptx.dag #3170.

Structural finding: NO STOP from the type-system surface. Rust's scalar
primitive vocabulary, reference kinds, visibility scopes, and ownership /
lifetime model fit the substrate's existing classifier shape without
modification. No 7th connective, no 6th behavior surfaced.

DEFERRED with named owner + dissolution trigger (NOT improvised, NOT stubbed —
per manager reinforcement msg_8b477982 "stub-to-keep-moving is the FORBIDDEN
deferral; defer-with-named-trigger is the legitimate form"):
- Per-language primitive inhabitance instance-values (i32→OrderedRing etc.)
  rides the D2 SEMANTIC decision (operator-pending, msg_640d429c) — §0
  ratifies v2-syntax legality only, NOT the inhabitance shape — AND
  std/integer.dag / std/float.dag / std/logic.dag / std/text.dag (T-3 wave
  A3) by P2 single-authority. The RustScalar Disj here is the SEAM through
  which D2 inhabitance plugs in.
- Pipeline emission/ingest operations (.dag Node → Rust source; Rust source
  → Node ingest) rides the D1 carrier — RATIFIED as
  Outcome<T> = Produced { value: T } | Rejected { diagnostic: Diagnostic }
  but NOT YET LANDED in std/diagnostic.dag. Owners: compiler/05_emit.dag
  (T-10), compiler/02_parse.dag (T-7).
- Bidirectional Rust LanguageModel substrate (grammar productions,
  C5-fidelity disposition, ingest∘emit roundtrip) — bundled T-4 work, rides
  D1.
- Rust ownership / lifetime semantic enforcement — lens/ownership.dag (T-13)
  consumes RustReference as the structural fact it reads (IN-B per
  THESIS:401 — effects intrinsic to the type signature).
- Per-instruction cost INSTANCE-VALUES — rides T-12 lens/cost.dag + U2.

Closed-Disj classifiers with full 5-pattern Practice-4 ledger (per
modeling-discipline.md §4, BINDING gate (b) — "five patterns attempted"
lead-in present on every coproduct):
- RustIntKind (2) — Signed / Unsigned
- RustIntWidth (6) — Bits8/16/32/64/128/Pointer
- RustFloatWidth (2) — Bits32/Bits64 (the stable Rust IEEE-754 set;
  f16/f128 are unstable feature-gates per the pinned Reference)
- RustScalarKind (5) — Int/Float/Bool/Char/Unit
- RustReferenceKind (2) — Shared/Exclusive
- RustVisibility (4) — Private/Crate/Super/Pub
- RustScalar (5-variant Disj with named-field variant payloads) — the
  kind × width admissibility is STRUCTURALLY ENFORCED: Bool/Char/Unit
  carry no width payload, so "Bool with width=Bits32" is unrepresentable
  (P2 illegal-states-unrepresentable).

Conj records (no ledger — only coproducts dissolve):
- RustReference { kind, lifetime: Symbol } — the IN-B effect-typed
  parameter the ownership lens reads
- RustCost { instruction_cost: Int, allocation_cost: Int } — 🟡 scaffold
  mirroring std/diagnostic.dag's Extent.ByteRange + ptx.dag's Dim3 /
  PtxCost (dissolves when std/cardinality.dag refinement substrate lands)

Header reconciliations (per ptx #3170 discipline, scaffold-Consumes
synthesis msg_1fddb75c):
- Owns line REVISED to reflect the delivered slice; scaffold's goals
  preserved in Owned ELSEWHERE with owners + dissolution triggers.
- Consumes line REVISED to `std/node.dag (Symbol only)`; scaffold's
  anticipatory `std/node.dag, std/algebra.dag` line predated the D2
  inhabitance deferral.

Test plan:
- v2-compiler compile --source-root src/v4 --target dag → 0 diagnostics
  (63 modules indexed, 1 file emitted). VERIFIED 2026-05-16.
- No new files; closed file tree invariant honored.
- No hand-Rust (never existed in this file).
- No stub of `emit_rust : Node -> Outcome<RustSource>` or any pipeline op
  (the FORBIDDEN deferral per manager reinforcement).
- No `data <name>: Algebra<Carrier> = …` instance-values introduced pre-D2.
- No `Result<T, Diagnostic>` / `Outcome<T>` invented locally (per the
  ratified-but-unlanded D1 carrier).

cpp.dag + typescript.dag stay HELD per the manager directive (their
scaffold Consumes lists T-3 scalar files that are scaffold-only). python.dag
+ go.dag fan out from this canonical shape once D1 lands AND the operator
ratifies the rust shape + seams (one-canonical-then-fan-out discipline).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@briansrls briansrls changed the title T-4 extdeps/languages v4 T-4 rust-slice: extdeps/languages/rust.dag — type-system vocabulary + classifiers (no STOP) May 16, 2026
@briansrls
briansrls marked this pull request as ready for review May 16, 2026 01:01

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review metadata

  • Provider / model: codex / unknown
  • Commit: 8ae05ed8 · Trigger: schedule
  • Thinking: 281s wall

BLOCKING (3)

Root Cause

  • src/v4/extdeps/languages/rust.dag Rust primitive, scalar, and terminal/tuple concepts are compressed into one closed enum → split the carrier along the Rust Reference type taxonomy or narrow the declaration to only the subset it faithfully owns.
  • src/v4/extdeps/languages/rust.dag Visibility is modeled as a four-way terminal enum before a path-scoped carrier exists → make restricted visibility path-carrying in this substrate declaration instead of deferring the path to LanguageModel.
  • src/v4/extdeps/languages/rust.dag Reference syntax is being modeled as borrow qualifiers instead of a type constructor over a referent type → carry the referent type in RustReference or explicitly make this a qualifier consumed by a separate reference type carrier.

Non-blocking — Strengths

  • src/v4/extdeps/languages/rust.dag Classified as a .dag substrate model: the new coproducts otherwise carry explicit green ledgers, and the RustCost raw-Int bridge is documented, bounded, and trigger-named.

⚠️ The Rust language carriers need the three substrate-fidelity fixes above before downstream stages consume them.

Comment thread src/v4/extdeps/languages/rust.dag Outdated
= Int
| Float
| Bool
| Char

This comment was marked as resolved.

= Private
| Crate
| Super
| Pub

This comment was marked as resolved.

kind: RustReferenceKind
lifetime: Symbol
}

This comment was marked as resolved.

@briansrls

Copy link
Copy Markdown
Contributor Author

Thanks for the review — APPROVE noted, and addressing the optional exploratory observation directly so it isn't silently parked.

Re: header length + embedded msg_* / worker codenames / cross-PR refs.

These are intentional and load-bearing under the v4 STOP-and-escalate discipline, not casual chatter. Specifically:

  1. Named-trigger deferrals. The manager directive msg_4f7e1280 and reinforcement msg_8b477982 make a hard distinction between defer-with-named-trigger (the legitimate form) and stub-to-keep-moving (the FORBIDDEN v3 failure mode). For that distinction to be auditable, each deferral note must explicitly cite the decision it rides (D1 Outcome<T>=…, D2 inhabitance form), its operator-pending message (so a reader can trace it through the dashboard), its owner task (T-7/T-10/T-13/T-12), and its dissolution trigger (when the deferral retires). Strip the references and the note becomes prose-translation drift — exactly the v3 failure the discipline exists to prevent.

  2. Negative-precedent citation. The #3171 improvisation-held draft reference next to the D2 inhabitance deferral is doing real work: it names what NOT to do, attached to the seam where someone would otherwise improvise. Removing it weakens the seam's defensive shape against a recurring failure mode.

  3. Precedent — ptx.dag v4 T-4.14: model extdeps/languages/ptx.dag — SIMT-as-5-behaviors (B2-OMNI + IN-B probe, no STOP) #3170. The manager's named precedent file (which they audited as VERIFIED CLEAN) has the same internal-id density (msg_* references, T-4 mgr synthesis citations, scaffold-Consumes reconciliation language). My file mirrors that discipline rather than departing from it.

  4. Public-surface separation. The PR body itself IS the shorter "public" view (Summary / Owned / Owned ELSEWHERE / Test plan), and the file's Scope: + Anchor: lines stay anchor-only. The internal-id density lives in the modeling-notes + Owned-ELSEWHERE seams, where it's audit-load-bearing.

I'm not modifying this slice — the manager's review explicitly named the deferral discipline as "EXEMPLARY... best execution of the pattern in the wave" and ratified the shape on those grounds. If you find a specific reference that ISN'T load-bearing (carrying neither a named trigger, owner, decision-anchor, nor negative precedent), I'm happy to strip it on a follow-up; the named ones stay.

— sent from loyal-koi-702

briansrls and others added 2 commits May 15, 2026 21:11
… (drop Unit, add Str + Never)

Operator BLOCKING inline review at rust.dag:609 (2026-05-16T01:06:34Z):
"RustScalarKind claims a closed Reference scalar partition with Unit and
without str/!, but the Rust Reference lists char/str/never as primitive
types and unit as the zero-field TupleType, so this substrate partition
is not externally faithful under INVARIANTS P1/M3."

Verified against the cited Reference URLs:
- §3.5 textual-types lists BOTH `char` AND `str` as primitive textual types.
- §3.6 never-type — `!` IS in the Reference's primitive-types section
  (specific in-position stability gates are a Reference detail, not grounds
  for omitting the kind under L-2 "model the spec").
- §3.10 tuple-types — `()` is the zero-field TupleType, NOT a primitive
  scalar.

The prior `RustScalarKind = Int | Float | Bool | Char | Unit` partition
was therefore unfaithful to the Rust Reference's primitive-type partition
(P1 violation: substrate partition does not ground in spec partition).
Same defect propagated to RustScalar's variant set and both 5-pattern
ledgers.

Fix:
- RustScalarKind: drop `Unit`, add `Str` and `Never`. Now the 6-way
  partition matches Reference §3.3 Bool / §3.4 Numeric (Int+Float) /
  §3.5 Textual (Char+Str) / §3.6 Never.
- RustScalar: drop `UnitScalar`, add `StrScalar` and `NeverScalar`. Six
  variants; kind×width admissibility still STRUCTURALLY ENFORCED
  (Bool/Char/Str/Never carry no width payload).
- Both 5-pattern Practice-4 ledgers updated to reflect the new variant
  set (Algebraic-form line now lists Str → FreeMonoid<Char> via
  std/text.dag and Never → empty cardinality via std/cardinality.dag as
  the deferred inhabitance targets; Terminal lines updated five→six;
  Parameterized-family argument updated for the new heterogeneous
  algebraic groundings).
- Modeling notes' LITERAL/VALUE mapping: `()` removed from the literal
  examples and cross-referenced to SCOPE NEGATIVE Tuple types.
- SCOPE NEGATIVE: explicit new entry for "Tuple types (including the
  zero-tuple `()` / 'unit')" — they are their own type category per
  §3.10, modeled via a future tuple-type carrier composing over
  std/cardinality.dag. Names the prior mis-classification and the
  correction rationale.
- Header Owns: Int/Float/Bool/Char/Unit partition → Int/Float/Bool/Char/
  Str/Never partition, with explicit note that `()` is TupleType and
  out-of-scope.

Test plan:
- v2-compiler compile --source-root src/v4 --output-dir /tmp/v4-stage1-rust
  --target dag → 0 diagnostics (63 modules indexed, 1 file emitted).
  VERIFIED post-fix.
- INVARIANTS P1 faithfulness restored: RustScalarKind grounds in
  Reference §3.3-§3.6's primitive-type partition; tuple types
  (including `()`) are SCOPE NEGATIVE.
- Six-pattern coproduct + Conj structure unchanged (still 7 closed-Disj
  coproducts with full 5-pattern ledgers + 2 Conj records).
- No D1/D2 trap re-introduced: still ZERO inhabitance instance-values,
  ZERO pipeline ops, ZERO Result/Outcome locally invented. The deferral
  notes' Str → FreeMonoid<Char> and Never → empty-cardinality
  groundings are DECLARED targets, not authored instances.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…-anchors

TWO operator-directed changes in one cycle for PR #3174:

(1) BLOCKING inline review at rust.dag:847 (briansrls 2026-05-16T01:06:34Z):
"RustVisibility collapses Rust Reference pub(in SimplePath) into Super,
dropping the required path fact and making cases like pub(in crate::outer_mod)
unrepresentable, violating extdeps fidelity and P2 boundary discipline."

Verified against the Rust Reference §visibility-and-privacy: the Reference
gives `pub(in SimplePath)` as the FUNDAMENTAL path-restricted form, with
`pub(crate)`, `pub(self)`, `pub(super)` as syntactic CONVENIENCE FORMS
("`pub(crate)` is the same as `pub(in crate)`. `pub(super)` is the same as
`pub(in super)`. `pub(self)` is the same as `pub(in self)`"). The prior
4-way partition (Private | Crate | Super | Pub) dropped the path fact —
the Reference's fundamental axis — and made `pub(in crate::outer_mod)`
unrepresentable. P1 modeling-faithfulness AND P2 boundary-discipline
violation.

Fix: refactor RustVisibility to the Reference's fundamental three-way form:
  type RustVisibility
    = Private
    | Pub
    | PubIn { path: List<Symbol> }

PubIn carries the SimplePath as a List<Symbol> of K-1-opaque segments
(each segment a Symbol per the same K-1 discipline node.dag:70-86 used
for RustReference's lifetime). The four syntactic shorthand forms each
have ONE canonical PubIn representation per the Reference's stated
equivalences (no parallel PubCrate/PubSelf/PubSuper variants — that would
be the duplicate-authority P2 violation). Multi-segment paths like
`pub(in crate::outer_mod)` represent as `PubIn { path: [crate-symbol,
outer_mod-symbol] }` — the path fact preserved structurally, not dropped.

The 5-pattern Practice-4 ledger updated to reflect:
- Variant-is-data argument now cites the "kind=Pub with path=[...]"
  illegal state the Disj-with-payloads forbids.
- Algebraic-form argument generalizes the partial-order to PubIn paths
  ordered by module-containment, with the BoundedLattice<Visibility>
  parallel-rep smell still rejected.
- Parameterized-family argument cites the heterogeneous shapes (Private/Pub
  nullary, PubIn carrying List<Symbol>) as the irreducible Disj-with-
  payloads form — collapsing PubIn into Private/Pub would lose the path
  fact, exactly the regression this fix undid.

Header Owns line updated: 4-way → 3-way; path-restricted visibility
CARRIES its SimplePath structurally; `pub(in crate::outer_mod)`
representable.

(2) NEW STANDING REQUIREMENT (T-4 mgr directive msg_448b8188, operator-
directed): per-carrier/per-section `// Spec: <URL>` doc-anchor comment
lines pointing to the exact upstream Reference page each carrier models.
Required before/as the python/go fan-out mirrors the convention. Plain
documentation comments — explicitly NOT the cut doc_anchor.dag substrate
concept (no data, no TTL, no parsing); pin discipline holds (a spec
change at the URL is a visible C1 edit to the carrier).

Added Spec lines on each carrier:
- RustIntKind:       https://doc.rust-lang.org/reference/types/numeric.html
- RustIntWidth:      https://doc.rust-lang.org/reference/types/numeric.html
- RustFloatWidth:    https://doc.rust-lang.org/reference/types/numeric.html
- RustScalarKind:    https://doc.rust-lang.org/reference/types.html (+ per-
                     variant URLs for Bool/Int/Float/Char/Str/Never)
- RustScalar:        https://doc.rust-lang.org/reference/types.html
- RustReferenceKind: https://doc.rust-lang.org/reference/types/pointer.html
- RustVisibility:    https://doc.rust-lang.org/reference/visibility-and-privacy.html
- RustReference:     https://doc.rust-lang.org/reference/types/pointer.html
- RustCost:          gunbc-internal (no upstream URL applies; the U1
                     one-homomorphism-with-cost discipline pins it)

Comment-only, additive. The header `Anchor:` root line preserved verbatim.

Test plan:
- v2-compiler compile --source-root src/v4 --output-dir /tmp/v4-stage1-rust
  --target dag → 0 diagnostics. VERIFIED post both edits.
- P1 modeling-faithfulness restored on visibility: the partition grounds
  in Reference §visibility-and-privacy's fundamental form.
- P2 boundary-discipline restored: path fact preserved structurally
  (`pub(in crate::outer_mod)` representable).
- Doc-anchor convention established for python/go/cpp/typescript fan-out
  to mirror; ready for that the moment the operator ratifies the rust
  shape + the rest of the queued findings are addressed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… (TypeNoBounds preserved)

Operator BLOCKING inline review (briansrls 2026-05-16T01:06:34Z):
"RustReference is declared as a typed reference but only carries kind and
lifetime, so the ReferenceType referent TypeNoBounds is lost and &'a i32 /
&'a str collapse to one fact, violating extdeps fidelity and P2 boundary
discipline; see https://doc.rust-lang.org/reference/types/pointer.html."

Verified against Reference §types-pointer: the ReferenceType grammar is
`&'lifetime mut? TypeNoBounds` — THREE structural coordinates (lifetime ×
reference-kind × referent type). The prior `RustReference { kind,
lifetime }` shape dropped the referent fact; `&'a i32` and `&'a str`
both produced the same RustReference value, collapsing distinct types.
INVARIANTS P1 modeling-faithfulness + P2 boundary-discipline violations.

Fix: add `referent: Node` field. Node is the bounded kernel's single
recursive type per node.dag A1 — same shape as `Edge.target: Node` and
`Diagnostic.correction Suggested(Node)`. Any type expression IS a Node
(per feedback_nodes_are_nodes — there is no separate "TypeNoBounds
alias"). Whether the referent is in fact a kind=TypeNode Node is a
structural well-formedness invariant the LanguageModel grammar enforces,
not a type-level constraint here (the same discipline node.dag's
`node_well_formed` applies to connective child shapes).

  type RustReference {
    kind: RustReferenceKind
    lifetime: Symbol
    referent: Node
  }

Now `&'a i32` ↔ `RustReference { kind: Shared, lifetime: 'a, referent:
<i32 Node> }` is distinct from `&'a str` ↔ `RustReference { kind: Shared,
lifetime: 'a, referent: <str Node> }`. Three structural coordinates per
the Reference grammar; the IN-B "intrinsic to the type signature" claim
now spans all three.

Import expanded: `import v4.std.node { Node, Symbol }` (was `{ Symbol }`
only — Node added for the referent field).

Header updates:
- Owns line: RustReference's three coordinates now spelled out — kind +
  lifetime Symbol + referent Node — with explicit "&'a i32 / &'a str
  distinct facts (P1/P2 fidelity)" annotation.
- Consumes line: revised to `Node` + `Symbol` from std/node.dag (was
  `Symbol` only). Same scaffold-Consumes reconciliation discipline as
  prior commits. ptx.dag had zero imports; this file now has two,
  driven by the RustReference Conj record's lifetime + referent fields.
- RustReference's modeling-notes block:
  - Opening prose re-cast around the Reference grammar's three-coordinate
    structure
  - New `referent` field documented with the "Node is the bounded
    kernel's single recursive type" rationale + the well-formedness
    boundary note
  - IN-B / ownership lens prose extended: the lens now reads
    (kind, lifetime, referent) coordinates; the referent's own type-
    Node structure is recursively walked as needed for the full type-
    expression grammar (array types, generic instantiations, function
    pointer types, nested references) without this file declaring each
    shape separately

Test plan:
- v2-compiler compile --source-root src/v4 --output-dir /tmp/v4-stage1-rust
  --target dag → 0 diagnostics. VERIFIED post-fix.
- P1 modeling-faithfulness restored on references: the Conj carrier
  grounds in the Reference's `&'lifetime mut? TypeNoBounds` rule's three
  coordinates.
- P2 boundary-discipline restored: referent fact preserved (`&'a i32` ≠
  `&'a str`).
- The `referent: Node` field is the SEAM through which the bundled T-4
  LanguageModel grammar's type-expression productions plug in when they
  land (any Rust type expression IS a Node — the grammar productions
  yield Node trees the referent slot consumes).
- No D1/D2 trap reintroduced: still ZERO inhabitance instance-values,
  ZERO pipeline ops, ZERO Result/Outcome locally invented.

One more BLOCKING queued ("+1 more" per dashboard relay) — addressing
next.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@briansrls

Copy link
Copy Markdown
Contributor Author

This codex review fires against SHA 8ae05ed8 (the WIP commit) — pre-dates the three subsequent operator-BLOCKING fix commits. Verifying each against current HEAD (138ea864d):

Finding 1 — Primitive/scalar/terminal-tuple concepts compressed into one enum.
Addressed in commit ae743e0c3 ("v4 T-4 rust: fix BLOCKING #3174 — Reference primitive-types partition"). Current HEAD's RustScalarKind is Int | Float | Bool | Char | Str | Never — the Reference §3.3-§3.6 primitive-types partition. Unit (and tuple types in general) are explicitly SCOPE NEGATIVE per Reference §3.10 TupleType. RustScalar Disj mirrors the partition with payload-carrying variants where applicable.

Finding 2 — Visibility modeled as four-way terminal enum before a path-scoped carrier exists.
Addressed in commit d90431ee0 ("v4 T-4 rust: fix BLOCKING #3174 visibility + add per-carrier Spec doc-anchors"). Current HEAD's RustVisibility is Private | Pub | PubIn { path: List<Symbol> } — path-carrying in the substrate declaration itself, NOT deferred to LanguageModel. pub(in crate::outer_mod) is representable; pub(crate)/pub(self)/pub(super) fold into PubIn per the Reference's stated equivalences.

Finding 3 — Reference modeled as borrow qualifiers instead of type constructor over a referent type.
Addressed in commit 138ea864d ("v4 T-4 rust: fix BLOCKING #3174 — RustReference adds referent: Node"). Current HEAD's RustReference is { kind: RustReferenceKind, lifetime: Symbol, referent: Node } — three structural coordinates per the Reference &'lifetime mut? TypeNoBounds grammar. &'a i32 and &'a str are now distinct facts.

The codex review's exploratory observation about the green ledgers + RustCost 🟡 scaffold bridge remains accurate (no change required).

If a re-trigger against current HEAD lands new findings, addressing them as separate commits per the same discipline.

— sent from loyal-koi-702

@briansrls

Copy link
Copy Markdown
Contributor Author

Thanks — APPROVE noted. This review fires at SHA ae743e0c3 (the Str/Never fix), pre-dating the next two BLOCKING fixes. Both exploratory observations are already addressed in subsequent commits:

Observation 1 — Process-noise density (msg_ / codenames).*
Addressed in detail in issuecomment-4464926199: the references are load-bearing under the v4 named-trigger STOP-and-escalate discipline (operator directive msg_4f7e1280 reinforcement msg_8b477982). Each msg_* is the auditable anchor for a defer-with-named-trigger vs. the FORBIDDEN stub-to-keep-moving. The PR body itself serves as the public-surface view; the internal-id density lives inside Owned-ELSEWHERE seams where it's audit-load-bearing. Manager ratified the deferral discipline as EXEMPLARY on those grounds.

Observation 2 — RustVisibility and pub(in path) folding into Super.
Addressed by commit d90431ee0 ("v4 T-4 rust: fix BLOCKING #3174 visibility + add per-carrier Spec doc-anchors"). The "folding into Super" simplification was correctly flagged as a sanity-check item and was subsequently called out as a BLOCKING operator finding (the path-fact-drop violated P1/P2 fidelity). Current HEAD's RustVisibility is now Private | Pub | PubIn { path: List<Symbol> } — the Reference's fundamental form with the SimplePath carried structurally, NOT folded. pub(in crate::outer_mod) is representable.

A re-trigger against current HEAD 138ea864d would land against the post-BLOCKING form for both observations.

— sent from loyal-koi-702

briansrls added a commit that referenced this pull request May 16, 2026
…rced (review #3170)

briansrls BLOCKING review on PR #3170 at line 592: the Conj-record
`RegisterScalar { kind: RegisterScalarKind, width: RegisterWidth,
state_space: StateSpace }` admitted illegal kind×width combinations
(Predicate+Bits64, Float+Bits8, Unsigned+Bits128, Bits+Bits1, etc.)
pending a "future check" — exactly the v3 fail-open failure mode
INVARIANTS P2 illegal-states-unrepresentable + Practice 2/6 forbid,
and contradicting the rust.dag #3174 precedent that ratified Disj-
with-payloads as the dissolved form.

Refactored to mirror rust.dag #3174's Disj-with-named-field-variant-
payloads shape:

DROPPED:
- `RegisterWidth` enum (was a meta-enum of all 6 widths combined —
  parallel-rep of the per-kind admissible sets). Its Bits1 variant
  was unused after refactor (Predicate's 1-bit width is implicit,
  no payload).

ADDED (each with full 5-pattern Practice-4 ledger):
- `BitsWidth` = Bits8 | Bits16 | Bits32 | Bits64 | Bits128 (5 widths
  PTX admits for `.b{n}`; `.b1` is not in the spec)
- `IntegerWidth` = Bits8 | Bits16 | Bits32 | Bits64 (4 widths PTX
  admits for typed `.u{n}` / `.s{n}`; `.u128` / `.s128` / `.u1` /
  `.s1` are not in the spec)
- `FloatWidth` = Bits16 | Bits32 | Bits64 (3 widths PTX admits for
  typed `.f{n}`; `.bf16` is a SEPARATE kind, scope-negative)

REFACTORED:
- `RegisterScalar` from Conj record to 5-variant Disj-with-payloads:
    BitsScalar      { width: BitsWidth,    state_space: StateSpace }
    UnsignedScalar  { width: IntegerWidth, state_space: StateSpace }
    SignedScalar    { width: IntegerWidth, state_space: StateSpace }
    FloatScalar     { width: FloatWidth,   state_space: StateSpace }
    PredicateScalar { state_space: StateSpace }
  Each variant carries EXACTLY its kind-admissible width sub-enum
  (or no width payload, for Predicate's intrinsic 1-bit) — illegal
  kind×width pairs are now STRUCTURALLY UNREPRESENTABLE, not deferred
  to a check. State_space is repeated on every variant (every typed
  register lives in a state space).
- Added 5-pattern Practice-4 ledger for RegisterScalar (Disj now
  needs one; the prior Conj record carried none).
- RegisterScalarKind now explicitly framed as a meta-classifier of
  the Disj's variants (not a separate axis); ledger updated to note
  the Cartesian product is HETEROGENEOUS by kind (each kind's
  admissible-width sub-enum differs), so the cross-product lives
  in the Disj structure, not in a flat grid.

HEADER UPDATES:
- Owns list line 43: "RegisterWidth (b1/b8/b16/b32/b64/b128)"
  replaced with "BitsWidth / IntegerWidth / FloatWidth (per-kind
  admissible-width sub-enums — kind × width admissibility is
  structurally enforced by RegisterScalar's Disj-with-payloads
  below, not deferred to a check)"
- Consumes block: "Dim3 component, RegisterWidth bit-count surface"
  → "Dim3 component; the per-kind width sub-enums are closed enums,
  not Int-carrying"
- Each new width sub-enum carries a `// Spec:` URL to
  docs.nvidia.com/cuda/parallel-thread-execution/index.html#fundamental-types

Re-verified: v2-compiler compile --source-root src/v4 --target dag →
0 diagnostics (63 modules, 1 emitted).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@briansrls

Copy link
Copy Markdown
Contributor Author

Thanks — APPROVE noted. Addressed the exploratory observation about the "(no STOP)" title ambiguity by adding a one-line clarifying note at the top of the PR body. The clarification names that "(no STOP)" follows the ptx.dag #3170 framing — it means no C1 substrate extension was triggered (no 7th connective, no 6th behavior from this slice); operational/deferral STOPs (the defer-with-named-trigger seams for D1/D2) are present and load-bearing per the manager directive, which is a separate axis.

No code change needed — this was purely a PR-body readability fix.

— sent from loyal-koi-702

briansrls added a commit that referenced this pull request May 16, 2026
…#3180)

codex/codex-default REQUEST_CHANGES on PR #3180 at line 86 / 726
(observation #2): the doc described a top-level carrier
`PythonScalarKind` in the Owns block + section header, but the
actual declaration is `type PythonScalar`. INVARIANTS P1 modeling-
faithfulness / "documentation describes live state" violated;
unclear which name is canonical for downstream workers.

Resolution: align doc to code (drop phantom `PythonScalarKind` doc
references; PythonScalar is the canonical single carrier). The
single-carrier collapse is INTENTIONAL — explained explicitly in the
PythonScalar modeling note as a Python-vs-rust structural difference:

  rust.dag #3174 declares TWO scalar carriers (RustScalarKind flat
  6-way meta-enum + RustScalar Disj-with-payloads typed-value form)
  because the typed-value form needs WIDTH payloads the meta-
  classifier doesn't.

  Python has NO orthogonal width axis (per header Python-particulars
  (a) — int arbitrary-precision, float machine-level double
  precision, no per-kind width discriminator). So the meta-
  classifier and the typed-value form COLLAPSE INTO ONE Disj:
  PythonScalar's variants (Numeric / String / Singleton) ARE the
  3-category meta-tags AND the typed-value variants in one. No
  separate `PythonScalarKind` exists because no orthogonal axis to
  factor across exists.

Changes:
- Owns block line 86-89: dropped phantom `PythonScalarKind` row;
  expanded PythonScalar row to explicitly note it serves both the
  3-category kind-classifier role AND the typed-value role in one
  carrier, with a pointer to the modeling-note for the
  Python-vs-rust rationale.
- Line 360: "see ... PythonScalarKind below" → "see PythonScalar
  below" (the actual referenced carrier).
- Section header line 750: "PythonScalarKind — the closed Python
  top-level primitive-scalar category partition" → "PythonScalar
  — the closed Python top-level primitive-scalar typed-value Disj"
  + new "SINGLE-CARRIER CONSOLIDATION" subsection explaining the
  Python-vs-rust difference and naming the codex finding as the
  correction driver.

Remaining `PythonScalarKind` mentions in the file are INTENTIONAL —
inside the explanatory note describing why no separate
PythonScalarKind type exists, citing the codex finding.

Re-verified: v2-compiler compile --source-root src/v4 --target dag →
0 diagnostics (63 modules, 1 emitted).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review metadata

  • Provider / model: codex / unknown
  • Commit: 138ea864 · Trigger: schedule
  • Thinking: 269s wall

BLOCKING (1)

Root Cause

  • src/v4/extdeps/languages/rust.dag Visibility canonicalization keeps all path-restricted spellings on the semantic scope carrier → collapse pub(self) and pub(in self) to Private and reserve PubIn for non-self ancestor scopes that are semantically wider than private.

Non-blocking — Strengths

  • src/v4/extdeps/languages/rust.dag The primitive-type and reference fixes are clean: the spec-critical fields now flow forward, the new coproducts carry dissolution ledgers, and the RustCost bridge is documented, bounded, and trigger-named.

⚠️ One visibility canonicalization issue still creates duplicate authority for pub(self) versus private visibility.

Comment thread src/v4/extdeps/languages/rust.dag Outdated
// construction; the Disj-with-payloads is the dissolved form
// per P2 + Practice 2/6 + M4).
// 3. Algebraic form — PARTIAL: visibility scopes form a partial
// order (Private ⊑ PubIn { path: [self] } ⊑ PubIn { path:

This comment was marked as resolved.

@briansrls

Copy link
Copy Markdown
Contributor Author

This finding is verbatim BLOCKING #1 from the earlier dashboard relay (operator review 2026-05-16T01:06:34Z, line 609 at that time). It was addressed in commit `ae743e0c3` ("v4 T-4 rust: fix BLOCKING #3174 — Reference primitive-types partition (drop Unit, add Str + Never)") and verified against current HEAD `138ea864d`:

```
type RustScalarKind
= Int
| Float
| Bool
| Char
| Str
| Never
```

Unit is removed from the partition; Str and Never are added per Reference §3.3-§3.6. () (the zero-tuple) is explicitly SCOPE NEGATIVE in the header modeling notes (it's a TupleType per §3.10, not a primitive scalar — deferred to the future tuple-types substrate). The fix follows the exact line of reasoning in the BLOCKING.

The relay appears to be re-firing on a stale SHA. The dashboard warning says "the bot may arrive after fix attempts" — confirming verification rather than dismissing.

If you'd like to re-trigger a review against current HEAD 138ea864d the partition should land clean. "+4 more queued" — standing by; will verify each against current HEAD before acting.

— sent from loyal-koi-702

@briansrls

Copy link
Copy Markdown
Contributor Author

This is verbatim BLOCKING #2 from the earlier dashboard relay (operator review 2026-05-16T01:06:34Z). Addressed in commit d90431ee0 ("v4 T-4 rust: fix BLOCKING #3174 visibility + add per-carrier Spec doc-anchors"). Current HEAD 138ea864d at line 990:

type RustVisibility
  = Private
  | Pub
  | PubIn { path: List<Symbol> }

The Reference's fundamental form is preserved — PubIn carries the SimplePath as List<Symbol>. pub(crate) / pub(self) / pub(super) fold into PubIn { path: [crate-symbol] } / [self-symbol] / [super-symbol] per the Reference's stated equivalences. Multi-segment paths like pub(in crate::outer_mod) represent as PubIn { path: [crate-symbol, outer_mod-symbol] } — path fact preserved structurally, not dropped.

Stale relay against a pre-fix SHA. "+3 more queued" — continuing to verify each against current HEAD before acting.

— sent from loyal-koi-702

@briansrls

Copy link
Copy Markdown
Contributor Author

Verbatim BLOCKING #3 from the earlier dashboard relay. Addressed in commit 138ea864d ("v4 T-4 rust: fix BLOCKING #3174 — RustReference adds `referent: Node` (TypeNoBounds preserved)"). Current HEAD at line 1063:

type RustReference {
  kind: RustReferenceKind
  lifetime: Symbol
  referent: Node
}

All three coordinates of the Reference &'lifetime mut? TypeNoBounds grammar now structurally carried. &'a i32 and &'a str are distinct facts. referent: Node per A1 (the bounded kernel's single recursive type, same shape as Edge.target and Diagnostic.correction Suggested(Node)); import expanded to import v4.std.node { Node, Symbol }.

Stale relay. "+2 more queued" — standing by.

— sent from loyal-koi-702

…ation)

Operator BLOCKING inline review at rust.dag:962 (briansrls 2026-05-16T02:26:00Z):
"RustVisibility treats Private as distinct from PubIn { path: [self] }, but
the Rust Reference says pub(self) is equivalent to not using pub at all
(https://doc.rust-lang.org/reference/visibility-and-privacy.html), so the
carrier has two authorities for one visibility scope under INVARIANTS P2."

Verified — the Reference §visibility-and-privacy states:
  "pub(self) is the same as pub(in self) AND is the same as not using
   pub at all."

So `pub(self)` / `pub(in self)` / no-modifier are THREE syntactic forms
for ONE semantic visibility scope. My prior PubIn fold admitted ALL
`pub(in path)` forms — including `pub(in self)` as `PubIn { path:
[self-symbol] }`. That created two STRUCTURAL representations of the
same visibility: `Private` AND `PubIn { path: [self-symbol] }`. P2
single-authority violation: two authorities for the no-modifier scope.

Fix:
- Doc-comment update: `Private` is now explicitly the canonical
  representation of `pub(self)` / `pub(in self)` / no-modifier (per the
  Reference's three-way equivalence). PubIn's doc states only
  `pub(crate)` / `pub(in crate)` / `pub(super)` / `pub(in super)` /
  arbitrary `pub(in path)` fold into PubIn — pub(self) family
  canonicalizes to Private.
- New `rust_visibility_well_formed(v: RustVisibility) -> Bool`
  well-formedness fn declared. PubIn { path: [self-symbol] } is
  documented as ill-formed; producers MUST canonicalize to Private.
- 🟡 SCAFFOLD invariant: same producer-obligation shape as Dim3 /
  RustCost. The actual check `path == [self-symbol]` requires
  comparing against a canonical `self` Symbol, which K-1 forbids
  minting in data literals. Until std/ exposes a canonical
  `self_symbol` surface OR std/cardinality.dag lands a refined-path
  carrier admitting only non-[self] paths, the fn returns `true`
  unconditionally and the invariant is producer-obligated and
  documented. Dissolution trigger named.
- 5-pattern Practice-4 ledger Pattern-3 (Algebraic form) updated:
  the partial-order chain previously listed `Private ⊑ PubIn { path:
  [self] } ⊑ ...` which was contradictory under the fix (those are
  the same scope). Now: Private ⊑ PubIn { path: [super] } ⊑ PubIn
  { path: [crate] } ⊑ Pub; pub(self) ≡ Private is not a separate
  level.
- Terminal note: lists the three-way canonical mapping explicitly
  (`pub(self)` → Private, NOT PubIn).
- BLOCKING-correction history extended: this is the second visibility
  BLOCKING — first dropped the path fact (commit d90431e), second
  admitted duplicate authority for pub(self). Both now corrected.

Test plan:
- v2-compiler compile --source-root src/v4 --target dag → 0 diagnostics.
  VERIFIED post-fix.
- P2 single-authority restored: each Reference visibility scope has
  exactly ONE canonical representation in the partition.
- Producer-obligation invariant declared via well-formedness fn (same
  shape as Dim3/RustCost 🟡 bridge — producer-side until refined-path
  substrate lands).
- Dissolution trigger named: std/ canonical-self-symbol surface OR
  std/cardinality.dag refined-path carrier.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@briansrls

Copy link
Copy Markdown
Contributor Author

This codex BLOCKING is the same pub(self) / Private duplicate-authority issue the operator flagged at the inline review 2026-05-16T02:26:00Z (rust.dag:962). Both reviews were against SHA 138ea864d. Addressed in commit e878926ce ("v4 T-4 rust: fix BLOCKING #3174 — pub(self) ≡ Private (P2 canonicalization)"), which is current HEAD.

The fix:

  • Private is now the canonical representation for pub(self) / pub(in self) / no-modifier (per Reference's three-way equivalence).
  • PubIn retains the SimplePath for pub(crate) / pub(super) / arbitrary pub(in path) only — pub(self) family does NOT fold into PubIn.
  • New rust_visibility_well_formed fn declared as the producer-side invariant (🟡 scaffold — same shape as Dim3 / RustCost; actual self-symbol comparison rides T-3 once std/ exposes a canonical-symbol surface).
  • Ledger Pattern-3 partial-order corrected: pub(self) ≡ Private is not a separate level.

The codex's "Non-blocking — Strengths" note on primitive-type / reference fixes + RustCost bridge accurately reflects the post-fix state.

A re-trigger against current HEAD e878926ce should land clean.

— sent from loyal-koi-702

briansrls and others added 4 commits May 16, 2026 02:37
…e (Bool worked example)

Per operator conversational request 2026-05-16 ("i basically just want
the shape ready - i.e. bit or something"): the IR ↔ Rust mapping SHAPE
gets fleshed out now so it's ready to land row-by-row as std/ scalar
types reach merged state. Bool is the centered worked example since
PR #3166 (std/logic.dag) is the readiest in-flight T-3 unblock.

Added:

(1) Per-primitive named inhabitants — 18 typed `data` instances of
    `RustScalar`'s closed-enum payload-bearing variants, one per Rust
    primitive type. NOT algebra-inhabitance (no D2 trap); just typed
    VALUES of the closed Disj:
      - 6 signed integer primitives (rust_i8/i16/i32/i64/i128/isize)
      - 6 unsigned integer primitives (rust_u8/u16/u32/u64/u128/usize)
      - 2 IEEE-754 float primitives (rust_f32/rust_f64)
      - 4 reference primitives (rust_bool/rust_char/rust_str/rust_never)
    Each is a structurally-distinct value of RustScalar; emit/ingest
    dispatch on these by STRUCTURAL identity, never by spelling (K-1).

(2) `IrToRust` Conj carrier — the IR-type ↔ Rust-primitive
    correspondence shape. One row per std/ canonical carrier ↔ Rust
    primitive emission. Fields:
      ir_carrier: Node       // name-reference to a std/ type
      rust_repr:  RustScalar // one of the 18 per-primitive inhabitants
    emit (T-10) reads these rows; ingest (C5 reverse direction) walks
    them backwards. Same shape per-language across fan-out.

(3) Bool worked example (comment-only — std/logic.dag's Bool not yet
    merged in PR #3166):
      // import v4.std.logic { Bool }
      // data bool_to_rust_bool: IrToRust = IrToRust {
      //   ir_carrier: Bool,
      //   rust_repr:  rust_bool
      // }
    Demonstrates emit dispatch (Bool-typed value → BoolScalar →
    Rust source "bool") and ingest reverse-walk (parsed "bool" →
    BoolScalar → Bool-typed Node).

(4) Per-row TestClaim shape sketch (also comment-only — pending
    std/verification.dag T-3 Wave-A2):
      // data t_bool_to_rust_bool_roundtrip: TestClaim = TestClaim {
      //   kind: RoundTrips, ...
      // }
    The fully-instrumented testcase rides three landings: (a)
    std/<scalar>.dag, (b) this PR's shape (current), (c)
    std/verification.dag's TestClaim schema.

(5) Status snapshot of in-flight T-3 PRs naming which IrToRust rows
    each unblocks (Bool ← #3166, Nat ← #3165, etc.). The MISSING list
    (std/integer.dag / std/machine.dag / std/float.dag / std/text.dag /
    std/verification.dag) is named explicitly so the T-4 manager
    driving T-3 has the dependency map.

Discipline preserved:
- NO algebra-inhabitance instance-values authored pre-D2 (`data X:
  OrderedRing<...> = ...`). The 18 named primitives are typed values
  of a closed Disj, not algebra inhabitances — different shape, not
  D2 trap.
- NO stubs of pipeline ops (emit_rust / parse_rust). The IrToRust
  rows declare structural correspondence; emit/parse remain T-7/T-10
  with the D1 Outcome carrier dependency (#3181 in flight).
- All deferrals carry named owners + dissolution triggers per the
  manager reinforcement msg_8b477982 discipline.

Test plan:
- v2-compiler compile --source-root src/v4 --output-dir /tmp/v4-stage1-rust
  --target dag → 0 diagnostics. VERIFIED.
- 18 per-primitive named inhabitants resolve against the RustScalar
  closed Disj.
- IrToRust carrier shape compiles (Conj record over Node + RustScalar).
- Worked example + TestClaim sketches are comments only (no
  data-instance rows authored pre-T-3).
- Shape is ready for incremental row landing — one row per std/
  scalar PR merge (Bool/Nat/Int/Float/Char/Str/Never).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ral fix)

Per claude-opus-4-7 review observation 2026-05-16T02:35:05Z (PR #3174):

> "`rust_visibility_well_formed` (line ~1080) returns `true` for all
> variants with a "PRE-T-3 LIMITATION" note saying the real check
> can't be written because K-1 forbids minting `Symbol` literals. The
> function is documented as a scaffold with named dissolution trigger,
> so this is the legitimate defer-with-trigger form rather than a stub
> — but it is worth noting that the function currently asserts an
> invariant it doesn't enforce. A downstream consumer naïvely calling
> it would get a false sense of validation. Consider whether the
> producer-obligation phrasing in the header is sufficient, or whether
> the fn should not exist at all until it can do real work."

This is exactly the stub-to-keep-moving anti-pattern the manager
reinforcement msg_8b477982 named as the FORBIDDEN deferral. A fn
named `*_well_formed` returning `true` unconditionally is a
false-validation surface — a naive consumer reading "is this value
well-formed? Yes, the substrate said so" would have no idea the
check is a noop. The fact that I added it (commit e878926) under
the 🟡-scaffold framing was the smell; the review correctly named
the anti-pattern.

Fix: REMOVE the fn entirely. The producer-obligation invariant lives
as DOCUMENTED-ONLY text in the RustVisibility doc-comment, alongside
explicit named conditions under which a real fn would land:
  (a) std/ exposes a canonical self_symbol via a typed boundary
      surface, enabling a working check, OR
  (b) std/cardinality.dag lands a refined-path carrier admitting only
      non-[self] paths (illegal states type-unrepresentable, no fn
      needed).

The doc-comment now explicitly states:
- NO fn is declared (the prior `rust_visibility_well_formed` was a
  false-validation stub).
- The invariant lives as producer obligation until the substrate can
  actually enforce.
- Downstream consumers reading PubIn MUST NOT assume any
  well-formedness check has validated the path.

This is the same discipline as the Dim3 / RustCost 🟡 scaffolds —
applied at the DOCUMENTATION layer, NOT as a noop fn. The proper
end-state has the fn appear only when it can do real work.

Test plan:
- v2-compiler compile --source-root src/v4 --output-dir /tmp/v4-stage1-rust
  --target dag → 0 diagnostics. VERIFIED post-removal.
- No false-validation surface introduced.
- Producer obligation explicit + dissolution trigger named.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…o Self variant)

Codex REQUEST_CHANGES (codex-default 2026-05-16T02:51:57Z):

> "RustVisibility = Private | Pub | PubIn { path: List<Symbol> } still
> admits the illegal duplicate-authority state PubIn { path:
> [self-symbol] }, and the diff explicitly leaves that invariant as a
> producer-side doc comment only. ... the single-authority rule for
> pub(self)/pub(in self) vs Private is not structurally enforced by
> the model being introduced here. ... On substrate-facing modeling
> work, that boundary should be encoded or blocked structurally rather
> than documented."

Codex is correct. My prior remediation (commit 03a43b7 — remove the
noop well-formedness fn, leave the invariant as a doc-comment) moved
the smell from "noop validator" to "documented-only," but the actual
structural state `PubIn { path: [self-symbol] }` remained CONSTRUCTIBLE.
modeling-discipline.md §Practices 2 & 6 require illegal states
unrepresentable; INVARIANTS P2 require single-authority structurally.

Fix: introduce `RustPathSegment` as a typed closed-Disj classifier
between RustReferenceKind and RustVisibility, with NO `Self` variant:

  type RustPathSegment
    = Crate
    | Super
    | Named { id: Symbol }

`RustVisibility.PubIn` updated to `{ path: List<RustPathSegment> }`.
Now `PubIn { path: [Self] }` is STRUCTURALLY UNREPRESENTABLE — Self
isn't a constructible segment kind. The duplicate-authority for the
no-modifier visibility scope is impossible at the TYPE level, not just
forbidden by convention.

Canonicalization rules (now type-enforced):
- `pub(crate)` / `pub(in crate)` → `PubIn { path: [Crate] }`
- `pub(super)` / `pub(in super)` → `PubIn { path: [Super] }`
- `pub(in crate::outer_mod)` → `PubIn { path: [Crate, Named { id: outer_mod }] }`
- `pub(self)` / `pub(in self)` / no-modifier → `Private` (the only
  representation; PubIn with Self segment is unrepresentable)
- `pub(in self::outer_mod)` → `PubIn { path: [Named { id: outer_mod }] }`
  (parse boundary drops the leading self per Reference §paths —
  `self::X` IS `X` from current module's POV)

Scope-negative (named C1 edit):
- `$crate` macro-context segment — not modeled in this slice; lands
  as a `MacroCrate` variant in RustPathSegment when hygienic-macro
  support lands.

Documentation cleanup:
- Removed the documented-only "producer-obligation invariant" block
  (the false-validation surface the codex / claude-opus reviews
  correctly flagged).
- Updated RustVisibility's BLOCKING-correction history: now THREE
  BLOCKING fixes — (1) path fact dropped, (2) PubIn admitted Self
  case, (3) doc-only enforcement isn't structural; final fix is
  type-level via RustPathSegment.
- 5-pattern Practice-4 ledger on RustVisibility's Pattern-3 partial-
  order updated (paths use RustPathSegment variants, not Symbol).
- Full 5-pattern ledger on the new RustPathSegment carrier.
- Header Owns line updated to mention RustPathSegment.

Test plan:
- v2-compiler compile --source-root src/v4 --output-dir /tmp/v4-stage1-rust
  --target dag → 0 diagnostics. VERIFIED.
- `PubIn { path: [Self] }` structurally unrepresentable (Self not a
  RustPathSegment variant — try to write it; v2-compiler diagnoses).
- `PubIn { path: [Crate] }`, `PubIn { path: [Super] }`, `PubIn { path:
  [Crate, Named { id: ... }] }` all constructible and well-typed.
- The 18 per-primitive named inhabitants + IrToRust shape unaffected.
- Bool worked-example unaffected.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds the lane-1 placement flag per T-4 mgr directive msg_148854d5
2026-05-16, surfacing the P2 shared-resolver-type-home decision
merry-ibex-337's peer-pair cross-check identified (msg_8dcbc645).

The encoded DECISIONS.md D2 row (commit 44a37ad) pinned the
D2a(2) "grounding map (surface spelling)" SHAPE but did not pin
where the shared resolver TYPE lives in the closed file tree. This
rust.dag declaration is PROVISIONAL:

- one decl alone is NOT a P2 violation; parallel-declaration
  would emerge only if sibling extdeps/languages/ files re-declare
  an identical type
- per-primitive INSTANCES correctly stay per-file; only the TYPE
  needs ONE home
- the D2 resolver SHAPE is canonical regardless of where the type
  ultimately lives — fan-out files defer D2a(2) under the SAME
  named trigger, no local re-declaration

Named owner = operator (escalation in flight per mgr lane); named
dissolution trigger = operator pins GroundingMap's home, on that
decision this declaration either stays (rust-as-shared-authority)
or moves to the chosen home with rust.dag adding the import.

Sibling 🟡 TRACKED-SCAFFOLD block added to the GroundingMap
declaration's leading doc; Owns: bullet annotated with the
placement-pending parenthetical pointing at the resolver-block
note. Declaration body unchanged — only its PLACEMENT is the
operator-pending facet; a future home change is a relocation +
import edit, NOT a re-modeling.

v2-compiler: 0 diagnostics.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review metadata

  • Provider / model: codex / unknown
  • Commit: 57f2f029 · Trigger: schedule
  • Thinking: 250s wall

BLOCKING (1)

Root Cause

  • src/v4/extdeps/languages/rust.dag Rust overflow semantics collapsed the build/flag/implementation-discretion axis into debug/release defaults → model that configuration axis explicitly or defer OverflowDisposition until the resolver can carry it faithfully.

⚠️ One new overflow-fidelity issue remains, and prior Bool-authority comments 3252522934/3252591047 are still unresolved.

Comment thread src/v4/extdeps/languages/rust.dag Outdated
// case mirrors structurally with different fields.
type OverflowDisposition<IRCarrier> {
debug_default: OverflowAction
release_default: OverflowAction

This comment was marked as resolved.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified the finding against the Rust Reference cited (behavior-not-considered-unsafe.html#integer-overflow). The Reference says exactly:

When the programmer has enabled debug_assert! assertions ... implementations must insert dynamic checks that panic on overflow. Other kinds of builds may result in panics or silently wrapped values on overflow, at the implementation's discretion.

You're right: release_default: OverflowAction pins to ONE value when the Reference says it's implementation's discretion (commonly driven by -C overflow-checks, build-config tooling state, not a language fact). P1 modeling-faithfulness violation per INVARIANTS.

Fixed in dfb9464. Specifically:

  1. Dropped release_default from OverflowDisposition. The carrier now has only debug_assert_required_action: OverflowAction — which IS a deterministic structural language fact per the Reference ("implementations MUST insert dynamic checks that panic"). Non-debug-assert behavior is not recorded as a structural fact; doc-block explains why (recording one Action over-determines; recording the closed permitted-set is tautological with OverflowAction itself).

  2. Reframed OverflowAction from "runtime-dispatch classifier" (implied a single per-build-mode dispatch) to "permitted SET" per the Reference's exact wording ("one of: panic or wrapping").

  3. Spec URL corrected from §types-numeric to the authoritative behavior-not-considered-unsafe.html#integer-overflow (where the overflow rule actually lives).

  4. Explicit per-op forms (wrapping_* / checked_* / saturating_* / overflowing_*) clarified as method-NAME facts on the integer type's library surface (LanguageModel scope, bundled T-4 grammar), NOT OverflowAction variants and NOT OverflowDisposition fields.

  5. Deferred per-integer data rust_<x>_overflow instruction in the alias-deferral block updated to the new shape (OverflowDisposition { debug_assert_required_action: PanicOnOverflow } — the Reference fact uniformly across integer widths).

— sent from loyal-koi-702

@briansrls

Copy link
Copy Markdown
Contributor Author

Review metadata

  • Provider / model: openai-pro / gpt-5-5-pro
  • Commit: f2dcea63 · Trigger: manual
  • Comparison: main @ c8f6d4e0 ... session/loyal-koi-702 @ f2dcea63
  • Conversation: View conversation

1. Story of the diff

This PR adds the first substantial Rust language-spec slice under src/v4/extdeps/languages/rust.dag: it establishes Rust primitive/type-system vocabulary rather than emitter behavior. The load-bearing pieces are the primitive classifiers (RustIntKind, RustIntWidth, RustFloatWidth, RustScalar), reference/visibility carriers (RustReferenceKind, RustReference, RustVisibility, PubInPath), a provisional per-target cost carrier, the D2 per-primitive resolver shape (GroundingMap, OverflowDisposition), and the first concrete Bool row (RustBool = Bool plus rust_bool_grounding). The diff also does a lot of reviewer-facing discipline work: it marks temporary shapes such as PubInPath, RustCost, and GroundingMap as tracked scaffolds with bounds and dissolution triggers, and it explicitly defers primitive alias rows blocked on upstream std carriers.

2. Invariant categories

1. LAYER MODEL — Finding

BLOCKING — target-spec/substrate-adjacent modeling fidelity. The diff touches extdeps/languages/rust.dag, which is not implementation-only Rust; it is modeled target-language authority that downstream resolution/emission will consume. The overflow carrier makes a Rust semantic claim that is too strong:

src/v4/extdeps/languages/rust.dag:1750-1752type OverflowDisposition<IRCarrier> {  debug_default: OverflowAction  release_default: OverflowAction}

and the deferral contract hard-codes the release row as wrapping:

src/v4/extdeps/languages/rust.dag:1798-1802//   - for integer aliases: `data rust_<x>_overflow://     OverflowDisposition<Rust<X>> = OverflowDisposition {//     debug_default: PanicOnOverflow,//     release_default: TwoComplementWrap }` row (D2a(3); Rust//     integer defaults per Reference §numeric apply uniformly

The Rust Reference does not make “release build ⇒ wrap” a reference-level semantic invariant. It says overflow is erroneous; with debug_assert! enabled implementations must insert panic checks, while other builds may panic or silently wrap at the implementation’s discretion, and the operator page says -C debug-assertions and -C overflow-checks control the behavior more directly. Rust Documentation+1 A language-spec carrier should therefore model overflow as configuration/implementation-sensitive, not as a closed debug-vs-release default pair with release_default: TwoComplementWrap.

2. INVARIANTS.md + modeling-discipline.md — Finding

P1 Modeling Faithfulness / fail-closed target grounding. The diff says:

src/v4/extdeps/languages/rust.dag:1680-1684// arithmetic at overflow. Per Reference §types-numeric: in debug// builds the default is panic on overflow; in release builds the// default is two's-complement wrap; explicit per-op variants// (wrapping_*, checked_*, saturating_*, overflowing_*) opt the

That is a reference-grounding error: the Reference leaves non-debug-assertion builds as “may panic or silently wrap,” not a canonical wrap default. Rust Documentation Modeling this as a fixed OverflowAction means downstream consumers can treat an unchecked arithmetic overflow as known wrapping behavior when the modeled target configuration could instead check and panic. The faithful shape should either carry the controlling compiler/profile facts (debug_assertions, overflow_checks) or use a disposition such as MustPanic | MayPanicOrWrap { wrap_convention: TwoComplement }, with explicit wrapping/checked/saturating operations modeled separately.

3. CODING.md — Compliant

The diff is declarative .dag model authoring, not new Rust implementation. It follows the project’s data-over-behavior shape: new concepts are introduced as type / data declarations (RustVisibility, RustReference, GroundingMap, rust_bool_grounding) rather than adding method-heavy Rust surfaces or hidden state.

4. TESTING.md — N/A

N/A — no test files or executable test harnesses are changed in this diff. The blocking issue is a model-fidelity bug in the target-language spec; after correcting the overflow carrier, a small .dag model assertion for the configuration-sensitive overflow shape would be useful, but the absence of tests is not an independent finding here.

5. LOCKED DESIGN DECISIONS — Compliant

No locked design document is edited, and the diff generally preserves the stated D2 resolver direction by using thin per-primitive facts rather than a target-private parallel algebra. For example, the Bool row is a direct alias/grounding pair:

src/v4/extdeps/languages/rust.dag:1771-1775type RustBool = Booldata rust_bool_grounding: GroundingMap<RustBool> = GroundingMap {  spelling: "bool"}

The overflow issue above is a reference-semantics mismatch, not an explicit divergence from a locked design doc.

6. TRACKED vs UNTRACKED DEBT — Compliant

The visible scaffolds are tracked rather than silent. PubInPath documents that only the shape is type-enforced today, bounds producer obligations, and names the future module-tree substrate trigger at src/v4/extdeps/languages/rust.dag:894-928. RustCost documents the illegal-state risk from raw Int, bounds producer use, and names the std/cardinality refinement trigger at src/v4/extdeps/languages/rust.dag:1490-1508. GroundingMap explicitly marks placement as operator-pending, warns sibling target files not to redeclare it, names the owner, and gives the relocation/import dissolution trigger at src/v4/extdeps/languages/rust.dag:1630-1672. That is the right tracked-bridge posture.

2.5. Top-down PM intent review

Finding — same blocker, at PM intent level. The PR’s stated purpose is to model Rust type-system vocabulary and classifiers from the Rust reference surface. The diff instead tells future workers to instantiate all integer alias overflow rows with release_default: TwoComplementWrap at src/v4/extdeps/languages/rust.dag:1798-1802, which would cause faithful implementers of this PR to build the wrong target-semantics contract. The Rust Reference authority is more nuanced: non-debug-assertion builds may panic or wrap, and compiler flags can control the checks directly. Rust Documentation+1 That is semantic dilution of the reference-grounding intent, not just wording drift.

3. Verdict

REQUEST_CHANGES. Most of the slice is careful and well-scaffolded, especially the visibility canonicalization and tracked-deferral comments. The overflow model, however, is a substrate-adjacent target-spec fact and currently encodes a stronger release-build invariant than the Rust Reference supports; that should be fixed before landing.

briansrls and others added 2 commits May 16, 2026 15:53
Per BLOCKING reviewer 2026-05-16T19:26:35Z + Rust Reference
behavior-not-considered-unsafe.html#integer-overflow:

  "When the programmer has enabled `debug_assert!` assertions ...
   implementations must insert dynamic checks that panic on
   overflow. Other kinds of builds may result in panics OR silently
   wrapped values on overflow, at the implementation's discretion."

The previous OverflowDisposition shape (debug_default +
release_default both : OverflowAction) over-determined the Rust
spec — it pinned release_default to a fixed Action when the
Reference says non-debug-assert behavior is implementation-defined
(commonly controlled by `-C overflow-checks`, build-configuration
tooling state, not a language fact). P1 modeling-faithfulness
violation per INVARIANTS.

Fix: drop `release_default`; keep only `debug_assert_required_action`
which IS a deterministic structural language fact per the Reference
(implementations MUST panic in debug_assert builds). The Reference
URL is corrected from §types-numeric to the authoritative
behavior-not-considered-unsafe.html#integer-overflow page (which
is where the overflow rule actually lives).

OverflowAction Disj reframed from "runtime-dispatch classifier"
(implied a single per-build-mode dispatch) to "permitted-set" per
the Reference's exact wording ("one of: panic OR wrapping"). The
explicit per-op forms (wrapping_* / checked_* / saturating_* /
overflowing_*) are clarified as method-NAME facts on the integer
type library surface (LanguageModel scope), not OverflowAction
variants and not OverflowDisposition fields.

Practice-4 ledger position 4 updated (no more "default action at
runtime configuration" framing — single overflow event produces
exactly one action per the Reference). Terminal sentence drops
the stale "OverflowDisposition's separate availability fields"
reference.

Owns: D2-resolver bullet updated. Deferred-instructions for
per-integer rust_<x>_overflow rows updated to the new shape.

v2-compiler: 0 diagnostics.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@briansrls

Copy link
Copy Markdown
Contributor Author

Mapping reply — codex review sha:57f2f029

The codex BLOCKING from the schedule cycle on sha:57f2f029 says:

Rust overflow semantics collapsed the build/flag/implementation-discretion axis into debug/release defaults → model that configuration axis explicitly or defer OverflowDisposition until the resolver can carry it faithfully.

This finding is on a STALE HEAD. Current HEAD is dfb9464 (pushed 2026-05-16T19:58Z). Per the rolling-HEAD discipline + sha-reconcile: verifying against current HEAD before any new fix attempt.

Sha-alignment + per-finding mapping:

The codex finding is the SAME concern as the operator's inline BLOCKING at 19:26:35Z on rust.dag:1753 (comment 3253344017). That comment is already addressed at HEAD dfb9464 (reply 3253382843). Specifically, the fix:

  1. Drops release_default from OverflowDisposition — the carrier now has only debug_assert_required_action: OverflowAction, which IS the deterministic structural language fact per Rust Reference behavior-not-considered-unsafe.html#integer-overflow ("implementations MUST insert dynamic checks that panic on overflow" — debug_assert builds).

  2. Documents the implementation-discretion axis explicitly — the OverflowDisposition doc-block states that builds WITHOUT debug_assert! are implementation-defined per the Reference ("may result in panics or silently wrapped values on overflow, at the implementation's discretion"), commonly driven by -C overflow-checks build-config flag (NOT a language fact). Recording one specific Action would over-determine the spec; recording the closed permitted-set would be tautological with OverflowAction. So the configuration axis is acknowledged as out-of-scope for a language-spec extdeps resolver.

  3. Reframes OverflowAction Disj from "runtime-dispatch classifier" to "permitted SET" per the Reference's exact wording.

  4. Corrects the Spec URL from §types-numeric to the authoritative behavior-not-considered-unsafe.html#integer-overflow page.

This satisfies codex's "model that configuration axis explicitly OR defer until the resolver can carry it faithfully" disposition: the BUILD-FLAG configuration axis is explicitly documented as implementation-defined and NOT recorded (the third option codex didn't enumerate but which is faithful to the Reference's actual framing — non-debug-assert behavior simply isn't a language-spec fact suitable for an extdeps language resolver).

Bool-authority comments 3252522934 / 3252591047: these are sha:a17fcd26-era inline comments (pre-reshape HEAD). At 0328bee the entire IrToRust<Bool> row + data bool_to_rust_bool row was DISSOLVED per the operator-ratified DECISIONS.md D2 row reshape (commit 44a37ad). Current HEAD has type RustBool = Bool as a D2a(1) alias-identity row, where Bool resolves kernel-ambient per STRUCTURE.md:147 to std/logic.dag (which IS landed via #3166). The "IrToRust imports an IR carrier not declared in std/logic.dag" finding referenced a carrier (IrToRust) that no longer exists on the PR. The 9 prior replies on this thread (issue-comments -4466327457 / -4466330090 / -4466472613 / -4466473857 / -4466595731 / -4466762885 / -4467047032 / -4467321512 / -4467748736) walked through this verification each time; the trailing reference in the schedule-cycle review is dashboard re-relay of already-replied state.

— sent from loyal-koi-702

@briansrls

Copy link
Copy Markdown
Contributor Author

Mapping reply — openai-pro REQUEST_CHANGES sha:f2dcea63 issue-comment 4467921022

This is the same overflow-fidelity concern raised by:

  • briansrls operator inline BLOCKING at rust.dag:1753 (comment 3253344017, 2026-05-16T19:26:35Z)
  • codex BLOCKING on sha:57f2f029 (mapping-reply at 4467960932)
  • this openai-pro REQUEST_CHANGES on sha:f2dcea63

Three reviewers converge on the same finding: the prior OverflowDisposition { debug_default, release_default } over-determined the Rust Reference. Already addressed at current HEAD dfb9464.

Sha-alignment + per-finding mapping:

The fix at dfb9464 drops the release_default field. Current shape:

type OverflowDisposition<IRCarrier> {
  debug_assert_required_action: OverflowAction
}

Doc-block notes: "The carrier deliberately does NOT carry a release_default (or any non-debug-assert default) field — per the Reference, builds without debug_assert! 'may result in panics OR silently wrapped values on overflow, at the implementation's discretion.' Recording one Action would over-determine; recording the permitted-set would be tautological with the OverflowAction Disj itself."

This addresses the over-determination by carrying ONLY the deterministic Reference fact (debug_assert builds MUST panic). The implementation-defined release behavior is acknowledged as out-of-scope for a language-spec carrier (it's build-configuration tooling state — commonly driven by -C overflow-checks — not a language fact per Reference).

On openai-pro's two suggested faithful shapes:

"The faithful shape should either carry the controlling compiler/profile facts (debug_assertions, overflow_checks) or use a disposition such as MustPanic | MayPanicOrWrap { wrap_convention: TwoComplement }, with explicit wrapping/checked/saturating operations modeled separately."

My fix takes a third path orthogonal to both: record only the deterministic-MUST fact; treat the impl-defined-MAY axis as documented-not-structurally-encoded. The rationale is that MayPanicOrWrap as a Disj variant encodes "implementation may choose one of these" structurally — but the choice itself isn't a language fact; it's compiler-config state. Encoding it as a Disj variant invites downstream consumers to dispatch on it, when in fact no spec fact is available for that dispatch.

The wrap_convention: TwoComplement part of openai-pro's suggested shape IS captured at HEAD — but via the OverflowAction Disj's closed two-variant set {PanicOnOverflow, TwoComplementWrap}. There's no ArbitraryWrap variant; the only wrap variant IS two's-complement, structurally encoding the Reference's "if wrap, two's-complement" requirement. The Disj is now reframed as "permitted SET" (not "runtime-dispatch classifier") matching the Reference's exact wording.

Explicit per-op forms (wrapping_* / checked_* / saturating_* / overflowing_*) clarified in the OverflowAction doc-block as method-NAME facts on the integer library surface (LanguageModel scope, bundled T-4 grammar), NOT OverflowAction variants and NOT OverflowDisposition fields — addressing openai-pro's "with explicit wrapping/checked/saturating operations modeled separately."

Reshape-offered if structurally-richer is preferred:

If openai-pro prefers the more-structural form (OverflowDisposition as a Disj like MustPanic | MayPanicOrTwoComplementWrap, capturing the build-mode-axis as a sum type), I can reshape — that's also faithful, just carries more structure than I've chosen to land. The trade-off: the Disj form encodes "implementation may choose" as a structural variant inviting downstream dispatch; my Conj-with-only-deterministic-field form documents impl-defined-as-out-of-scope. Both meet "not over-determining"; either is acceptable per the Reference.

Note: per-integer instance rows are 🟡 TRACKED-SCAFFOLD deferred (pending std/integer.dag T-3 Wave-A3); the carrier's shape only governs the future instance-row form, not anything landing in this PR.

— sent from loyal-koi-702

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review metadata

  • Provider / model: codex / unknown
  • Commit: dfb9464e · Trigger: schedule
  • Thinking: 278s wall

BLOCKING (1)

Root Cause

  • src/v4/extdeps/languages/rust.dag OverflowAction is serving both the non-debug permitted action set and the required debug semantics → split the required debug fact into a constant/marker carrier or otherwise make TwoComplementWrap unrepresentable there.

⚠️ One substrate-shape issue remains before this should land.

Comment thread src/v4/extdeps/languages/rust.dag Outdated
// case is the canonical instance of the D2a(3) shape; the float
// case mirrors structurally with different fields.
type OverflowDisposition<IRCarrier> {
debug_assert_required_action: OverflowAction

This comment was marked as resolved.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified the finding. The prior shape OverflowDisposition<IRCarrier> { debug_assert_required_action: OverflowAction } admits OverflowDisposition { debug_assert_required_action: TwoComplementWrap } as a structurally-valid value, but the Rust Reference (behavior-not-considered-unsafe.html#integer-overflow) fixes that fact: "implementations MUST insert dynamic checks that panic on overflow." Variable field type = illegal-state-constructible = INVARIANTS P2 illegal-states-unrepresentable violation. The finding is correct.

Fixed in c9ba92d. Reshape: replaced the Conj-record-with-OverflowAction-field form with a closed two-variant nullary Disj, structurally pinning both Reference facts:

type OverflowDisposition<IRCarrier>
  = MustPanicOnOverflow
  | MayPanicOrTwoComplementWrap
  • MustPanicOnOverflow — nullary variant; the deterministic Reference fact (debug_assert builds MUST panic) is structurally pinned by variant identity. No payload can carry an alternative action; OverflowDisposition { ... = TwoComplementWrap } is unrepresentable.
  • MayPanicOrTwoComplementWrap — captures the impl-defined-choice case for non-debug-assert builds. The wrap convention (two's-complement per Reference: "implementations must provide well-defined results by using two's complement overflow conventions") is structurally encoded in the variant name — no ArbitraryWrap sibling exists; OverflowAction's closed {PanicOnOverflow, TwoComplementWrap} set encodes the permitted-action axis at the action level.

This matches openai-pro's REQUEST_CHANGES suggested faithful shape (MustPanic | MayPanicOrWrap { wrap_convention: TwoComplement }) — with the wrap-convention encoded in variant naming instead of as a payload, since OverflowAction already structurally constrains wrap to two's-complement.

Practice-4 ledger updated for the new Disj: 5 patterns FAIL; nullary variants ARE the faithful form per pattern-2 (carrying an OverflowAction payload reintroduces exactly the illegal-state this BLOCKING rejected); terminal 🟢 GREEN under #3200 (Bool-shaped on the debug_assert-enabled axis; no namable richer std/ source).

Deferred-instructions block updated for per-integer rust_<x>_overflow rows: two D2a(3) data rows per integer type (= MustPanicOnOverflow and = MayPanicOrTwoComplementWrap). Both are TOP-LEVEL SUM-VARIANT bodies → DOUBLE-deferred under (a) std/integer.dag T-3 Wave-A3 ladder for the alias-target Rust<X>, AND (b) Class-5-Gap-3 closure (top-level ValueBody::Unparsed gap per ROADMAP.md:418; substrate items #920/#1017/#1068). The TYPE shape is canonical regardless of instance-row landing.

v2-compiler: 0 diagnostics through full lower-and-emit pipeline.

— sent from loyal-koi-702

@briansrls

Copy link
Copy Markdown
Contributor Author

Review metadata

  • Provider / model: openai-pro / gpt-5-5-pro
  • Commit: dfb9464e · Trigger: manual
  • Comparison: main @ 606034a2 ... session/loyal-koi-702 @ dfb9464e
  • Conversation: View conversation

1. Story of the diff

This PR turns src/v4/extdeps/languages/rust.dag from a placeholder into the first real Rust target-language model for v4. The core move is to model Rust’s type-system vocabulary as .dag declaration data: closed classifiers for integer kind/width and float width, a payload-bearing RustScalar sum that prevents invalid kind×width states, RustReference with kind/lifetime/referent, canonical visibility carriers, a provisional Rust cost carrier, and D2 resolver carriers plus the first concrete Bool → rust bool grounding row. That aligns with the thesis-level grounding-completeness direction: target primitives should be structurally modeled from the target language reference, with grounding through declared structure rather than name-keyed shortcuts. chatgpt-review-1f141fa7-dc88-4b…

The load-bearing design shape is mostly: “declare the Rust vocabulary now; defer grammar, parse/emit, and non-landed std primitive aliases to named owners/triggers.” That is visible in the declarations at src/v4/extdeps/languages/rust.dag:793-799 (RustScalar), src/v4/extdeps/languages/rust.dag:1342-1345 (RustVisibility), src/v4/extdeps/languages/rust.dag:1459-1463 (RustReference), src/v4/extdeps/languages/rust.dag:1678-1680 (GroundingMap), and src/v4/extdeps/languages/rust.dag:1818-1822 (RustBool + grounding data). The remaining issue I see is not with those declarations themselves, but with stale D2 prose that still instructs a now-superseded inhabitance path.

2. Invariant categories

  1. LAYER MODEL — Finding. This is substrate / target-spec modeling, not implementation-only: it adds v4 target-language carriers and resolver declarations. The issue is that the file now contains two incompatible D2 stories. The same diff correctly says D2 is ratified and that the form is “THREE-THIN-FACTS D2a” — alias identity, grounding map, and operation-semantics carrier — at src/v4/extdeps/languages/rust.dag:127-138. But later it still says:

src/v4/extdeps/languages/rust.dag:733: // SEAM (where D2 inhabitance plugs in). When the D2 form decision

src/v4/extdeps/languages/rust.dag:734: // lands (operator-pending, msg_640d429c), the per-variant

src/v4/extdeps/languages/rust.dag:735: // inhabitance instance-values land in this file with these typed

src/v4/extdeps/languages/rust.dag:736: // variants as their carriers — IntScalar { kind: Signed, width:

src/v4/extdeps/languages/rust.dag:737: // Bits32 } is the carrier for Rust's i32 inhabitance into

src/v4/extdeps/languages/rust.dag:738: // OrderedRing (or its v4-equivalent per the D2-ratified form);

That is a substrate-authority drift: downstream workers could follow the later seam text and attach algebra inhabitance to RustScalar variant values instead of the ratified alias-identity resolver shape. The fix is just to update this seam prose to say RustScalar remains the parse-stage source-syntax classifier and primitive grounding/invariance lands through alias identity + GroundingMap + operation semantics, matching src/v4/extdeps/languages/rust.dag:1548-1559.

  1. INVARIANTS.md + modeling-discipline.md — Finding. Specific principle: P2 Boundary Discipline / single authority, with the modeling-discipline corollary that facts should not be represented in parallel. INVARIANTS says boundaries need one authoritative fact location and warns that duplicate authority causes drift. chatgpt-review-2194da43-88ce-4a…

The declarations mostly honor this: the prior RustScalarKind duplicate partition is gone, RustScalar carries heterogeneous payloads at src/v4/extdeps/languages/rust.dag:793-799, and the D2 block explicitly dissolves the prior registry/table shape at src/v4/extdeps/languages/rust.dag:1548-1559. The stale D2 seam at src/v4/extdeps/languages/rust.dag:733-738, however, reintroduces a second textual authority for where inhabitance should attach. Because this file is itself the language-spec authority, comment drift here is not harmless.

  1. CODING.md — Compliant. The diff is .dag data, not Rust implementation code, and follows the project’s “data + functions, not objects” direction: it introduces declarations like type RustIntKind at src/v4/extdeps/languages/rust.dag:518-520, type RustReference at src/v4/extdeps/languages/rust.dag:1459-1463, and data rust_bool_grounding at src/v4/extdeps/languages/rust.dag:1820-1822, with no hidden mutable state, method surface, trait hierarchy, or impure edge.
  2. TESTING.md — N/A. No tests are added, but this diff is a declaration-only target-spec slice rather than a behavior change, boundary command, or executable parser/emitter path. The appropriate future tests belong with the LanguageModel / parse / emit consumers when those declarations are executed as .dag TestClaim rows, consistent with the current test direction that new boundary intent should default to .dag claims where possible. chatgpt-review-e35a10c4-915c-44…
  3. LOCKED DESIGN DECISIONS — Finding. The diff itself treats D2 as a locked / ratified decision: src/v4/extdeps/languages/rust.dag:127-138 says D2 was ratified and defines alias identity + grounding map + operation semantics as the form, and src/v4/extdeps/languages/rust.dag:1548-1559 says the prior RustScalar registry / IrToRust shape dissolves. The stale seam text at src/v4/extdeps/languages/rust.dag:733-738 still says the D2 decision is operator-pending and that per-variant inhabitance rows land with RustScalar variant carriers. That is not an explicit divergence from the lock; it is unreconciled comment drift.
  4. TRACKED vs UNTRACKED DEBT — Compliant. The actual scaffolds I see are tracked with the required three properties. RustCost names the scaffold, bounds producer use to non-negative values, and gives the std/cardinality refinement trigger at src/v4/extdeps/languages/rust.dag:1495-1513. GroundingMap names the placement owner and trigger at src/v4/extdeps/languages/rust.dag:1660-1672. PubInPath similarly calls out producer-obligation enforcement and the module-tree / ancestor-witness dissolution trigger at src/v4/extdeps/languages/rust.dag:899-933. That matches the project rule that scaffolds need named dissolution triggers. chatgpt-review-2194da43-88ce-4a…

2.5. Top-down PM intent review

Finding. The PR mostly preserves the PM intent: Rust target primitives are being modeled structurally, and the D2 resolver shape is moved away from string/table-style target mapping. The PM-risk is the stale D2 seam: the intended meaning is established by the diff’s own ratified-D2 block at src/v4/extdeps/languages/rust.dag:127-138 and its dissolution of the previous registry/table shape at src/v4/extdeps/languages/rust.dag:1548-1559; the contradictory execution instruction remains at src/v4/extdeps/languages/rust.dag:733-738. A future worker faithfully following that later seam could implement the wrong primitive-grounding path even though the surrounding file says the opposite.

3. Verdict

REQUEST_CHANGES. The modeled carriers look directionally right, and the debt scaffolds are properly bounded, but this is a substrate authority file and it still contains stale D2 instructions that contradict the ratified resolver shape. I would land this after the D2 seam prose is corrected to match the alias-identity / GroundingMap / operation-semantics model already declared elsewhere in the diff.

briansrls added a commit that referenced this pull request May 16, 2026
…ulary + classifiers (no STOP) (#3180)

* v4 T-4 python-slice: extdeps/languages/python.dag — type-system vocabulary + classifiers (no STOP)

Fills src/v4/extdeps/languages/python.dag mirroring the canonical T-4
rust-slice (PR #3174 loyal-koi-702) per manager directive
msg_4f7e1280 fan-out. Declaration-class only: closed-Disj classifiers
+ Conj records for Python's primitive type-system vocabulary, with
structural admissibility enforced. The D1 and D2 dependent pieces
(parse/emit operations + scalar inhabitance instance-values) are
explicitly DEFERRED to their named owners — never improvised.

STRUCTURAL FINDING. Python's type-system surface fits the substrate
(6 connectives + 5 L1 behaviors + Conj/Disj/Atom) without
modification. No 7th connective, no 6th behavior. Python-specific
particulars vs the rust analog:
- NO WIDTH AXIS — Python int is arbitrary-precision (Reference §3.2);
  float is always IEEE-754 binary64. The rust kind×width admissibility
  axis collapses to kind alone, by spec design.
- NUMERIC SUBTYPE TOWER — PEP 285 (bool ⊂ int) + PEP 3141 (Integral ⊆
  Rational ⊆ Real ⊆ Complex). The admissibility axis Python ADDS vs
  rust is the numeric-tower partition.
- THREE SINGLETON TYPES — None / NotImplemented / Ellipsis per
  Reference §3.2. Each one-inhabitant; the cardinality fact rides
  std/cardinality.dag (T-3 wave A3).
- MUTABILITY DEGENERATE AT SCALAR LAYER — only bytearray is mutable
  among scalars; encoded structurally as a variant of PythonStringKind,
  not a separate mutability axis.

CARRIERS DECLARED:

- PythonNumericTower (4-variant Disj: BoolLevel / IntegralLevel /
  RealLevel / ComplexLevel) — PEP 285 + PEP 3141 partition; partial-
  order structurally derived. Full 5-pattern ledger.
- PythonStringKind (3-variant Disj: Str / Bytes / Bytearray) —
  Reference §3.2 textual/byte-sequence partition with mutability
  fixed per variant (Bytes-with-mutable-flag is unrepresentable).
  Full 5-pattern ledger.
- PythonSingletonKind (3-variant Disj: NoneT / NotImplementedT /
  EllipsisT) — Reference §3.2 spec-defined singletons. Full 5-pattern
  ledger.
- PythonScalar (3-variant Disj-with-payloads: Numeric { tower }
  / String { kind } / Singleton { kind }) — hierarchical category ×
  sub-classifier; illegal cross-category combinations (e.g. a
  Singleton with a numeric tower level) are STRUCTURALLY
  UNREPRESENTABLE. The Python analog of rust.dag's
  Disj-with-payloads kind×width admissibility, adapted for Python's
  hierarchical-not-flat partition. Full 5-pattern ledger.
- PythonCost (Conj record: bytecode_cost + allocation_cost) — per-
  target cost-realization carrier shape; 🟡 scaffold for Int
  components per the std/cardinality.dag dissolution trigger
  (precedent: std/diagnostic.dag Extent.ByteRange, ptx.dag Dim3 /
  PtxCost, rust.dag RustCost).

DEFERRED to named owners (Owned ELSEWHERE):
- Scalar inhabitance instance-values → operator D2 form-decision
  (msg_640d429c) + T-3 wave A3 carriers (std/integer.dag /
  std/float.dag / std/logic.dag / std/text.dag). STOP-TRIGGER:
  authoring a placeholder `data python_int_integral: <…> = …` row
  is the FORBIDDEN deferral.
- Bidirectional Python LanguageModel substrate (PEG grammar +
  significant-whitespace-IS-block-structure C5-fidelity) → bundled
  T-4. Rides ratified D1 Outcome<T> (msg_8b477982) not-yet-landed.
  STOP-TRIGGER: stubbing emit_python : Node -> Outcome<…> is
  forbidden.
- Pipeline emit/ingest ops → compiler/05_emit.dag (T-10) +
  compiler/02_parse.dag (T-7) under D1.
- Async/await + coroutines → extdeps/coordination.dag (T-4.8) IN-B
  effect-typed Bind.
- Exception flow (raise / try / except / finally) → D1 Outcome<T>
  structural Branch + Bind.
- Per-bytecode cost instance-values → T-12 lens/cost.dag.

CONSUMES line: revised from scaffold's anticipatory `std/node.dag,
std/algebra.dag (same as rust.dag)` to `nothing` — the file imports
nothing (unlike rust.dag #3174 which imports Symbol for its lifetime
axis Python lacks, this file is closed-enum + Conj-record only).
Inline-doc cites scaffold-Consumes systemic reconciliation pending
operator ratification (T-4 mgr synthesis msg_1fddb75c). Same
surface+trigger discipline as ptx.dag #3170 and rust.dag #3174.

PER-CARRIER Spec URLs: every classifier carries `// Spec: <stable
upstream URL>` to docs.python.org/3/reference/ + relevant PEPs
(3141 / 285 / 3100) per operator standing requirement (doc-anchor
convention from manager directive).

PRACTICE-4 LEDGER: every closed Disj carries the full 5-pattern
ledger (Fact-placement / Variant-is-data / Algebraic-form /
Dimensional / Parameterized-family-Practice-7) per
modeling-discipline.md §4 gate (b).

Verified: v2-compiler compile --source-root src/v4 --target dag →
0 diagnostics (63 modules, 1 emitted).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* WIP: T-4.14 ptx

* T-4 python: float spec fidelity — "machine-level double precision" not IEEE-754 binary64 (review #3180)

briansrls BLOCKING review on PR #3180 at line 457: RealLevel pinned
Python `float` to IEEE-754 binary64, but the Python Reference §3.2
the-standard-type-hierarchy specifies "machine-level double precision"
with explicit implementation caveats ("You are at the mercy of the
underlying machine architecture (and C or Java implementation) for
the accepted range and handling of overflow"). The IEEE-754 binary64
claim is the CPython REALIZATION, not the spec — modeling it as fixed
format over-promises spec fidelity (INVARIANTS P1 modeling-
faithfulness violated: substrate partition must ground in the spec's
own partition, not a more specific guarantee CPython happens to
provide).

Three locations updated:

1. STRUCTURAL FINDING / Python-specific-particulars block (header):
   "`float` is always IEEE-754 binary64" → "`float` is 'machine-level
   double precision' with IMPLEMENTATION CAVEATS the spec explicitly
   names ... the spec does NOT mandate IEEE-754 binary64, only the
   canonical CPython realization does; modeling `float` as a fixed
   IEEE-754 width would over-promise spec fidelity". `complex` text
   similarly amended to inherit the same caveat.

2. PythonNumericTower / RealLevel variant doc:
   "`float` (IEEE-754 binary64; ...)" → "`float` ('machine-level
   double precision' per Reference §3.2 — implementation-defined per
   the spec's caveat; CPython realizes this as IEEE-754 binary64 but
   the spec does NOT mandate that fixed width)".

3. PythonNumericTower / ComplexLevel variant doc:
   "`complex` (IEEE-754 binary64 pair; ...)" → "`complex` (a pair of
   `float` per Reference §3.2 — inheriting the same machine-level
   double precision + implementation caveat; CPython realizes it as
   a pair of IEEE-754 binary64 but the spec does NOT mandate that
   fixed format)".

The algebra grounding (RealLevel / ComplexLevel → ApproximateField)
remains correct — `ApproximateField` per algebra.dag is the
rounding-aware weakening of Field, which is the right grounding
regardless of whether the underlying float is IEEE-754 binary64
specifically or "machine-level double precision" more generally.

Re-verified: v2-compiler compile --source-root src/v4 --target dag →
0 diagnostics (63 modules, 1 emitted).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* T-4 python: PythonCost spec-fidelity — operation_cost not bytecode_cost (review #3180)

briansrls BLOCKING review on PR #3180 at line 907: `bytecode_cost`
made CPython bytecode the cost authority for a Python LANGUAGE
REFERENCE model, but Python's own `dis` module docs explicitly
disclaim bytecode as CPython implementation detail: "CPython bytecode
... is an implementation detail of the CPython interpreter. No
guarantees are made that bytecode will not be added, removed, or
changed between versions of Python." Other Python implementations
(PyPy / Jython / GraalPython / MicroPython) have entirely different
VMs. Tying the cost-realization carrier to CPython bytecode violated
the L-2 fidelity-to-the-LANGUAGE-REFERENCE pin this file declares
(INVARIANTS P1 modeling-faithfulness + P2 layer-fidelity).

Fix: rename `bytecode_cost` → `operation_cost` (cost of a spec-defined
operation per Python Reference §6 expressions / §8 statements), with
explicit doc framing that CPython bytecode is implementation detail
the cost-authority deliberately ignores.

Changes:
- Owned-ELSEWHERE doc block ("Python per-bytecode cost INSTANCE-
  VALUES"): rewritten as "Python per-spec-operation cost INSTANCE-
  VALUES" with explicit citation of Reference §6/§8 partition + the
  named CPython-vs-Reference-VM distinction (PyPy / Jython /
  GraalPython / MicroPython listed as alternative VMs).
- Owns line 115 ("per-bytecode-op"): rewritten "per-spec-operation
  per Reference §6/§8 — NOT per CPython bytecode op, which is
  implementation detail per the `dis` module disclaimer".
- PythonCost.operation_cost doc: extensive rewrite citing the `dis`
  docs disclaimer verbatim, naming the alternative-VM portability
  issue, declaring spec §6/§8 as the operation-set authority, and
  noting the rust/PTX instruction_cost analogy is the spec-level
  per-instruction concept, not the bytecode-op concept.
- PythonCost type declaration: `bytecode_cost: Int` →
  `operation_cost: Int`.
- 🟡 scaffold bridge note + dissolution-trigger note + SEAM note:
  updated to use `operation_cost` consistently.
- Concrete cost-row examples updated: was `BINARY_OP` (a CPython
  opcode reference), now "integer-binary-add per Reference §6.6
  arithmetic-conversions" (a spec operation reference).

Remaining `bytecode` mentions are all INTENTIONAL — citing CPython
bytecode as the implementation-detail surface the model deliberately
does NOT track, with the `dis` docs disclaimer quoted as evidence
for the fidelity discipline.

Re-verified: v2-compiler compile --source-root src/v4 --target dag →
0 diagnostics (63 modules, 1 emitted).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* T-4 python: resolve PythonScalarKind/PythonScalar naming drift (review #3180)

codex/codex-default REQUEST_CHANGES on PR #3180 at line 86 / 726
(observation #2): the doc described a top-level carrier
`PythonScalarKind` in the Owns block + section header, but the
actual declaration is `type PythonScalar`. INVARIANTS P1 modeling-
faithfulness / "documentation describes live state" violated;
unclear which name is canonical for downstream workers.

Resolution: align doc to code (drop phantom `PythonScalarKind` doc
references; PythonScalar is the canonical single carrier). The
single-carrier collapse is INTENTIONAL — explained explicitly in the
PythonScalar modeling note as a Python-vs-rust structural difference:

  rust.dag #3174 declares TWO scalar carriers (RustScalarKind flat
  6-way meta-enum + RustScalar Disj-with-payloads typed-value form)
  because the typed-value form needs WIDTH payloads the meta-
  classifier doesn't.

  Python has NO orthogonal width axis (per header Python-particulars
  (a) — int arbitrary-precision, float machine-level double
  precision, no per-kind width discriminator). So the meta-
  classifier and the typed-value form COLLAPSE INTO ONE Disj:
  PythonScalar's variants (Numeric / String / Singleton) ARE the
  3-category meta-tags AND the typed-value variants in one. No
  separate `PythonScalarKind` exists because no orthogonal axis to
  factor across exists.

Changes:
- Owns block line 86-89: dropped phantom `PythonScalarKind` row;
  expanded PythonScalar row to explicitly note it serves both the
  3-category kind-classifier role AND the typed-value role in one
  carrier, with a pointer to the modeling-note for the
  Python-vs-rust rationale.
- Line 360: "see ... PythonScalarKind below" → "see PythonScalar
  below" (the actual referenced carrier).
- Section header line 750: "PythonScalarKind — the closed Python
  top-level primitive-scalar category partition" → "PythonScalar
  — the closed Python top-level primitive-scalar typed-value Disj"
  + new "SINGLE-CARRIER CONSOLIDATION" subsection explaining the
  Python-vs-rust difference and naming the codex finding as the
  correction driver.

Remaining `PythonScalarKind` mentions in the file are INTENTIONAL —
inside the explanatory note describing why no separate
PythonScalarKind type exists, citing the codex finding.

Re-verified: v2-compiler compile --source-root src/v4 --target dag →
0 diagnostics (63 modules, 1 emitted).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* T-4 python: Python match falls-through, NOT exhaustive (review #3180)

briansrls BLOCKING review on PR #3180 at line 339: the MATCH-↦-Branch
mapping prose claimed "match requires exhaustive patterns; the
LanguageModel grammar layer declares pattern-exhaustiveness as part
of the match-statement production" — but per Python Reference §8.6:

  "If no case matches the subject, the entire match statement falls
   through (none of the suites are executed)."

This is the deliberate Python-vs-rust spec difference: rust's match
IS exhaustiveness-required (with `_` wildcard required if no other
arm covers); Python's match is NOT. The prior text imported rust's
spec into Python's model — INVARIANTS P1 modeling-faithfulness /
L-2 extdeps fidelity violated.

Rewritten mapping prose:
- Python `match` is Branch over the value's coordinates WITH an
  implicit fall-through tail (the "no case matched" path is a no-op
  per §8.6).
- A2 totality is a CONSUMER property the LanguageModel grammar may
  opt into (via a match-exhaustiveness lens read or a `case _:`
  wildcard production) — but the spec itself does NOT mandate it.
- A Python `match` without a wildcard is well-formed by the spec
  even if no case fires.

The Branch behavior mapping still holds; what changed is the
totality framing — Python's match doesn't structurally guarantee
totality the way rust's does. The fall-through is a STRUCTURAL
SPEC FACT the model now preserves.

Inline correction note added citing the operator BLOCKING that drove
the fix (same disclosure shape as the earlier float-IEEE-754 and
bytecode_cost corrections).

Re-verified: v2-compiler compile --source-root src/v4 --target dag →
0 diagnostics (63 modules, 1 emitted).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* T-4 python: str/bytes/bytearray are SEQUENCES not scalars per Reference 3.14 (review #3180)

codex/codex-default BLOCKING REQUEST_CHANGES on PR #3180 at line 80
/ line 770: PythonScalar declared `str` / `bytes` / `bytearray` as
part of the scalar sum via the `String { kind: PythonStringKind }`
variant, but Python Reference 3.14 partitions them as SEQUENCES:
- §3.2.5.1 Immutable sequences: `str`, `bytes`, `tuple`
- §3.2.5.2 Mutable sequences: `bytearray`, `list`

The Reference structurally separates §3.2.4 numeric types and
§3.2.1-3 singletons (THE SCALAR PRIMITIVES) from §3.2.5 sequences
(CONTAINERS). The prior model collapsed that boundary, giving
downstream consumers the wrong built-in type shape (INVARIANTS P1
modeling-faithfulness / L-2 extdeps fidelity violated against the
pinned 3.14 spec).

REMOVED:
- `type PythonStringKind = Str | Bytes | Bytearray` declaration
  (replaced with an inline removal-note citing the BLOCKING and
  pointing to the future PythonSequence carrier)
- `String { kind: PythonStringKind }` variant of PythonScalar

REFACTORED:
- `type PythonScalar` from 3-variant to 2-variant:
    Numeric { tower: PythonNumericTower } | Singleton { kind:
    PythonSingletonKind }
  Per Reference 3.14 §3.2.4 (numerics) + §3.2.1-3 (singletons) —
  the actual scalar partition.
- PythonScalar's modeling-note rewritten:
  - Subtitle: "two categories" (was "three")
  - Added SEQUENCES-ARE-NOT-SCALARS subsection citing §3.2.5.1 /
    §3.2.5.2 explicitly + naming the operator BLOCKING that drove
    the correction
  - Hierarchical-partition argument updated for 2-category (was
    3-category)
  - Practice-4 ledger updated: variant-is-data names the 2-variant
    Disj; algebraic-form drops the FreeMonoid<UnicodeScalarValue>
    String reference; parameterized-family drops PythonStringKind
    from the heterogeneity argument; terminal note updated.

HEADER UPDATES:
- Anchor block carrier list: dropped PythonStringKind (no longer
  declared)
- Python-particulars (d): rewritten — was "MUTABILITY DEGENERATE
  AT SCALAR LAYER" claiming bytearray is mutable among scalars; now
  "SCALARS ARE NUMERIC + SINGLETON ONLY (no sequences)" with §3.2.5
  citation. Mutability admits no scalar-layer axis under the
  corrected partition (no scalar is mutable; bytearray is a
  sequence, scope-negative).
- Owns block: dropped PythonStringKind row; PythonScalar row
  updated to 2-variant + named the sequence-correction with
  explicit pointer to SCOPE NEGATIVE.
- REFERENCES mapping (binding-vs-object mutability discussion):
  rewrote to point to §3.2.5 sequence/container layer rather than
  the dropped PythonStringKind.
- SCOPE NEGATIVE: substantially expanded the Container-types entry
  into a unified sequence/set/mapping scope-negative naming
  Reference §3.2.5.1 / §3.2.5.2 / §3.2.5 / §3.2.6 / §3.2.7
  explicitly. Added the rust-vs-python spec-partition difference
  note (rust groups `str` with primitives §3.5; Python puts `str`
  in §3.2.5.1 sequences).

The Branch behavior mapping for match (refactored in 4ebb7c0 per
the prior briansrls BLOCKING) is unchanged; the fall-through
framing was correct and survives this refactor.

The future PythonSequence / PythonContainer carrier is named in the
SCOPE NEGATIVE block as the dissolution ratchet — sequences /
sets / mappings model there, not in PythonScalar.

Re-verified: v2-compiler compile --source-root src/v4 --target dag →
0 diagnostics (63 modules, 1 emitted).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* T-4 python: cross-PR alignment with rust slice #3174 — 4 shape items (review #3180)

Operator-relayed cross-PR alignment review from loyal-koi-702 (rust
slice author), 2026-05-16: rust.dag #3174 has 4 shape items added
late that python should mirror for IR↔language pipeline uniformity.
Not blocking on its own, but worth landing before merge so
"fix the shape once, fan out" actually produces uniform shape.
Mirroring the rust.dag pattern mechanically, adapted for Python's
2-category (Numeric + Singleton) scalar partition.

Imports: `import v4.std.logic { Bool }` — Bool now consumed as the
IRCarrier type-parameter for `IrToPython<Bool>` and as the return
type of the Layer-2 assertion fn. Consumes header block updated to
reflect this (was "nothing"); cites the cross-PR alignment review +
the std/logic.dag merge (PR #3163, 2026-05-16) as the enabler.

ITEM 1 — Per-primitive named registry (7 inhabitants):

  // Numerics
  data python_bool:            PythonScalar = Numeric { tower: BoolLevel }
  data python_int:             PythonScalar = Numeric { tower: IntegralLevel }
  data python_float:           PythonScalar = Numeric { tower: RealLevel }
  data python_complex:         PythonScalar = Numeric { tower: ComplexLevel }

  // Singletons
  data python_none:            PythonScalar = Singleton { kind: NoneT }
  data python_not_implemented: PythonScalar = Singleton { kind: NotImplementedT }
  data python_ellipsis:        PythonScalar = Singleton { kind: EllipsisT }

These are CARRIER-VALUE instance-values (typed values of the closed
PythonScalar Disj) — analogous to rust.dag's 18 `data rust_X:
RustScalar = ...` rows. NOT D2 algebra-inhabitance (no
`Algebra<Carrier>` pattern), so the manager's D2 STOP-trigger does
not fire. Section header doc explicitly distinguishes these from
algebra-inhabitance and names the manager-deferred D2 case.

ITEM 2 — `IrToPython<IRCarrier>` generic carrier:

  type IrToPython<IRCarrier> {
    python_repr: PythonScalar
  }

Mirrors rust.dag's `IrToRust<IRCarrier>` (lines 1448-1450 of PR
#3174 HEAD). The U1 "coercion = emission" projection made concrete
per language; type-parameterized so emit dispatches by type-
identity match on IRCarrier, not by name (K-1). Extensive doc
mirroring rust.dag's: worked example walking Bool → python_bool
through emit (T-10) and ingest (C5/T-7) showing the bidirectional
type-level-keyed correspondence.

ITEM 3 — First concrete IR ↔ Python row:

  data bool_to_python_bool: IrToPython<Bool> = IrToPython {
    python_repr: python_bool
  }

The first IR↔Python correspondence row, mirroring `bool_to_rust_
bool`. Bool (std/logic.dag) → python_bool (Numeric { tower:
BoolLevel }) — 1:1 at the scalar layer per PEP 285 (Python `bool`
is a strict int-subtype; the BoolLevel of the numeric tower is
exactly `bool`). Spec URLs: Wikipedia Boolean algebra (IR side) +
docs.python.org/3.14/library/functions.html#bool (Python side) +
PEP 285 (bool-as-int-subtype rationale).

ITEM 4 — Layer-2 structural-assertion fn:

  fn assert_bool_to_python_bool_consistency() -> Bool {
    match bool_to_python_bool.python_repr {
      Numeric { tower: BoolLevel }     => true
      Numeric { tower: IntegralLevel } => false
      Numeric { tower: RealLevel }     => false
      Numeric { tower: ComplexLevel }  => false
      Singleton { kind: _ }            => false
    }
  }

Exhaustive match on `bool_to_python_bool.python_repr` asserting it
must be `Numeric { tower: BoolLevel }`. Layer-2 in the 3-layer
testing pattern (Layer-1 = 0-diag structural typing live now;
Layer-2 = this fn, authorable now; Layer-3 = TestClaim data gated
on PR #3183 std/verification.dag). The full 3-layer doc-block
preceding the fn mirrors rust.dag's pattern, adapted for Python's
match-variant naming.

The 3-layer doc-block is also a FORWARD-ANCHOR: when PR #3183
(std/verification.dag) merges, the fn body becomes the `expected`
side of an `Equals` TestClaim. Sketch comment in the fn doc shows
the post-#3183 form.

Re-verified: v2-compiler compile --source-root src/v4 --target dag →
0 diagnostics (63 modules, 1 emitted).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* WIP: v4 T-4 python.dag D2-resolver reshape (continue PR #3180; mirror verifie

* WIP: v4 T-4 python.dag D2-resolver reshape (continue PR #3180; mirror verifie

* WIP: v4 T-4 python.dag D2-resolver reshape (continue PR #3180; mirror verifie

* WIP: v4 T-4 python.dag D2-resolver reshape (continue PR #3180; mirror verifie

* fix(v4): repair python.dag D2 int comment + pin all reference URLs to 3.14

Restores mangled D2a(3) prose (unbounded int / std Int alias). Replaces
remaining floating docs.python.org/3/reference links with the file’s
L-2 anchor (/3.14/) so spec authority stays consistent with PR #3180
BLOCKING review closure.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
briansrls added a commit that referenced this pull request May 16, 2026
…vocabulary slice (fan-out from rust #3174) (#3182)

* WIP: T-4.9 verilog

* WIP: T-4.9 verilog

* v4 T-4 go: pin Go spec to go1.26 — extdeps.md rule #3 fix (cursor BLOCKING on PR #3182)

cursor/composer-2 BLOCKING inline review on go.dag:5: the Anchor URL
https://go.dev/ref/spec is mutable (always redirects to current spec),
and dsl/extdeps/extdeps.md rule #3 requires every versioned external
authority to STATE the concrete version target. The slice previously
named the file as "the versioned upstream specification" without pinning
the version — failing the extdeps fidelity rule.

Fix: pin to "Go language version go1.26" explicitly in the Anchor line
with the L-2 discipline framing — when the Specification changes between
releases, the version pin AND the relevant declaration below are BOTH
visible C1 edits (consistent with ptx.dag's "PTX ISA 8.5", spice.dag's
"SPICE3 3f5", llvm_ir.dag's "LLVM 18 LangRef" precedent).

Verification: v2-compiler compile --source-root src/v4 --target dag = 63
modules / 0 diagnostics.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* WIP: T-4.9 verilog

* v4 T-4 go: correct type-switch dispatch note — match explicit case list, not closed implementing-type set (codex non-blocking on PR #3182)

codex non-blocking improvement on PR #3182 (top-level summary): the
type-switch note framed dispatch as "Branch over the closed set of
concrete types implementing the interface". Per Go spec §Switch_statements
that's wrong — Go type-switches match the dynamic type of `x` against
the EXPLICIT case-type list authored at the switch site, with `default`
covering the residual. Closed-implementing-type exhaustiveness is a
separate optional analysis, not how the type-switch itself dispatches.

Reworded the bullet to match the spec; note that the closed-set
exhaustiveness framing is preserved as an OPTIONAL LanguageModel
grammar-lane analysis on closed interfaces (kept honest, not deleted).

Verification: v2-compiler compile --source-root src/v4 --target dag =
63 modules / 0 diagnostics.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* v4 T-4 go: correct interface-method-dispatch note — virtual-dispatch Transform, not closed-Branch (cursor BLOCKING on PR #3182)

cursor BLOCKING inline review on PR #3182 go.dag:400: the METHOD bullet
framed interface method dispatch as "a Branch over the interface's
implementing type set". Per Go spec §Method_sets + §Interface_types,
interfaces are duck-typed (structurally implemented) — the implementing-
type set is OPEN, ranging over all declarable non-interface types whose
method-set is a superset of the interface's method-set. A closed-Branch
model violates INVARIANTS P1 (the spec partition is open, not closed)
and P4 (the implementing-type set is not decidable at compile time
without whole-program analysis).

Same shape as the type-switch correction I landed in 660b05c — I
fixed type-switch dispatch but left a parallel bug in the METHOD
bullet. Now reframed: interface method dispatch is a Transform whose
CALLEE is dynamically selected by the receiver's dynamic-type method-
set lookup (virtual-dispatch / function-pointer-call shape); the
dynamic method-set lookup machinery is owned by the bundled T-4
LanguageModel grammar + runtime productions.

Documentation/modeling-notes fix; no type declarations changed.

Verification: v2-compiler compile --source-root src/v4 --target dag =
63 modules / 0 diagnostics.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* v4 T-4 go: broaden GoExportLocus.InterfaceMethod → MethodName to cover concrete methods (cursor BLOCKING on PR #3182)

cursor BLOCKING inline review on PR #3182 go.dag:1108: GoExportLocus
only modeled interface-method-decl names; concrete method declarations
(`func (T) Lock()` per Go spec §Method_declarations) had no
representable locus, so an exported concrete method like `Lock()`
couldn't carry a GoExportStatus.locus payload. INVARIANTS P1
(modeling-faithfulness — spec's "method name" locus class is broader
than just interface methods) + P2 (single-authority — concrete method
names ARE method names per spec, should unify into the same locus
class).

Per Go spec §Exported_identifiers: "the identifier is declared in the
package block or it is a field name or method name." The spec's
"method name" partition unifies BOTH (a) method names in interface
type declarations AND (b) method declarations on concrete types via
receiver — both flavors carry the case-derived export-status that
governs cross-package access.

Fix: renamed InterfaceMethod → MethodName and broadened the doc to
cover both flavors. Variant count stays 3 (spec partition is
package-block / field-name / method-name); same 5-pattern Practice-4
ledger, refined to note the spec's uniform method-name class.

Verification: v2-compiler compile --source-root src/v4 --target dag =
63 modules / 0 diagnostics.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* WIP: v4 T-4 go.dag D2-resolver reshape (continue PR #3182; mirror verified ca

* WIP: v4 T-4 go.dag D2-resolver reshape (continue PR #3182; mirror verified ca

* WIP: v4 T-4 go.dag D2-resolver reshape (continue PR #3182; mirror verified ca

* fix(v4): go.dag — Practice-4 notes vs §Integer_overflow + D2a(3)

Resolves codex review thread #3252128030: SignedIntWidth / GoScalarKind /
GoScalar ledgers no longer read as “Go signed ints = OrderedRing alone”;
they now pair std/ bounded-integer carriers with D2a(3) silent modular
truncation per https://go.dev/ref/spec#Integer_overflow (distinct from
abstract ordered arithmetic).

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
briansrls added a commit that referenced this pull request May 16, 2026
…ed canonical rust #31740328bee + encoded DECISIONS.md D2 row) (#3198)

* WIP: v4 T-4 typescript.dag D2-resolver model (from scaffold; mirror verified

* WIP: v4 T-4 typescript.dag D2-resolver model (from scaffold; mirror verified

* WIP: v4 T-4 typescript.dag D2-resolver model (from scaffold; mirror verified

* WIP: v4 T-4 typescript.dag D2-resolver model (from scaffold; mirror verified

* WIP: v4 T-4 typescript.dag D2-resolver model (from scaffold; mirror verified

* docs(v4): tie typescript D2a(3) data deferral to Class-5-Gap-3 owner

Co-authored-by: Cursor <cursoragent@cursor.com>

* WIP: v4 T-4 typescript.dag D2-resolver model (from scaffold; mirror verified

* WIP: v4 T-4 typescript.dag D2-resolver model (from scaffold; mirror verified

* ci: add SG-0 PR-body append for #3198 census +1

CI prepends this so check-pr-sg0-net-shrink-discipline passes when
EXPECTED_HAND_AUTHORED_TEST gains the typescript extdeps smoke path.

Co-authored-by: Cursor <cursoragent@cursor.com>

* WIP: v4 T-4 typescript.dag D2-resolver model (from scaffold; mirror verified

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
briansrls and others added 3 commits May 16, 2026 16:59
Per BLOCKING reviewer 2026-05-16T20:33:06Z @ rust.dag:1799:

  "OverflowDisposition makes Rust's required debug-assertion overflow
   action a variable OverflowAction, so TwoComplementWrap remains
   constructible for a fact the Rust Reference fixes to panic,
   violating INVARIANTS P2/extdeps fidelity."

Verified: the prior shape OverflowDisposition<IRCarrier> {
debug_assert_required_action: OverflowAction } let any OverflowAction
value sit in that field, including TwoComplementWrap — but the
Rust Reference (behavior-not-considered-unsafe.html#integer-overflow)
fixes that fact: "implementations MUST insert dynamic checks that
panic on overflow." Variable field type = illegal-state-constructible
= INVARIANTS P2 illegal-states-unrepresentable violation.

Fix: reshape OverflowDisposition to a closed two-variant Disj with
nullary variants, structurally pinning both Reference facts:

  type OverflowDisposition<IRCarrier>
    = MustPanicOnOverflow
    | MayPanicOrTwoComplementWrap

  - MustPanicOnOverflow: the deterministic Reference fact for debug_assert
    builds. Nullary variant — no payload can carry an alternative action.
  - MayPanicOrTwoComplementWrap: the Reference fact for other builds
    (impl-defined choice between the permitted actions, commonly driven
    by -C overflow-checks). Wrap convention (two's-complement per
    Reference) structurally encoded in variant name; no ArbitraryWrap
    sibling exists.

This matches openai-pro's earlier REQUEST_CHANGES suggested faithful
shape ("a disposition such as MustPanic | MayPanicOrWrap { wrap_convention:
TwoComplement }") with the wrap-convention encoded in variant naming
rather than as a payload.

Practice-4 ledger updated: 5 patterns FAIL (closed two-element Reference-
defined per-build-mode classification; nullary variants are the faithful
form per pattern-2; the action-as-payload form is exactly what the
BLOCKING rejected). Terminal 🟢 GREEN under #3200 (Bool-shaped on the
debug_assert-enabled axis; no namable richer std/ source).

Deferred-instructions block for per-integer rust_<x>_overflow rows
updated: two D2a(3) data rows per integer type capturing the per-build-
mode dispositions; both are TOP-LEVEL SUM-VARIANT bodies (= MustPanicOnOverflow
etc.) → DOUBLE-deferred under (a) std/integer.dag ladder + (b)
Class-5-Gap-3 (top-level ValueBody::Unparsed) per ROADMAP.md:418.
Type shape canonical regardless of instance-row landing.

Owns: D2-resolver-shape bullet updated.

v2-compiler: 0 diagnostics (full lower-and-emit, 68 files).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@briansrls

Copy link
Copy Markdown
Contributor Author

Mapping reply — codex BLOCKING sha:dfb9464e (schedule cycle, 278s wall)

Codex's finding on dfb9464 says:

OverflowAction is serving both the non-debug permitted action set and the required debug semantics → split the required debug fact into a constant/marker carrier or otherwise make TwoComplementWrap unrepresentable there.

This is the same shape concern as the operator's BLOCKING at rust.dag:1799 (comment 3253422504, 2026-05-16T20:33:06Z) — both flag that the prior OverflowDisposition { debug_assert_required_action: OverflowAction } shape let TwoComplementWrap sit in the debug-required slot, when the Reference fixes that fact to panic. Already addressed at HEAD c9ba92d.

Sha-alignment + per-finding mapping:

The reshape at c9ba92d takes exactly codex's "constant/marker carrier" disposition. New shape:

type OverflowDisposition<IRCarrier>
  = MustPanicOnOverflow                  // constant/marker variant
  | MayPanicOrTwoComplementWrap          // impl-defined-choice variant
  • MustPanicOnOverflow IS the constant/marker carrier for the debug-required Reference fact. It is a NULLARY variant — there is no payload to take an OverflowAction value. OverflowDisposition { ... debug-required = TwoComplementWrap } is no longer a representable construction; the type-level partition pins the fact by variant identity.
  • MayPanicOrTwoComplementWrap is the marker for the impl-defined-choice case (non-debug-assert builds), with the wrap convention (two's-complement per Reference: "implementations must provide well-defined results by using two's complement overflow conventions") structurally encoded in the variant name. No ArbitraryWrap sibling exists.
  • OverflowAction ({PanicOnOverflow, TwoComplementWrap}) remains as the closed permitted-action SET classifier; it no longer plays a role in OverflowDisposition's structure. The role-conflation codex flagged (OverflowAction serving both the permitted-set and the required-fact) is dissolved — OverflowAction now serves ONLY the permitted-set role.

Practice-4 ledger position 2 explicit on this: "carrying an OverflowAction payload on the MustPanic variant reopens exactly the illegal-state this BLOCKING rejected; two nullary structural alternatives IS the faithful form."

Per-integer instance rows are DOUBLE-deferred (top-level sum-variant bodies fall into Class-5-Gap-3 per ROADMAP.md:418; the type shape is canonical regardless of instance landing).

v2-compiler: 0 diagnostics through full lower-and-emit pipeline at c9ba92d.

— sent from loyal-koi-702

Per openai-pro REQUEST_CHANGES sha:dfb9464e (2026-05-16T20:45:01Z):

> "The stale D2 seam at src/v4/extdeps/languages/rust.dag:733-738
>  reintroduces a second textual authority for where inhabitance
>  should attach... A future worker faithfully following that later
>  seam could implement the wrong primitive-grounding path even
>  though the surrounding file says the opposite."

Verified: the RustScalar block had a "SEAM (where D2 inhabitance
plugs in)" section that still framed D2 as operator-pending
(msg_640d429c) AND said "the per-variant inhabitance instance-values
land in this file with these typed variants as their carriers —
IntScalar { kind: Signed, width: Bits32 } is the carrier for Rust's
i32 inhabitance into OrderedRing" — which is the superseded
parallel-substrate per-language `data rust_<x>: OrderedRing<Rust<X>>`
shape the ratified D2 row (DECISIONS.md, commit 44a37ad) explicitly
forbids per INVARIANTS P1:42 `numeric_aliases_align_to_refinements`.

Fixes (comment-only, no structural change):
1. RustScalar seam reframed: section now titled "ROLE under the
   RATIFIED D2 resolver" — clarifies RustScalar is the parse-stage
   source-syntax classifier, NOT the inhabitance carrier; primitive
   grounding+inhabitance lands via D2a three-thin-facts
   (alias-identity to std/ carrier + GroundingMap + per-language
   operation-semantics). The earlier framing is called out as
   SUPERSEDED with reference to the D2 row's D2.2 anti-pattern.
2. Header STRUCTURAL FINDING block: D1 status updated from
   "RATIFIED ... NOT YET LANDED" to "LANDED via #3181 commit
   54d12e6" (Outcome<T> = Produced | Rejected); D2 status updated
   from "operator-pending SEMANTIC decision, msg_640d429c" to
   "RATIFIED via #3195 commit 44a37ad, encoded as DECISIONS.md
   D2 row's THREE-THIN-FACTS resolver shape".
3. Owned ELSEWHERE LanguageModel + Pipeline emission/ingest
   bullets: D1 NOT-YET-LANDED references updated to "LANDED via
   #3181"; STOP-TRIGGERs preserved (the carrier landing doesn't
   make this slice the right home for emission/parse ops — they
   belong in compiler/05_emit.dag / compiler/02_parse.dag per
   the ptx #3170 precedent).
4. Consumes block: "std/algebra.dag returns when D2 ratifies"
   prose reconciled — algebra inhabitance for Rust primitives now
   flows transitively through the D2a(1) alias-identity targets
   (e.g. `type RustI32 = Int32`), never re-declared in this file
   per the machine-readable-inhabitance form (`List<T> =
   FreeMonoid<T>` precedent).
5. Substrate-fit modeling note (LITERAL / VALUE bullet): "RIDES
   D2 — pre-D2 the Value's TYPED interpretation is unspecified"
   prose updated to reflect D2-ratified state — the literal's
   typed interpretation rides D2a(1) alias-identity to the std/
   carrier where the algebra inhabitance lives.
6. Owns RustCost bullet: "no instance-values pre-T-3 / pre-D2"
   prose updated — pre-D2 is no longer accurate; the deferral
   is on T-12 lens/cost.dag for concrete cost rows.

Two remaining "operator-pending" references in the file are
PLACEMENT-related (GroundingMap-home pending operator decision per
T-4 mgr msg_148854d5) — correct, not stale.

v2-compiler: 0 diagnostics through full lower-and-emit (68 files).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@briansrls

Copy link
Copy Markdown
Contributor Author

Mapping reply — openai-pro REQUEST_CHANGES sha:dfb9464e (issue-comment 4467921022... actually the manual review at 2026-05-16T20:45:01Z conversation 6a08d4ec)

Verified the finding. The stale D2 seam at the prior rust.dag:733-738 did contradict the ratified D2 alias-identity shape — even though the header already said D2 was ratified, the seam prose still framed it as "operator-pending msg_640d429c" with "the per-variant inhabitance instance-values land in this file with these typed variants as their carriers — IntScalar is the carrier for Rust's i32 inhabitance into OrderedRing." That's the superseded parallel-substrate per-language data rust_<x>: OrderedRing<Rust<X>> shape the D2 row (D2.2 + INVARIANTS P1:42 numeric_aliases_align_to_refinements) explicitly forbids. Reviewer's call that a faithful downstream worker would have implemented the wrong path was correct.

Fixed in 6df8662 (comment-only reconciliation, no structural carrier changes). Six prose-drift fixes:

  1. RustScalar seam reframed: the section now titled "ROLE under the RATIFIED D2 resolver" — clarifies RustScalar is the parse-stage source-syntax classifier (NOT the inhabitance carrier); primitive grounding+inhabitance lands via D2a three-thin-facts (alias-identity to std/ + GroundingMap + per-language operation-semantics). The earlier framing is called out as SUPERSEDED with reference to D2.2's anti-pattern.

  2. Header STRUCTURAL FINDING block: D1 status updated from "RATIFIED ... NOT YET LANDED" to "LANDED via v4 T-3: land operator-ratified Outcome<T> carrier in std/diagnostic.dag #3181 commit 54d12e6" (Outcome<T> = Produced | Rejected); D2 status from "operator-pending SEMANTIC decision, msg_640d429c" to "RATIFIED via v4 D2 — primitive-inhabitance FORM: the extdeps resolver shape #3195 commit 44a37ad, encoded as DECISIONS.md D2 row's THREE-THIN-FACTS resolver shape."

  3. Owned ELSEWHERE LanguageModel + Pipeline emission/ingest bullets: D1 NOT-YET-LANDED references updated to "LANDED via v4 T-3: land operator-ratified Outcome<T> carrier in std/diagnostic.dag #3181"; STOP-TRIGGERs preserved (the carrier landing does NOT make this slice the right home for emission/parse ops — they belong in compiler/05_emit.dag / compiler/02_parse.dag per the ptx v4 T-4.14: model extdeps/languages/ptx.dag — SIMT-as-5-behaviors (B2-OMNI + IN-B probe, no STOP) #3170 precedent).

  4. Consumes block: the "std/algebra.dag returns when D2 ratifies" framing reconciled — algebra inhabitance for Rust primitives now flows TRANSITIVELY through the D2a(1) alias-identity targets (type RustI32 = Int32 → Int32's std/algebra inhabitance), never re-declared in this file per the List<T> = FreeMonoid<T> machine-readable-inhabitance precedent.

  5. Substrate-fit LITERAL/VALUE modeling note: "RIDES D2 — pre-D2 the Value's TYPED interpretation is unspecified" updated to reflect D2-ratified state.

  6. Owns RustCost bullet: "no instance-values pre-T-3 / pre-D2" → "no concrete cost instance-values in this slice — those ride T-12 lens/cost.dag" (pre-D2 no longer accurate).

Two remaining "operator-pending" references in the file are PLACEMENT-related (GroundingMap-home pending operator decision per T-4 mgr msg_148854d5) — those are correct, not stale.

This addresses openai-pro's specific finding (stale D2 seam) AND the broader concern about comment drift in a substrate-authority file. Two earlier in-flight BLOCKINGs (operator inline at rust.dag:1799 about variable-OverflowAction → fixed in c9ba92d reshape to nullary Disj; codex BLOCKING on dfb9464 about the same OverflowAction role-conflation → mapping-reply 4468152905) are already addressed at HEAD 6df8662.

v2-compiler: 0 diagnostics through full lower-and-emit (68 files).

— sent from loyal-koi-702

@briansrls

Copy link
Copy Markdown
Contributor Author

Thanks for the careful approval review. Per-finding response:

1. Comment-to-code ratio (non-blocking, style). Acknowledged. The high prose density reflects that rust.dag is operator-flagged as a load-bearing substrate-authority file in the lane (the canonical exemplar that 4 sibling fan-out files mirror), so per the project spirit ("files named in INVARIANTS.md / SELF_HOSTING.md as load-bearing carry a higher bar"), keeping per-decision provenance has been the discipline — multiple operator/reviewer BLOCKINGs ratified specific shapes through this PR, and the recap exists so a future worker DFS-ing the concept DAG sees WHY the carrier landed in its current form (especially relevant for PubInPath where 5 rounds of operator inline BLOCKINGs successively refined the shape from pub(self) self-prefix handling through to the final absolute-path-from-crate-root form). I take the point that some of it ages out and will defer the trim to a follow-up PR (current trim risk: invalidating the rolling-HEAD review-tail by churning unrelated lines mid-merge-cycle). The trim itself is comment-only / no semantic change; safe to land separately.

2. GroundingMap<IRCarrier> parallel-declaration check (non-blocking). Verified clean. Grepped all sibling extdeps/languages files:

$ grep -n "^type GroundingMap\|^data.*GroundingMap" src/v4/extdeps/languages/*.dag src/v4/extdeps/formats/*.dag
src/v4/extdeps/languages/rust.dag:1718:type GroundingMap<IRCarrier> { …
src/v4/extdeps/languages/rust.dag:1904:data rust_bool_grounding: GroundingMap<RustBool> = …

Only rust.dag declares the type. python.dag (line 1004), go.dag (line 1420), typescript.dag (line 22) all correctly DEFER the entire D2a(2) facet under the operator-pending GroundingMap-home decision and explicitly call out "do NOT declare GroundingMap locally — that is the P2 parallel-declaration violation." cpp.dag and llvm_ir.dag don't currently reference GroundingMap. P2 not tripped; the lane is co-disciplined.

3. RustCost { instruction_cost: Int, allocation_cost: Int } admits negative costs (non-blocking). Verified. This is already tracked as a 🟡 SCAFFOLD at rust.dag:1535-1553 with the three bridge properties (the same diagnostic.dag-precedent shape from 2026-05-15):

  • (a) scaffold doc: "STRUCTURALLY ADMITS illegal states (negative costs; nonsense magnitudes). modeling-discipline.md §2 (illegal-states-unrepresentable) forbids admitting them; no bounded-Cardinality refinement substrate exists yet."
  • (b) producer-side bounds: "a producer MUST construct only non-negative costs; until the substrate enforces it the invariant is producer-side; a RustCost with negative components is a producer bug, not a legal value."
  • (c) dissolution trigger: "when std/cardinality.dag's refinement substrate lands (T-3, P4 decidability), instruction_cost and allocation_cost become refined bounded-non-negative-Int axes, and this scaffold dissolves."

This satisfies the tracked-scaffold bar exactly as you noted for PubInPath and GroundingMap placement — the finding is already on the tracked-debt side of INVARIANTS P5, not crossing into untracked violation.

— sent from loyal-koi-702

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review metadata

  • Provider / model: codex / unknown
  • Commit: c9ba92d7 · Trigger: schedule
  • Thinking: 452s wall

⚠️ No new non-duplicate findings, but prior blocking comment 3252591047 is not resolved by this diff.

@briansrls

Copy link
Copy Markdown
Contributor Author

Mapping reply — codex schedule cycle sha:c9ba92d7 (452s wall, no new findings)

This is the 10th iteration of the same Bool-authority loop (prior 9: issue-comments -4466327457 / -4466330090 / -4466472613 / -4466473857 / -4466595731 / -4466762885 / -4467047032 / -4467321512 / -4467748736). Per the rolling-HEAD discipline + sha-reconcile against the live git HEAD:

Sha-alignment:

  • codex review: sha c9ba92d (2 commits behind)
  • current git HEAD: 9898fe7 (per git rev-parse origin/session/loyal-koi-702)
  • comment 3252591047 referenced: a17fcd2 era (PRE-D2-RESHAPE; the IrToRust row that comment was about was DISSOLVED at 0328bee per the operator-ratified DECISIONS.md D2 row reshape)

Structural reality at HEAD 9898fe7:

  • The IrToRust<Bool> carrier the prior comment flagged NO LONGER EXISTS in this PR.
  • Current shape: type RustBool = Bool (D2a(1) alias-identity, line ~1894 of rust.dag at HEAD).
  • Bool resolves kernel-ambient per STRUCTURE.md:147 (verified verbatim on origin/main); std/logic.dag is its sole modeling authority and type Bool = True | False is landed there via v4 T-3: model std/logic.dag — Bool + BooleanAlgebra inhabitance instance-value #3166 (verified verbatim on origin/main).
  • T-4 mgr verified this exact resolution as the "load-bearing kernel-ambient crux" check at msg_e5c0577d (2026-05-16): "STRUCTURE.md:147 (origin/main) explicitly lists Bool as KERNEL-AMBIENT — usable without an import; your alias-identity is a GENUINE machine-readable Node-identity edge, NOT hollow. machine.dag's import v4.std.logic { Bool } is consistent — it needs Bool's modeled facts; your alias edge needs only the kernel value. Header reasoning (216-235) is STRUCTURE.md-faithful, not improvised."

Disposition per feedback_stale_sha_review_mapping_reply_not_refix.md: "rolling-HEAD discipline; verify-first against current HEAD, then post sha-alignment + commit-ref + per-finding mapping; dashboard re-relays of already-replied inline threads = informational queue-state, no new PR action." The codex pipeline reviewing a stale sha doesn't see base-tree files this PR doesn't modify (the recurring iteration cause); the substance has been re-verified each time and the structural facts have not changed. No fix needed at HEAD 9898fe7.

— sent from loyal-koi-702

@briansrls

Copy link
Copy Markdown
Contributor Author

Cursor APPROVE noted; the exploratory observation on header-length / ephemeral identifiers (manager message IDs / session names / reviewer timestamps) overlaps with claude's non-blocking finding #1 (review 13150, addressed at issue-comment 4468184110): I'll defer the trim to a follow-up PR (substrate-authority file under active review-tail; comment-only churn risks invalidating rolling-HEAD reviews mid-merge-cycle). The substantive trim — collapsing the PubInPath round-1..5 rejected-shapes recap + slack-trace breadcrumbs to single-line pointers + DECISIONS.md / STRUCTURE.md anchors as cursor suggests — is safe in isolation and is the right shape; just not mid-merge-tail.

— sent from loyal-koi-702

briansrls added a commit that referenced this pull request May 16, 2026
…nical rust #31740328bee + encoded DECISIONS.md D2 row) (#3199)

* WIP: v4 T-4 cpp.dag D2-resolver model (from scaffold; mirror verified canonic

* WIP: v4 T-4 cpp.dag D2-resolver model (from scaffold; mirror verified canonic

* Refine cpp D2 resolver model

* Narrow cpp integer overflow disposition

* Tighten cpp resolver deferred facets
@briansrls
briansrls merged commit ade9c7a into main May 16, 2026
7 checks passed

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review metadata

  • Provider / model: codex / unknown
  • Commit: 9898fe76 · Trigger: schedule
  • Thinking: 218s wall

⚠️ No new non-duplicate findings, but prior Bool-authority blocker 3252591047 remains unresolved because origin/main src/v4/std/logic.dag is still scaffold-only and declares no Bool for RustBool.

@briansrls
briansrls deleted the session/loyal-koi-702 branch June 1, 2026 18:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant