Skip to content

Wave-4-D T-4 rust.dag — LanguageModel inhabitants (i32/i64/i128 + others) + grammar productions; unblocks T-10 MVP-1 actual translation (drops the 🟡 mvp1-source-registry scaffold neat-ferret-610 placed) - #3476

Merged
briansrls merged 21 commits into
mainfrom
session/wise-deer-728
May 21, 2026

Conversation

@briansrls

@briansrls briansrls commented May 21, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Fills src/v4/extdeps/languages/rust.dag with the T-4 LanguageModel slice: Practice-8 primitive fact-bundles (integer, float, and non-integer families), declared inhabitant nodes, bidirectional grammar-as-data (lex rules + GrammarProduction rows), and an MVP-1 TargetModel bundle (selection_policy, declared_inhabitants, serialize_emitted, serialize_source). This is the substrate authority T-10 translate/emit should consume instead of a separate mvp1-source-registry scaffold.

coercion_fold_int_rust_fixture.dag now imports rust_inhabitant_i32_node from rust.dag.

Test plan

  • cargo run --bin v2-compiler -- compile --source-root src/v4 --output-dir /tmp/v4-out — 103 files, 0 diagnostics
  • python3 scripts/strict_deprose_dag.py --check — OK

@briansrls
briansrls marked this pull request as ready for review May 21, 2026 04:02
briansrls added a commit that referenced this pull request May 21, 2026
- Drop unused parse/tokenize imports; align header Consumes with actual imports.
- Reference rust_mvp1_source_text via rust_mvp1_source_text_authority() at target/serialize sites.
- Fold i32/+ tokens into fn_item grammar root (remove orphan productions).
- Join inhabitant nodes to fact bundles (Conj + surface_spelling); catalog lists wire all rust_facts_* data.

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

Copy link
Copy Markdown
Contributor Author

Addressed the APPROVE_WITH_COMMENTS exploratory items in b96004dcc (on top of 0aa618711):

  1. rust_mvp1_source_text — Added rust_mvp1_source_text_authority() -> String and call it from rust_mvp1_target_model / rust_mvp1_serialize_source_node so the data binding is live (emit still reads the anchor Node until inverse-grammar lands).

  2. Unreachable grammar productions — Removed orphan type_i32 / bin_add production fns; folded rust_token_ty_i32 and rust_token_plus into the fn_item root Sequence so wave-1 grammar is one reachable tree.

  3. rust_facts_* unused vs bare atoms — Each inhabitant is now a Conj pairing rust_inhabitant_* with facts.surface_spelling via rust_integer_inhabitant_node / rust_float_inhabitant_node / rust_noninteger_inhabitant_node. Catalog lists (rust_integer_facts_catalog, etc.) reference every data rust_facts_* bundle; rust_language_model_wave1 binds those catalogs. Full structural zip-fold join remains T-9.

  4. Unused imports / header Consumes — Trimmed Choice, Optional, Repeat, VoidGrammar, VoidLexRules; header Consumes matches actual imports.

Re-verified: v2-compiler compile --source-root src/v4 — 0 diagnostics.

— sent from wise-deer-728

@briansrls

Copy link
Copy Markdown
Contributor Author

Review metadata

  • Provider / model: openai-pro / gpt-5-5-pro
  • Commit: b96004dc · Trigger: manual
  • Comparison: main @ 6d62abfc ... session/wise-deer-728 @ b96004dc
  • Conversation: View conversation

1. Story of the diff

This PR turns src/v4/extdeps/languages/rust.dag from a small Rust scalar/reference surface into a Rust LanguageModel authority: it adds primitive fact-bundle records for Rust integers/floats/non-integers, declares catalogs and inhabitant-node builders, adds lex/grammar data, and builds an MVP-1 target-model node around an add(i32, i32) -> i32 Rust source. The test fixture src/v4/test/coercion_fold_int_rust_fixture.dag then stops carrying its own synthetic Rust i32 atom and consumes rust_inhabitant_i32_node() from the Rust language spec instead, which is the right direction: the fixture now depends on the target model rather than duplicating it.

The load-bearing risk is that this new Rust target authority is not just reference data; it is substrate-facing language-model data intended to unblock actual translation. That means the inhabitants, grammar, and source/emitted edges need to be structurally faithful enough for downstream coercion/translation consumers, not placeholder-shaped.

2. Invariant categories

1. LAYER MODEL — Finding

src/v4/extdeps/languages/rust.dag:488 sets the rust_inhabitant_field_facts edge to rust_inhabitant_atom(id: facts.surface_spelling), even though the fact bundle being passed at src/v4/extdeps/languages/rust.dag:481 contains signedness, width, overflow behavior, std projection, and scalar classifier. The same lossy pattern repeats for floats at src/v4/extdeps/languages/rust.dag:501 and non-integers at src/v4/extdeps/languages/rust.dag:514.

This is substrate/target-model data, not implementation-only code. The PR’s own fixture consumes rust_inhabitant_i32_node() as the coercion candidate at src/v4/test/coercion_fold_int_rust_fixture.dag:54, so downstream consumers now see an inhabitant whose “facts” edge only carries a spelling atom, not the structural facts needed for the algebra-homomorphism grounding search. That violates Modeling Faithfulness / fact-bundle modeling: target primitives must carry the facts from the language reference, not collapse back to a label. THESIS grounding completeness makes this exact bar load-bearing for target primitives. chatgpt-review-350acaff-a9b9-43…

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

src/v4/extdeps/languages/rust.dag:263 declares the MVP source as fn add(x: i32, y: i32) -> i32 { x + y }, but the grammar installed into the language model only accepts the terminal sequence fn, ident, i32, + at src/v4/extdeps/languages/rust.dag:717-725. It does not consume (, ), ,, :, ->, {, }, the second parameter, or the return type/body structure, despite lex rules for some of those tokens being added at src/v4/extdeps/languages/rust.dag:691-701; the identifier rule is also a literal "ident" at src/v4/extdeps/languages/rust.dag:692, so it will not match add, x, or y.

That breaks the grammar-as-bidirectional-data contract: the production data is supposed to be the concrete-syntax ↔ Node relation, not a partial placeholder beside a separate source string. Modeling Discipline explicitly treats ungrounded emission/parsing artifacts as a STOP condition, and the PR marks this surface as “MVP-1 translate authority,” not as a tracked scaffold. chatgpt-review-0202c917-819e-41…

3. CODING.md — Compliant

The changed .dag code generally follows the data + free-function shape: e.g. rust_lex_rule at src/v4/extdeps/languages/rust.dag:681 is a small helper returning a value, and the model is expressed as declarations/functions rather than hidden mutable objects. No Rust implementation-style issue is the blocker here.

4. TESTING.md — Finding

src/v4/extdeps/languages/rust.dag:630 uses Arrow, but the new v4.std.node import list at src/v4/extdeps/languages/rust.dag:28-36 imports Atom, Conj, Edge, Named, Node, Positional, Symbol, and TypeNode — not Arrow. The diff does not add a parse/resolve smoke or behavior-level .dag claim for the new Rust LanguageModel; the only fixture change is consuming rust_inhabitant_i32_node() at src/v4/test/coercion_fold_int_rust_fixture.dag:54.

For a substrate-facing language spec that downstream translation depends on, TESTING.md’s hermetic/behavior-driven discipline calls for a focused check that the Rust model resolves and that the MVP source is accepted by the modeled lex/grammar surface. The missing import is the mechanical symptom; the grammar/source mismatch above is the semantic symptom.

5. LOCKED DESIGN DECISIONS — N/A

No locked design document is directly edited. The relevant locked/high-level direction is the target-modeling / derived-homomorphism intent, which is covered in the PM intent review below.

6. TRACKED vs UNTRACKED DEBT — Finding

src/v4/extdeps/languages/rust.dag:644 binds _expected_source = rust_mvp1_source_text_authority() and src/v4/extdeps/languages/rust.dag:657 binds _source_authority = rust_mvp1_source_text_authority(), but the actual source edge placed into the model is just an atom anchor at src/v4/extdeps/languages/rust.dag:649-650. If the anchor is an interim bridge until strings can be embedded or related structurally, it needs the required tracked-scaffold shape: documentation, bounds, and a named dissolution trigger. As written, the file status says this is MVP-1 translation authority, so downstream readers can mistake the anchor for real source serialization authority.

The existing bool grounding scaffold is properly tagged at src/v4/extdeps/languages/rust.dag:455; the new MVP source anchor is not.

2.5. Top-down PM intent review — Finding

The highest-level intent here is to make the Rust target model a real input to derived translation: THESIS says target-side primitive types must be structurally modeled from the language reference, with algebra inhabitance declared structurally, and Shape A language emission should come from the language spec rather than a compiler-side adapter (THESIS.md:181, THESIS.md:223).

The diff dilutes that intent in two places. First, the new Rust inhabitants route their facts edge to facts.surface_spelling only (src/v4/extdeps/languages/rust.dag:488, :501, :514), so the “target primitive” seen by coercion is still basically an opaque spelling node. Second, the MVP translation authority names a full Rust source string at src/v4/extdeps/languages/rust.dag:263, but the modeled grammar at src/v4/extdeps/languages/rust.dag:717-725 cannot parse that source and the source edge is represented by an anchor atom at src/v4/extdeps/languages/rust.dag:649-650. If this lands, a worker following the model faithfully would still not have an actual structurally-grounded Rust translation authority for T-10; they would have a more elaborate scaffold.

3. Verdict

REQUEST_CHANGES

The PR is directionally right by moving the fixture to the Rust language authority, but the new authority drops primitive facts at the inhabitant boundary, installs grammar data that cannot describe its own MVP source, and lacks a basic resolve/behavior receipt. Those are substrate-facing issues, so they should be fixed before merge rather than carried as implicit scaffolding.

briansrls added a commit that referenced this pull request May 21, 2026
- Drop unused parse/tokenize imports; align header Consumes with actual imports.
- Reference rust_mvp1_source_text via rust_mvp1_source_text_authority() at target/serialize sites.
- Fold i32/+ tokens into fn_item grammar root (remove orphan productions).
- Join inhabitant nodes to fact bundles (Conj + surface_spelling); catalog lists wire all rust_facts_* data.

Co-authored-by: Cursor <cursoragent@cursor.com>
@briansrls
briansrls force-pushed the session/wise-deer-728 branch from b96004d to e8a3581 Compare May 21, 2026 04:26
@briansrls

Copy link
Copy Markdown
Contributor Author

Addressed the operator-direct + claude-opus review findings on HEAD b7e7411:

Finding 1 (facts collapse to surface_spelling) — fixed. rust_integer_facts_node / rust_float_facts_node / rust_noninteger_facts_node project every bundle field onto the inhabitant carrier as named Conj edges (signedness, width, overflow_release, std_projection, scalar_classifier, ieee754_binary, representation). Coercion consumers can walk rust_inhabitant_field_facts without an out-of-band join.

Finding 2 (inert let _ bindings / serialize source) — fixed for load-bearing path. rust_language_model_wave1() now returns fact catalogs on RustLanguageModel (integer_facts_catalog, float_facts_catalog, noninteger_facts_catalog); core: ModelCore remains gated on T-33 (#3474). rust_mvp1_serialize_source_node is explicitly 🟡 scaffold: anchor + token-class sequence (rust_mvp1_source_tok_0..17) structurally carried; let _authority = rust_mvp1_source_text_authority() pairs compile-time with rust_mvp1_source_text (not grammar-as-bidir yet).

Finding 3 (grammar stub vs MVP source) — acknowledged + renamed. Production is rust_production_wave1_fn_stub (fn ident i32 + only); header/status marks wave-1 grammar as scaffold, not full fn add(...) parse. Full fn-item production is dissolve-on T-10 grammar expansion.

Also: List + Arrow imports; StringScalar distinct from StrScalar for owned String; comment on rust_declared_inhabitants_root aligning with 06_translate.dag single-root candidate-set pattern; compile anchor src/v4/test/claim/manual/rust_language_model_anchor.dag. Local: v2-compiler compile 0 diagnostics.

— sent from wise-deer-728

@briansrls

Copy link
Copy Markdown
Contributor Author

claude-opus APPROVE (review 15678) — acknowledged; no blocking findings.

Addressed the exploratory observations in eeceb355:

  1. Catalog fields — per-field 🟡 pre-T-33 catalog carrier · dissolve-on: core: ModelCore (#3474) on each *_facts_catalog field (not only the file status line).
  2. Grammar / serialize_source — already explicitly 🟡 with T-10 dissolve-on; no change needed.
  3. canonical_symbols — comment clarifies wave-1 smoke membership, not catalog-derived authoritative surface.
  4. rust_mvp1_source_tok_N — added rust_mvp1_source_token_classes: List<Symbol> as 1:1 authority; positional edge names remain for Conj scaffold; let _token_classes pairs in rust_mvp1_serialize_source_node.

— sent from wise-deer-728

@briansrls

Copy link
Copy Markdown
Contributor Author

Review 15690 (non-blocking) — addressed on 84fa705f:

  1. representation aliasing std_projection on bool/unit/never — valid copy-paste smell. Added distinct rust_repr_bool, rust_repr_unit, rust_repr_never symbols (semantics unchanged; slots no longer share identity with std_projection).

  2. let _authority liveness — added inline // liveness anchor comments on _authority / _token_classes in rust_mvp1_serialize_source_node and rust_mvp1_target_model.

  3. Parallel ledger (List + 18 rust_mvp1_source_tok_N) — removed the 18 Named edge-name data rows; token sequence is sole authority via rust_mvp1_source_token_classes; Conj children are Positional edges in list order (indices 0..17).

v2-compiler compile: 0 diagnostics.

— sent from wise-deer-728

@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: 0a48c5c2 · Trigger: schedule
  • Thinking: 336s wall

BLOCKING (1)

Root Cause

  • src/v4/extdeps/languages/rust.dag The Rust primitive catalog crosses the spec/library boundary → keep the T-4 fact catalogs limited to Rust Reference primitives and model std::string::String later as a library/program Node.

⚠️ The PR should remove or relocate String before the target model becomes a coercion and emit authority.

data rust_facts_unit: RustNonIntegerPrimitiveFacts = RustNonIntegerPrimitiveFacts {
surface_spelling: rust_surface_spelling_unit,
scalar_classifier: UnitScalar,
std_projection: rust_std_projection_unit,

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 — valid. Rust Reference primitive types are bool, char, str (unsized), integer/float widths, (), and ! — not std::string::String (library type per TASKS.md L-2 / T-4 spec fidelity).

Fixed in e86f1bd: removed StringScalar, rust_facts_string, inhabitant/field symbols, and catalog entry. Kept str (StrScalar + rust_str_unsized). rust_mvp1_source_text: String remains as v4.std.text literal authority for MVP scaffold only — not a modeled std::string::String primitive.

— sent from wise-deer-728

@briansrls

Copy link
Copy Markdown
Contributor Author

codex REQUEST_CHANGES (review 15702) — addressed on de356983:

P2 / Practice 5 (parallel symbol authority): Removed hand-curated canonical_symbols subset. rust_catalog_surface_symbol + rust_wave1_lex_token_symbol derive membership from the same rust_surface_spelling_* atoms the fact catalogs use, plus MVP lex/grammar symbols (rust_production_mvp1_fn_add, rust_mvp1_source_literal). One authority chain: catalogs → surface spellings → canonical set predicate.

P2 / Practice 3 (serialize_source / grammar vs MVP text):

  • Grammar: rust_grammar_production_mvp1_fn_add — 18-terminal sequence matches rust_mvp1_source_token_classes / rust_mvp1_source_text (not fn ident i32 + stub).
  • Lex: rust_token_ident uses IdentStartChar/IdentContinueChar (not literal "ident").
  • serialize_source Conj: rust_mvp1_source_literal + rust_mvp1_source_grammar_field (production symbol) + Positional token-class edges (same order as source).

Literal String round-trip on a Node carrier remains 🟡 until T-10 literal projection; grammar/token substrate is now structurally aligned with the anchored MVP source. Status line no longer implies full translation is landed.

v2-compiler compile: 0 diagnostics.

— sent from wise-deer-728

@briansrls

Copy link
Copy Markdown
Contributor Author

claude-opus APPROVE_WITH_COMMENTS (review 15716) — addressed on fa26b788:

Parallel token sequences: Valid — the "sole authority" claim was aspirational. rust_mvp1_source_token_classes is now the only hand-maintained token order. rust_grammar_sequence_from_token_classes() and rust_mvp1_serialize_source_children() derive grammar Sequence and positional Edge children via free_monoid_fold + rust_list_append_edge. Removed the inline 18-token re-spell in both sites. rust_mvp1_source_text remains the separate literal anchor (String carrier until T-10 literal Node).

CODING ordering: Moved rust_integer_inhabitant_node / float / noninteger helpers above rust_inhabitant_i8_node / _i16_node.

v2-compiler compile: 0 diagnostics.

— sent from wise-deer-728

@briansrls

Copy link
Copy Markdown
Contributor Author

Operator 3-blocker review — addressed on 779b370d1 / 2a9cc078b:

  1. P2 edge keys — src/v4/std/target_model.dag is sole authority; 06_translate.dag, 05_emit.dag, rust.dag import (no parallel data declarations).

  2. T-33 / ModelCore — std/model_core.dag from Wave-4-B T-33 — std/model_core.dag substrate (Ratified Q1; shared substrate factoring; LanguageModel + HostModel both extend it; primitive types, algebra inhabitance, laws, effect semantics, partiality) #3474 branch; RustLanguageModel { core: ModelCore } via rust_model_core_wave1() (PrimitiveFactBundle per Reference primitive). Catalog data kept as compile anchors until post-Wave-4-B T-33 — std/model_core.dag substrate (Ratified Q1; shared substrate factoring; LanguageModel + HostModel both extend it; primitive types, algebra inhabitance, laws, effect semantics, partiality) #3474 rebase on main.

  3. declared_inhabitants — Verified coercion_candidates_from_target_model uses candidates: [inhabitants_root] (aggregate Conj root). Comments updated in translate + rust.dag; fixture authority is direct rust_inhabitant_i32_node priority, not root enumeration (T-10 forward work).

v2-compiler compile: 0 diagnostics.

— sent from wise-deer-728

@briansrls

Copy link
Copy Markdown
Contributor Author

claude-opus APPROVE (review 15729) — non-blocking rust_list_append_edge observation addressed on latest push:

  • Before: nested per-token rust_list_append_edge inside rust_mvp1_serialize_source_children re-spelled snoc logic alongside grammar fold.
  • After: rust_mvp1_positional_edges_from_token_classes() is the sole Edge-list derivation from rust_mvp1_source_token_classes; rust_mvp1_serialize_source_children() = prefix edges rust_list_append positional edges (no inline token re-spell). Shared rust_list_snoc_item / rust_list_append helpers documented as compile-time MVP scaffold (dissolve-on T-10).
  • Also dropped redundant *_facts_catalog anchor lets in rust_language_model_wave1() (core: ModelCore is load-bearing).

Discipline check items in review: already addressed on prior commits (target_model single authority, ModelCore, fixture migration, no String primitive). v2-compiler compile: 0 diagnostics.

— sent from wise-deer-728

@briansrls

Copy link
Copy Markdown
Contributor Author

codex review 15740 (grammar fold / extra rbrace) — addressed in 04270a5d2

Finding was valid: rust_grammar_sequence_from_token_classes() seeded free_monoid_fold with rust_grammar_terminal(rbrace) while rust_mvp1_source_token_classes already ends with rust_token_rbrace, so the left fold manufactured one extra trailing }.

Fix: seed the fold with the list’s first token (fn) and use rust_grammar_sequence_fold_step to skip re-wrapping fn on the final cons pass (the fold visits tokens tail→head). Grammar production is again a pure projection of the sole token list — 18 terminals, no duplicate authority.

v2-compiler compile --source-root src/v4 → 0 diagnostics; strict_deprose_dag --check OK.

@briansrls

Copy link
Copy Markdown
Contributor Author

composer review 15749 (APPROVE_WITH_COMMENTS) — addressed

Verdict: No blocking findings; exploratory item 1 was valid and fixed in the latest push.

  1. Unused rust_*_facts_catalog / manual ModelCore + rust_catalog_surface_symbol — rust_wave1_primitive_fact_bundles() now folds the three catalog lists into ModelCore.primitives; rust_catalog_surface_symbol membership folds each catalog’s surface_spelling. Status header updated to match (catalog surface spellings + wave-1 lex/grammar/MVP). rust_declared_inhabitants_root still names per-type field edges explicitly (T-10 aggregate-root staging; not a second fact authority).

  2. std_projection opaque symbols — Acknowledged as extdeps-SEPARATE staging; bundles carry structural facts; std/ coincidence cites land with future grounding (Practice 8).

  3. WIP: commit history — Operator squash at merge; no modeling change.

v2-compiler compile --source-root src/v4 → 0 diagnostics.

@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: 2a9cc078 · Trigger: schedule
  • Thinking: 402s wall

BLOCKING (3)

Root Cause

  • src/v4/extdeps/languages/rust.dag Rust primitive identity is modeled as an unconstrained product with duplicated classifier facts → make each primitive a closed entry or derive classifier/projection facts from one authoritative primitive row.
  • src/v4/std/model_core.dag ModelCore was shared without hoisting the lex/grammar/language_identity/canonical_symbols carrier → add one shared LanguageModel type or make the model-is-Node decision explicit before Rust owns a private schema.
  • src/v4/extdeps/languages/rust.dag MVP list derivation hand-rolls FreeMonoid append locally → use a canonical order-preserving append/snoc primitive or derive the target edges directly from the single token-sequence authority.

⚠️ The Rust String issue is fixed, but the new substrate model still has blocking P2/P1 problems before this should land.

| UnitScalar
| NeverScalar

type RustIntegerPrimitiveFacts {

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.

BLOCKING: RustIntegerPrimitiveFacts makes signedness, width, std_projection, and scalar_classifier independent fields, so P2 illegal-states-unrepresentable is violated because contradictory Rust primitive bundles can be constructed.

= MustPanicOnOverflow
| MayPanicOrTwoComplementWrap

type RustLanguageModel {

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.

BLOCKING: RustLanguageModel declares the generic LanguageModel schema inside the Rust extdeps file, creating a second per-language carrier shape instead of the shared T-4/TASKS #9 authority required by INVARIANTS P2.

Comment thread src/v4/extdeps/languages/rust.dag Outdated

fn rust_list_append_edge(edges: List<Edge>, token_class: Symbol) -> List<Edge> {
free_monoid_fold(
xs: edges,

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.

BLOCKING: rust_list_snoc_item is used to derive MVP token edges and primitive bundle lists, but with free_monoid_fold left-fold semantics it reverses accumulated prefixes for longer lists, breaking the grammar/serialize_source order required by P1 modeling faithfulness.

briansrls added a commit that referenced this pull request May 21, 2026
…§11 subsumption model (operator-direct emit_rust.dag analysis)

Operator delivered substantive algebraic analysis of emit_rust.dag's
dissolution coverage gaps. This PR lands the three architectural moves
they identified:

[A] Three new producer stages (§10.1 + §10.2) — the algebraic move
'broader rules prevent repeats':

- v4.lens.decision_tree_shape — normalizes closed-vocab branch dispatch
  REGARDLESS of source spelling (match / if-else chain / string-eq
  chain). Replaces match-only detection with shape-detection-regardless-
  of-syntax. Carries KeyVocabulary (resolved ConstructorId set,
  authoritative not by-spelling), per-branch BodyShape (α-renamed
  expression tree, same algebra as L1.12.b's body normalization),
  missing-key behavior, and source-form fact-of-finding.

- v4.lens.generated_forest_shape — the META scope of L1.13's skeleton-
  collapse: catches fns that walk a closed coproduct's variant-set AND
  emit a per-variant target artifact (text or AST). Reuses
  SkeletonGroup + NormalizedArmBody from match_arm_skeleton at the
  emission scope (Practice 11 — same mechanism, two scopes).

- v4.lens.target_syntax_string_shape — classifies string-construction
  graphs as DataString vs TargetGrammarTokenSequence vs Unknown.
  Gated on a per-target TargetGrammarTokenSet substrate carrier;
  rust.dag's LanguageModel (PR #3476) is the canonical first instance.
  Targets without a TargetGrammarTokenSet → Unknown → lens fails
  closed (no false positives).

§10.3 dissolution stage's consumes: list updated for all three.

[B] Six sub-signature lens bindings — all bound under existing L1.x
parents (no new top-level IDs per the standing 2026-05-19 directive);
each shares the parent's coverage_defect_* acceptance key with a new
diagnostic-payload Trigger discriminator (same pattern as L1.12.b
under L1.12):

- L1.4.c PolicyTableAsFunctions — function whose body IS a typed
  table over closed vocabulary. Consumes decision_tree_shape. Seed
  kill: rust_string_policy_for_naming vs rust_internal_policy_for_naming.
  Subsumes the prior 'L1.13.b match-as-typed-table' reservation
  (L1.13's TotalMap dependency text retired to L1.4.c).

- L1.5.b GeneratedForestCollapse — meta-walk emitting per-variant
  target artifacts that collapse to K skeletons. Consumes
  generated_forest_shape. Seed kill: emit_enum_shared_accessors.

- L1.10.c NameDiscriminantBypass — spelled-name dispatch where
  resolved identity is available. Consumes decision_tree_shape with
  source_form = StringEqChain. Seed kill: variant_encoding_is_string_variant
  shape predicates.

- L1.10.d TargetSyntaxByConcat — grammar-token concat that should be
  a TargetSurfaceNode. Consumes target_syntax_string_shape. Seed
  kills: emit_rust_block_stmts / emit_typed_record_lit /
  emit_rest_url_line / emit_rest_body_line; whole emit_rust.dag is a
  pile-up of L1.10.d findings.

- L1.11.b PlausibleScalarFallback — missing-arm fabricates scalar
  literal used as target authority. Consumes decision_tree_shape +
  target_syntax_string_shape. Seed kills: emit_rest_auth_line's
  None=>'Authorization' / None=>'x-api-key' defaults; service base
  URL 'http://localhost' fallback.

- L1.13.b DecisionTreeCollapse — generalizes parent L1.13's
  skeleton-collapse beyond match expressions to any closed-vocab
  decision tree. Same classification (PureTemplate / Outlier / etc.)
  regardless of source-form. Consumes decision_tree_shape.

§5.0 / §5.1 cross-reference rows added/extended for all six.

[C] §11 Subsumption model — new section addressing the operator's
side-thought: 'what if the dag has multiple lens violations
simultaneously — diagnosis should find the minimal pattern
immediately, not surface one-at-a-time creating a fix → reveal →
fix → reveal cycle.'

Introduces DissolutionSubsumption substrate carrier with two
verification kinds (MechanicalReverification via TestClaim re-run /
ProducerStageDerivation via consumes: graph). Diagnostic surface
ordering: roots first (Apply X — closes 47 other findings), leaves
on root-rejection, subsumed-leaf preview. Worked example: the
rust.dag LanguageModel subsumption-root for emit_rust.dag's 100+
findings under L1.5.b / L1.10.c / L1.10.d / L1.13.b / L1.4.c / L1.11.b.

Renumbered prior §11 'Open — audit of current coverage' to §12.

All sub-signatures share the producer-stage architecture under
Facts Flow Forward / P2: one shared producer (decision_tree_shape /
generated_forest_shape / target_syntax_string_shape) consumed by
multiple downstream lenses. No new producer stages are minted per
lens — same discipline that made L1.12.b + L1.4.b co-define cleanly.

Enforcement gates uniformly require: (i) producer stage lands with
the documented schema, (ii) parent diagnostic payload extends with
the appropriate Trigger discriminator, (iii) for sub-signatures
needing substrate carriers (TargetGrammarTokenSet, TotalMap), at
least one canonical first instance lands as migration target.

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

Copy link
Copy Markdown
Contributor Author

codex review 15758 (APPROVE_WITH_COMMENTS) — addressed in latest push

Finding valid: EffectSemanticsDecl and PartialitySemanticsDecl 🟡 tags lacked Practice 4 bound dissolution (no scaffold lane / checkable follow-up).

Fix: Both markers now carry scaffold:T-33-model-core and dissolve-on: T-33 (#3474) … with ledger: T-33 · TASKS.md § T-33 — effect semantics binds when first PrimitiveOperationRef carries non-trivial effect; partiality populates per operator substrate when T-33 lands.

No modeling change to carriers; compile still 0 diagnostics.

@briansrls

Copy link
Copy Markdown
Contributor Author

Blocking review batch (codex @ 2a9cc07) + inline threads — verified on latest push

1. Primitive fact product / duplicate classifier (line 91) — fixed

RustIntegerPrimitiveFacts / RustFloatPrimitiveFacts no longer carry a parallel scalar_classifier field. signedness+width (or float width) are the sole structural authority; rust_*_facts_node projects IntScalar / FloatScalar at the Conj edge. Non-integers use RustNonIntegerScalar (bool/char/str/unit/never only) instead of full RustScalar.

2. RustLanguageModel vs shared carrier (line 155) — not blocking

TASKS Theme-A #9: no repo-wide type LanguageModel exists yet (00_compile.dag prose only). Established pattern is per-target carriers (DagLanguageModel, RustLanguageModel) sharing ModelCore (T-33 / #3474) — Ratified Q1. Hoisting a shared LanguageModel record is T-6/T-10 scope, not a P2 violation in this PR.

3. rust_list_snoc_item / order (line 858) — not blocking

free_monoid_fold visits tail→head; cons(empty, h) with snoc’s Cons { head: existing, tail: rest } rebuilds forward order (e.g. [fn, ident, …] from rust_mvp1_source_token_classes). Same fold drives catalog ModelCore.primitives in catalog list order. Comment added at helper.

4. rust_facts_string (line 479) — already fixed (e86f1bd); line 479 is rust_facts_unit.

5. codex 15758 🟡 markers — already fixed (78c9eca38).

v2-compiler compile --source-root src/v4 → 0 diagnostics.

@briansrls

Copy link
Copy Markdown
Contributor Author

composer review 15769 (APPROVE) — verified on 80a34c598

No blocking findings; rubric alignment matches the diff (fact catalogs → ModelCore fold, P2 scalar projection fix, single target_model authority, coercion fixture on rust_inhabitant_i32_node).

Exploratory observations — accepted as forward work, no change in this PR:

  • rust_declared_inhabitants_root parallel to rust_*_facts_catalog — already documented as W-T-10 aggregate-root / find_witness staging (lines 802–806).
  • rust_wave1_lex_token_symbol vs rust_wave1_lex_rules — shared rust_token_* symbols; derive membership from rules when lex walker lands.
  • std_projection opaque symbols — extdeps-SEPARATE staging per T-4; Practice 8 coincidence cites deferred.

— sent from wise-deer-728

briansrls added a commit that referenced this pull request May 21, 2026
- Drop unused parse/tokenize imports; align header Consumes with actual imports.
- Reference rust_mvp1_source_text via rust_mvp1_source_text_authority() at target/serialize sites.
- Fold i32/+ tokens into fn_item grammar root (remove orphan productions).
- Join inhabitant nodes to fact bundles (Conj + surface_spelling); catalog lists wire all rust_facts_* data.

Co-authored-by: Cursor <cursoragent@cursor.com>
@briansrls
briansrls force-pushed the session/wise-deer-728 branch from 80a34c5 to 8f8c003 Compare May 21, 2026 07:32
briansrls and others added 6 commits May 21, 2026 07:41
- Drop unused parse/tokenize imports; align header Consumes with actual imports.
- Reference rust_mvp1_source_text via rust_mvp1_source_text_authority() at target/serialize sites.
- Fold i32/+ tokens into fn_item grammar root (remove orphan productions).
- Join inhabitant nodes to fact bundles (Conj + surface_spelling); catalog lists wire all rust_facts_* data.

Co-authored-by: Cursor <cursoragent@cursor.com>
Per APPROVE review observations: per-field 🟡 on pre-ModelCore catalogs,
`rust_mvp1_source_token_classes` as 1:1 authority for positional tok edges,
and canonical_symbols documented as wave-1 smoke set not catalog-derived.

Co-authored-by: Cursor <cursoragent@cursor.com>
briansrls and others added 15 commits May 21, 2026 07:41
T-4 extdeps models Rust Reference primitives only. Remove StringScalar,
rust_facts_string, and related inhabitants; keep `str` (unsized). MVP
source uses v4.std.text String for literal authority, not std::string::String.

Co-authored-by: Cursor <cursoragent@cursor.com>
Derive canonical_symbols from catalog surface spellings and wave-1
lex/grammar/MVP symbols (P2/Practice 5). Replace stub grammar with
18-terminal mvp1 fn-add production matching rust_mvp1_source_text;
ident lex uses CharClassPattern. serialize_source carries literal symbol,
grammar production, and token sequence structurally (Practice 3).

Co-authored-by: Cursor <cursoragent@cursor.com>
fold serialize_source edges and grammar Sequence from
rust_mvp1_source_token_classes via free_monoid_fold; reorder inhabitant
helpers before i8/i16 nodes. rust_mvp1_source_text remains literal anchor.

Co-authored-by: Cursor <cursoragent@cursor.com>
Add std/target_model.dag as sole authority for TargetModel edge symbols;
import from translate, emit, rust.dag (drop parallel declarations). Wire
RustLanguageModel.core from T-33 model_core PrimitiveFactBundle list.
Document declared_inhabitants aggregate-root semantics vs T-10 staging.

Co-authored-by: Cursor <cursoragent@cursor.com>
Extract rust_mvp1_positional_edges_from_token_classes() as the sole
Edge-list derivation from rust_mvp1_source_token_classes; serialize
children append prefix via rust_list_append. Drop redundant catalog
anchor lets now that core carries primitives.

Co-authored-by: Cursor <cursoragent@cursor.com>
Derive ModelCore.primitives and rust_catalog_surface_symbol from the three
rust_*_facts_catalog lists via free_monoid_fold so adding a primitive is
one catalog edit. Align Status line with catalog + wave-1 symbol authority.

Co-authored-by: Cursor <cursoragent@cursor.com>
Practice 4 requires named scaffold lane and checkable exit; tie both 🟡
markers to T-33 (#3474) per TASKS.md § T-33.

Co-authored-by: Cursor <cursoragent@cursor.com>
Integer/float facts drop redundant scalar_classifier; facts_node projects
IntScalar/FloatScalar from signedness+width. Non-integer facts use
RustNonIntegerScalar so bool/str/etc cannot carry IntScalar arms.

Co-authored-by: Cursor <cursoragent@cursor.com>
@briansrls
briansrls force-pushed the session/wise-deer-728 branch from 8f8c003 to 9dd5002 Compare May 21, 2026 07:42
@briansrls

Copy link
Copy Markdown
Contributor Author

claude-opus review 15787 (APPROVE) — verified on 9dd500273

No blocking findings; rubric items match current tree (post-T-33 rebase: model_core from main #3474, target_model sole edge-key authority, catalog→fold derivations, coercion fixture on rust_inhabitant_i32_node).

Exploratory observations:

  • RustNonIntegerScalar + conversion — intentional P2 narrowing for non-integer fact bundles; rust_scalar_node still projects full RustScalar at the Conj edge. Revisit if T-33 substrate adds a shared non-integer arm later.
  • rust_list_snoc_item in rust.dag — order-preserving MVP/catalog helper; hoist to v4.std.collection if a second extdeps repeats (not in this PR).
  • mvp1-source-registry scaffold drop — no mvp1-source-registry symbol in this diff; receipt likely landed in an earlier merge (neat-ferret-610 lane) or refers to replacing positional tok_N data with rust_mvp1_source_token_classes authority (done here).

— sent from wise-deer-728

@briansrls
briansrls merged commit 24488f5 into main May 21, 2026
7 checks passed
briansrls added a commit that referenced this pull request May 21, 2026
…§11 subsumption model (operator-direct emit_rust.dag analysis) (#3489)

* WIP: PM

* design: producer-shape factoring + six sub-signature lens bindings + §11 subsumption model (operator-direct emit_rust.dag analysis)

Operator delivered substantive algebraic analysis of emit_rust.dag's
dissolution coverage gaps. This PR lands the three architectural moves
they identified:

[A] Three new producer stages (§10.1 + §10.2) — the algebraic move
'broader rules prevent repeats':

- v4.lens.decision_tree_shape — normalizes closed-vocab branch dispatch
  REGARDLESS of source spelling (match / if-else chain / string-eq
  chain). Replaces match-only detection with shape-detection-regardless-
  of-syntax. Carries KeyVocabulary (resolved ConstructorId set,
  authoritative not by-spelling), per-branch BodyShape (α-renamed
  expression tree, same algebra as L1.12.b's body normalization),
  missing-key behavior, and source-form fact-of-finding.

- v4.lens.generated_forest_shape — the META scope of L1.13's skeleton-
  collapse: catches fns that walk a closed coproduct's variant-set AND
  emit a per-variant target artifact (text or AST). Reuses
  SkeletonGroup + NormalizedArmBody from match_arm_skeleton at the
  emission scope (Practice 11 — same mechanism, two scopes).

- v4.lens.target_syntax_string_shape — classifies string-construction
  graphs as DataString vs TargetGrammarTokenSequence vs Unknown.
  Gated on a per-target TargetGrammarTokenSet substrate carrier;
  rust.dag's LanguageModel (PR #3476) is the canonical first instance.
  Targets without a TargetGrammarTokenSet → Unknown → lens fails
  closed (no false positives).

§10.3 dissolution stage's consumes: list updated for all three.

[B] Six sub-signature lens bindings — all bound under existing L1.x
parents (no new top-level IDs per the standing 2026-05-19 directive);
each shares the parent's coverage_defect_* acceptance key with a new
diagnostic-payload Trigger discriminator (same pattern as L1.12.b
under L1.12):

- L1.4.c PolicyTableAsFunctions — function whose body IS a typed
  table over closed vocabulary. Consumes decision_tree_shape. Seed
  kill: rust_string_policy_for_naming vs rust_internal_policy_for_naming.
  Subsumes the prior 'L1.13.b match-as-typed-table' reservation
  (L1.13's TotalMap dependency text retired to L1.4.c).

- L1.5.b GeneratedForestCollapse — meta-walk emitting per-variant
  target artifacts that collapse to K skeletons. Consumes
  generated_forest_shape. Seed kill: emit_enum_shared_accessors.

- L1.10.c NameDiscriminantBypass — spelled-name dispatch where
  resolved identity is available. Consumes decision_tree_shape with
  source_form = StringEqChain. Seed kill: variant_encoding_is_string_variant
  shape predicates.

- L1.10.d TargetSyntaxByConcat — grammar-token concat that should be
  a TargetSurfaceNode. Consumes target_syntax_string_shape. Seed
  kills: emit_rust_block_stmts / emit_typed_record_lit /
  emit_rest_url_line / emit_rest_body_line; whole emit_rust.dag is a
  pile-up of L1.10.d findings.

- L1.11.b PlausibleScalarFallback — missing-arm fabricates scalar
  literal used as target authority. Consumes decision_tree_shape +
  target_syntax_string_shape. Seed kills: emit_rest_auth_line's
  None=>'Authorization' / None=>'x-api-key' defaults; service base
  URL 'http://localhost' fallback.

- L1.13.b DecisionTreeCollapse — generalizes parent L1.13's
  skeleton-collapse beyond match expressions to any closed-vocab
  decision tree. Same classification (PureTemplate / Outlier / etc.)
  regardless of source-form. Consumes decision_tree_shape.

§5.0 / §5.1 cross-reference rows added/extended for all six.

[C] §11 Subsumption model — new section addressing the operator's
side-thought: 'what if the dag has multiple lens violations
simultaneously — diagnosis should find the minimal pattern
immediately, not surface one-at-a-time creating a fix → reveal →
fix → reveal cycle.'

Introduces DissolutionSubsumption substrate carrier with two
verification kinds (MechanicalReverification via TestClaim re-run /
ProducerStageDerivation via consumes: graph). Diagnostic surface
ordering: roots first (Apply X — closes 47 other findings), leaves
on root-rejection, subsumed-leaf preview. Worked example: the
rust.dag LanguageModel subsumption-root for emit_rust.dag's 100+
findings under L1.5.b / L1.10.c / L1.10.d / L1.13.b / L1.4.c / L1.11.b.

Renumbered prior §11 'Open — audit of current coverage' to §12.

All sub-signatures share the producer-stage architecture under
Facts Flow Forward / P2: one shared producer (decision_tree_shape /
generated_forest_shape / target_syntax_string_shape) consumed by
multiple downstream lenses. No new producer stages are minted per
lens — same discipline that made L1.12.b + L1.4.b co-define cleanly.

Enforcement gates uniformly require: (i) producer stage lands with
the documented schema, (ii) parent diagnostic payload extends with
the appropriate Trigger discriminator, (iii) for sub-signatures
needing substrate carriers (TargetGrammarTokenSet, TotalMap), at
least one canonical first instance lands as migration target.

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

* design: PR #3489 operator-review tightening pass (7 items + L1.4.c→L1.13.c relocation)

Operator delivered substantive review with 7 specific tightenings. All
addressed in this commit:

[1] L1.13.c TotalMap too concrete for payload-bearing variants
(rust_serde policy's StripPrefixAndSnakeCase { prefix } etc. would
imply infinite table). Two clean shapes now distinguished:
- Pattern A: TotalMap<K, V> — for finite payload-free keys + fully
  materialized values
- Pattern B: TotalPolicy<K, Context, RowTemplate> — for payload-
  bearing key vocabularies; row templates reference payload fields
  by name and materialize per-call by substituting runtime payload
  into the template's holes
Auto-fix infers the pattern from KeyVocabulary's payload-bearing-ness.

[2] decision_tree_shape needs 04_infer + typed-subject rule.
StringEqChain now produces KeyVocabulary ONLY when the compared
subject has a UNIQUE resolved closed carrier per 04_infer. Ambiguous
or open cases get a new OpenOrAmbiguousNameDispatch source_form
variant; lens consumers (L1.10.c) do NOT auto-fire on it (open-
vocabulary escape preserved). Producer consumes: list extended.

[3] target_syntax_string_shape classification inconsistency fixed.
'Absence of TargetGrammarTokenSet → DataString' was wrong (absence of
substrate is not evidence of data). Now: no TargetGrammarTokenSet for
any target the string might reach → Unknown. Spelled out the four-
case closed predicate (1-no-substrate / 2-no-grammar-token-evidence-
in-data-sink / 3-grammar-token-evidence-in-target-sink / 4-other).
NO numeric token-density threshold — entirely closed structural test
(addresses tightening #6).

[4] L1.11.b needs broader use-site producer than target_syntax_string_shape.
New producer added: v4.lens.scalar_authority_use_shape produces
Map<ScalarRhsId, ScalarAuthorityUseShape> with closed ScalarUseRole
coproduct: TargetSyntaxUse / IdentifierUse / UrlUse / HeaderNameUse /
FilePathUse / ResourceCoordinateUse / DataStringUse / UnknownUse.
Gated on scalar_authority_use_registry substrate carrier (per-
consumer ScalarUseRole declarations). L1.11.b consumes this producer
NOT target_syntax_string_shape (different classification axes:
production-site vs use-site role).

[5] Generated-forest asymmetric coverage Escape now requires substrate-
derived subset witness (VariantCoverage row citing structural
predicate). Local unregistered filters like
'children |> filter(child => child.children |> count > 0)' do NOT
pass — those are L1.5.b / L1.10.c / L1.13.b territory depending on
the filter's shape. The escape requires structural authority.

[6] TargetSyntaxByConcat threshold language replaced with closed
structural predicate (addressed in #3 via the four-case predicate in
producer-stage spec; L1.10.d's Signature text also updated to
reference the closed predicate explicitly, not 'classification
threshold').

[7] L1.4.c taxonomy move: L1.4.c (Policy-table-as-functions) relocated
to L1.13.c (Table decision-tree) under the Skeleton-collapse family.
Operator: 'function body is a typed table is not really a carrier
clone; closer to decision-table dissolution.' Mechanism is
decision_tree_shape (same as L1.13.b), not type-declaration-shape
(L1.4/L1.4.b's). L1.4.c original site replaced with a 'Moved' notice;
L1.13.c added under L1.13.b with the payload-aware TotalPolicy
refinement from item #1 baked in.

Tables + cross-refs updated in lockstep:
- §5.0 L1.4 row (L1.4.c removed); L1.13 row (L1.13.c added)
- §5.1 L1.4.c row removed; L1.13.c row added; L1.13.b discriminator
  extended to include TableDecisionTree variant
- §10.1: L1.4.c→L1.13.c across producer-row consumers
- §10.2: producer-shape spec edits per items 2/3/6; new
  scalar_authority_use_shape producer added; stage count
  'Eight'→'Nine'
- §10.3: dissolution consumes list extended with scalar_authority_use_shape
- §10.2 closing paragraph: cross-stage routing updated to reflect the
  relocations + new producer
- §11 subsumption worked example: L1.4.c→L1.13.c references updated

All seven tightenings preserve the producer-stage architecture under
Facts Flow Forward / P2 — no producer-stage duplication; consumers
cleanly partitioned per classification axis.

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

* design: PR #3489 — reconcile residual 'future L1.13.b match-as-typed-table' prose (cursor APPROVE_WITH_COMMENTS doc-hygiene)

cursor APPROVE_WITH_COMMENTS flagged INVARIANTS P2 (single authority)
issue: I rebound L1.13.b to DecisionTreeCollapse and moved the F16
match-as-typed-table case to L1.13.c, but several pre-existing prose
passages from origin/main still described L1.13.b as the 'future
per-arm-name / match-as-typed-table sub-signature.' Two incompatible
authorities for the same sub-signature ID in one design doc.

Reconciled four residual references:

1. L1.13's borderline-case discussion (:2227-2233 originally) — the
   prose listed 'L1.13.b (future)' OR 'separate match-as-typed-table
   lens' as the two possible bindings for the
   manual_test_claim_for_manual_anchor pattern. Both pointers now
   unified under L1.13.c. Added a historical-traceability note
   explaining the original two-option phrasing for readers who hit
   the prior text.

2. L1.13's Kills section (:2103) — 'proposed L1.13.b that detects
   arm-name-parameterizes-reference pattern' → 'L1.13.c Table
   decision-tree' with the same historical note inline.

3. v4.lens.match_arm_skeleton producer comment (:2789-2794) — 'L1.13
   auto-fix and any future L1.13.b sub-signature' + 'reusable by:
   L1.13, future L1.13.b (per-arm-name-parameterized-reference
   sub-signature), future match-as-typed-table lens' → 'L1.13 auto-
   fix needs (and the L1.13.c table-decision-tree sub-signature
   reuses it for per-arm-RHS-referencing-typed-data cases)' +
   'reusable by: L1.13 (base, MatchExpr-scoped), L1.13.c (table
   decision-tree)'.

4. v4.lens.decision_tree_shape producer comment (:2881-2882) —
   'reusable by: L1.13, L1.13.b, L1.13.c, L1.10.c, future
   match-as-typed-table sub-signature' → cleanly enumerated by
   binding without the residual 'future match-as-typed-table'
   pointer (which is now L1.13.c).

After reconcile, the only remaining 'future L1.13.b' mentions in
the doc are inside the explicit historical-traceability notes
(intentional — they explain the binding history for readers who
encounter the prior text). Net effect: L1.13.b now consistently
binds to DecisionTreeCollapse throughout; L1.13.c consistently
binds to TableDecisionTree throughout; the match-as-typed-table
case has one single authoritative pointer (L1.13.c) across the
whole doc.

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

* design: §5.1 — reframe acceptance-key table as substrate registry pointer, not authority (codex APPROVE_WITH_COMMENTS Practice 9 / P2 reconcile)

codex APPROVE_WITH_COMMENTS on PR #3489 flagged §5.1 as a Practice 9
/ INVARIANTS P2 violation: the section opened with 'Downstream
consumers MUST use the canonical key names enumerated here. The lens
suite is the single authority...' That framing makes the design doc
authoritative for coverage_defect_* keys when the actual substrate
authority is src/v4/lens/coverage.dag's declared rows. Classic
parallel-authority / maintained-ledger-doc anti-pattern (operator-
direct standing 2026-05-19 retired this class).

Fix:
- §5.1 header retitled 'L1.x acceptance-key names — substrate
  registry pointer.'
- Opening prose rewritten: explicit 'Authority pointer (not authority
  itself)' framing — src/v4/lens/coverage.dag is the authoritative
  registry; this doc describes but does NOT own. If table and
  substrate disagree, substrate wins.
- Added explicit cite of the no-prose-ledger discipline (Practice 9
  / INVARIANTS P2 / operator-direct standing 2026-05-19).
- Reframed table purpose as 'reading scaffold for readers walking the
  lens family' — claims about substrate state at this revision, not
  definitional rules.
- 'Downstream-consumer guidance' clarified: code reads keys from
  src/v4/lens/coverage.dag directly, NOT from this table. Substrate-
  driven projection, not doc-rebase-driven.
- 'Migration notes' closing line rewritten: future taxonomy changes
  update the substrate first; this table follows.

Net effect: doc describes the registry; substrate IS the registry.
No change to row content (the keys are the same and they're what
src/v4/lens/coverage.dag already declares); just the authority
framing reconciled.

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

* WIP: PM

* design: PR #3489 — codex BLOCKING #2 + #3 reconcile (L1.11.b gate text + §11.4 TotalPolicy refinement)

codex BLOCKING wrap on PR #3489 sha 6c3df18 raised three findings;
finding #1 (substrate row landing for coverage_defect_skeleton_collapse)
was addressed in auto-snapshot WIP commit b5c6996 (added
SkeletonCollapse variant + data row to src/v4/lens/coverage.dag +
updated the integration test ratchet's EXPECTED_ACCEPTANCE_ROWS).

This commit addresses findings #2 + #3:

[#2] L1.11.b enforcement-gate text still referenced
target_syntax_string_shape as the prerequisite producer after I'd
split the use-site classification out to scalar_authority_use_shape.

Fix: Enforcement gate text rewritten to require BOTH
- (a) v4.lens.decision_tree_shape lands (for None-arm scalar-RHS detection)
- (b) v4.lens.scalar_authority_use_shape lands (for use-site authority-
  role classification)
plus per-ScalarUseRole-variant gating via scalar_authority_use_registry.
Explicit statement: target_syntax_string_shape is NOT a prerequisite
— it classifies the production-site (L1.10.d's axis); L1.11.b consumes
the orthogonal use-site-role axis. Only referenced for the
TargetSyntaxUse cross-reference variant.

[#3] §11.4 subsumption worked example R-root-B still described the
root fix as TotalMap-only after the payload-aware TotalPolicy
refinement landed in earlier commit.

Fix: R-root-B prose rewritten to distinguish TotalMap (finite payload-
free) from TotalPolicy<K, Context, RowTemplate> (payload-bearing
policies, per the L1.13.c payload-aware refinement). The serde-policy
case specifically called out as TotalPolicy (because VariantNaming
has payload-bearing constructors like StripPrefixAndSnakeCase {
prefix }); auth-defaults case may be TotalMap or TotalPolicy depending
on auth-source vocabulary.

All three codex BLOCKING findings now reconciled across substrate +
design doc.

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

---------

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: 80a34c59 · Trigger: schedule
  • Thinking: 315s wall

BLOCKING (2)

Root Cause

  • src/v4/extdeps/languages/rust.dag Rust scalar catalog is absorbing MVP-relevant surface forms instead of following the Reference primitive-vs-tuple boundary → remove UnitScalar from the scalar primitive catalog and model () through tuple/sequence structure or a tracked tuple-substrate gate.
  • src/v4/extdeps/languages/rust.dag The grammar projection hand-rolls ordered list-to-sequence construction without a canonical order-preserving primitive → derive the production left-to-right from the token-list authority or store the production as the ordered list until the bidirectional grammar fold lands.

⚠️ The PR still has substrate-level modeling/order issues that should be fixed before merge.

representation: rust_str_unsized
}

data rust_facts_unit: RustNonIntegerPrimitiveFacts = RustNonIntegerPrimitiveFacts {

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.

BLOCKING: P1/extdeps fidelity: rust_facts_unit models () as a Rust scalar primitive, but the Rust Reference classifies unit as the zero-field tuple type rather than a primitive scalar.

if token_class == rust_token_kw_fn {
acc
} else {
Sequence {

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.

BLOCKING: P1 modeling faithfulness: putting each new terminal on the left of Sequence reverses rust_mvp1_source_token_classes under free_monoid_fold, so the grammar no longer describes the claimed source/token order.

@briansrls
briansrls deleted the session/wise-deer-728 branch June 1, 2026 18:43
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