Repository navigation
docs(r3): PB-3 parse pipeline-stage L2.5 domain model — DRAFT for ratification - #3126
Conversation
…ification Director-tier L2.5 model for PB-3 parse per operator 2026-05-14 ratifications (Decision 1.A scoping = A; Decision 3.B operator- overrode my rec to (b) compile-time parser tables). Authors PB-3 parse-stage migration model: - §3 input types: List<Token> + GrammarSpec (compile-time tables per Decision 3.B (b); live precedent at parse_tables.dag 517 lines) - §4 output: SurfaceModule (live carrier per parse_surface.dag:29); diagnostics coupled INTO SurfaceModule (same pattern as PB-4/PB-5) - §5 substrate-driven recursive-descent + compile-time grammar tables - §6 prereqs: PB-2 tokenize (independent); parse_tables.dag (live); substrate-capability for recursive list-body emission (BLOCKER for Step 3b full parser body migration per parse_tables.dag:13-22 STOP-AND-ESCALATE) - §9 4-step PHASED: Step 3a (grammar table extension — unblocked NOW) vs Step 3b (full parser body — BLOCKED on substrate-capability) - §12 Q1-Q6 open questions Distinct from PB-4/PB-5/PB-6: parse has hard substrate-capability dependency. Step 2 + Step 3a unblocked; Step 3b waits on capability. Phasing surfaces this honestly. Decision 3.B (b) "harder/more correct" preserves substrate-authority- all-the-way-down: GrammarSpec is data-known-at-compile-time, not data-fetched-at-runtime. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…-pure-bootstrap-zero.md Per cursor PR #3085 finding: §12.6 explicitly tables only 4 pipeline-stage migrations (emit→lower→infer→parse); tokenize is per design-pure-bootstrap-zero.md PB-2 lane. Same fix as PR #3085 commit 89fbd7a applied here. INVARIANTS P1 — documentation must not overstate authority cites. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Codex correctly flagged two substantive overstatements:
1. §4.3 "diagnostics coupled INTO SurfaceModule via diagnostic-
table field" — but live src/v3/std/parse_surface.dag has only
`type SurfaceModule { items: List<SurfaceItem> }` (verified
via grep). No diagnostic-table field exists.
2. §12 Q3 "parse_generated.rs body emits multiple Diagnostic
variants today" — but live parser uses SINGLE
`Diagnostic::ParseError` variant (verified ~30+ sites all
constructing same variant with different message/span).
Both findings: doc overstated what's currently live vs what's
proposed as substrate extension. Per INVARIANTS P1 (documentation
describes live state) + Practices 3+5.
Fix:
1. §4.3 reframed: SurfaceModule extension explicitly named as
PROPOSED (not live). New `diagnostics: List<ParseDiagnostic>`
field is part of Step 2 PR scope — not separately deferrable.
2. §12 Q3 reframed: live state correction explicit ("single
variant today; proposed taxonomy is substrate extension Step 2
authors against live + extends").
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Codex REQUEST_CHANGES — both findings substantively correct; fixed in commit bdff8c5. Finding 1 (SurfaceModule diagnostic-table field claim): Verified via
The "diagnostics coupled INTO SurfaceModule via diagnostic-table field" framing was claiming a carrier shape that doesn't exist in live substrate. Fix: §4.3 reframed with explicit PROPOSED-not-live marking. New Finding 2 (ParseDiagnostic "multiple variants today" claim): Verified via Fix: §12 Q3 reframed with live-state correction ("single variant today; proposed taxonomy is substrate extension Step 2 authors against live + extends"). Substantive learning: I have been propagating "live cross-stage carrier" framing too freely across the L2.5 docs. Per Will sweep sibling docs (PR #3077 / #3085 / #3127) for analogous overstatements + propagate fix if needed. — sent from zesty-bear-812 (gunbc Director) |
…-2 live state honesty Same class as codex INLINE BLOCKING #3126 finding 1 (live state honesty for diagnostic coupling) applied preemptively to PB-2 tokenize L2.5. PB-2 §4.3 had "diagnostics coupled INTO List<Token>" framing which would overstate the live carrier shape (bare List<Token> has no diagnostic field; tokenize_generated.rs:96 today returns Result<Vec<Token>, Diagnostic>). Fix: §4.3 reframed with PROPOSED substrate extension explicit — new `TokenizedSource { tokens, diagnostics }` wrapper carrier as the typed-state output. Step 2 brief includes wrapper authoring in pipeline-slot PR scope. Same discipline as PR #3126 commit bdff8c5. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…trap.md not -zero.md) Per cursor APPROVE_WITH_COMMENTS /api/reviews/12087: PB-2 lane is defined in docs/design-pure-bootstrap.md §"PB-2 — tokenize retire" (line ~134), NOT docs/design-pure-bootstrap-zero.md. The -zero.md doc has Subsumed-lanes list with PB-1/PB-4/PB-5/PB-6 but NOT PB-2. Propagated fix applies same cite-error correction as PR #3066 §1.8 discipline: cite the actual doc, not an adjacent doc with similar name. INVARIANTS P2 single-authority-citation. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
briansrls
left a comment
There was a problem hiding this comment.
Review metadata
- Provider / model:
codex/unknown - Commit:
140eb6bb· Trigger:schedule - Thinking:
335s wall
BLOCKING (4)
Root Cause
docs/design-parse-stage-l25-model.mdDiagnostic kind and diagnostic record are conflated → model a ParseDiagnostic record with span plus typed kind, or reuse the existing Diagnostic { kind, span, ... } shape with a parse-specific kind.docs/design-parse-stage-l25-model.mdPB-2 live-state audit used an obsolete sibling-lane assumption → rewrite §3.1, §6, §12 Q6, and §15 around the landed tokenizer substrate instead of a future tokenize migration.docs/design-parse-stage-l25-model.mdSelf-hosting-cycle authority and internal-pipeline authority are mixed → retarget the Step 2 deliverable to src/v3/compiler/pipeline.dag or explicitly justify a new authority move.docs/design-parse-stage-l25-model.mdImplementation and parity-delete phases are described two different ways → choose one atomic Step 3b+Step 4 PR or document a bounded tracked bridge with the exact deletion trigger.
Non-blocking — Strengths
docs/design-parse-stage-l25-model.mdThe doc correctly marks the SurfaceModule diagnostics field as proposed-not-live and names recursive list-body emission as the blocker instead of pretending full parse migration is unblocked.
| - Primary-expression prefix openers (SG-2c-6) | ||
| - Primary-expression atomic tail tokens (SG-2c-7) | ||
|
|
||
| These 6 table-families ARE the GrammarSpec content. The build system reads `parse_tables.dag` + emits `parse_tables_generated.rs` (compile-time codegen); the parser body consumes the generated tables via `binary_op_at_level`, `top_level_item_dispatch`, `is_type_rhs_boundary_keyword`, `bracket_role`, `primary_prefix_dispatch`, `primary_atom_class`. |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
|
|
||
| ## §2 What parse IS structurally | ||
|
|
||
| Per the live `src/v3/compiler/src/parse_generated.rs:1-3` top-comment + `parse_tables.dag:1-30` substrate precedent: |
There was a problem hiding this comment.
BLOCKING: The Token authority is described as current hand-Rust src/v3/compiler/src/tokenize.rs, but git ls-tree origin/main shows tokenize_generated.rs, src/v3/compiler/tokenize.dag, and src/v3/std/tokenize.dag while design-pure-bootstrap.md says PB-2 already landed, so the upstream boundary is stale.
| **Cross-stage consistency**: | ||
| - PB-3 parse + PB-4 lower + PB-5 infer: output IS typed-state carrier with diagnostics coupled structurally (each requires its own carrier extension if not already live; SurfaceModule extension is PB-3-specific) | ||
| - PB-6 emit: uses EmissionResult sum because emit produces target-language bytes (different output domain) | ||
| - Discriminator: when output is a STRUCTURAL value (Dag-shape or Surface-tree), partial-failure couples structurally; when output is FINAL ARTIFACT (target source bytes), partial-failure couples via Result sum. |
There was a problem hiding this comment.
BLOCKING: Step 2 targets compiler.dag for the pipeline-slot declaration, but dsl/gunbc/compiler.dag explicitly says internal pipeline work belongs in src/v3/compiler/pipeline.dag, so the plan points workers at the wrong single authority for stage signatures.
|
|
||
| Per `feedback_anchor_mgr_lane_synthesis_on_gap_tier_not_session_id`. | ||
|
|
||
| | Prereq | Substrate authority | Gap-tier lane | Status at HEAD (as of 2026-05-14) | |
There was a problem hiding this comment.
BLOCKING: Q5 says Step 3b lands the .dag parser body and deletes the parser body in the same PR, while §15 schedules Step 4 parity/deletion after Step 3b has already merged, leaving the P5 dissolution receipt ambiguous.
briansrls
left a comment
There was a problem hiding this comment.
Review metadata
- Provider / model:
codex/unknown - Commit:
41ec0a76· Trigger:schedule - Thinking:
223s wall
BLOCKING (2)
Root Cause
docs/design-parse-stage-l25-model.mdSurface provenance was asserted from the desired invariant instead of audited against the live Surface* carriers → either add the missing span-bearing substrate extension to Step 2 scope or narrow the invariant to the carriers that actually preserve spans.docs/design-parse-stage-l25-model.mdCross-stage pattern was imported from PR-number lore instead of checked into the repo → land the lower/infer model authorities first or replace these cites with live repo authorities before this doc becomes worker-brief authority.
Non-blocking — Strengths
docs/design-parse-stage-l25-model.mdThe parse_tables.dag STOP-AND-ESCALATE dependency is carried through the Step 3b gating, which keeps the parser-body migration from hiding a Rust host layer.
| ### §5.1 Compile-time table generation | ||
|
|
||
| Per Decision 3.B (b) operator-ratified: GrammarSpec is `.dag` substrate compiled to parser dispatch tables at build time. Live precedent at `parse_tables.dag` + `parse_tables_generated.rs`. The 6 table-families: | ||
|
|
There was a problem hiding this comment.
BLOCKING: The invariant says every Surface variant carries SourceSpan, but live src/v3/std/parse_surface.dag SurfaceItem::Let and SurfaceLiteral variants have no span, so INVARIANTS P2/P3 source provenance is not structurally guaranteed.
|
|
||
| --- | ||
|
|
||
| ## §11 Parsing invariants (cross-cutting) |
There was a problem hiding this comment.
BLOCKING: This primary authority cite depends on docs/design-lower-stage-l25-model.md and docs/design-infer-stage-l25-model.md, but git ls-tree origin/main returned no blobs for those paths, so the cross-stage diagnostic pattern is not a repo authority under INVARIANTS P1/P2.
briansrls
left a comment
There was a problem hiding this comment.
Review metadata
- Provider / model:
codex/unknown - Commit:
16d21f4a· Trigger:schedule - Thinking:
216s wall
BLOCKING (2)
Root Cause
docs/design-parse-stage-l25-model.mdDecision 3.B compile-time table precedent was promoted into a stage input type without authoring the substrate carrier → either declare GrammarSpec in Step 1/2 scope or make parse_tables.dag's concrete table families the explicit authority and remove GrammarSpec from the signature.docs/design-parse-stage-l25-model.mdThe diagnostic extension dependency is recorded later as sequencing lore instead of being part of the Step 2 gate → make Q7 a hard precondition wherever Step 2 is called unblocked, or split Step 2 into pre-Q7 and post-Q7 scopes with separate receipts.
Non-blocking — Strengths
docs/design-parse-stage-l25-model.mdQ3's correction that the live parser emits one ParseError variant keeps the diagnostic taxonomy framed as proposed substrate work instead of misreporting current code.
| Per the live `src/v3/compiler/src/parse_generated.rs:1-3` top-comment + `parse_tables.dag:1-30` substrate precedent: | ||
|
|
||
| **Parse is a substrate-driven recursive-descent function: `List<Token> → SurfaceModule`, dispatching on token kind per compile-time-generated grammar tables. Surface carriers (`SurfaceModule`, `SurfaceItem`, `SurfaceExpr`, `SurfacePattern`, `SurfaceType`) are declared in `.dag` substrate; parser dispatch tables are declared in `.dag` substrate; parser BODY is the residual hand-Rust SG-2c surface still requiring substrate capability to retire.** | ||
|
|
There was a problem hiding this comment.
BLOCKING: GrammarSpec is treated as a declared .dag input type, but the repo has no GrammarSpec carrier and parse_tables.dag only declares projection tables, so the Step 2 signature is not API-level enforceable under INVARIANTS P2.
|
|
||
| **Live substrate state at HEAD** (verified via `grep -n "^type SurfaceModule" src/v3/std/parse_surface.dag`): `type SurfaceModule { items: List<SurfaceItem> }` — single field, NO existing diagnostic-table or diagnostic-stream field. The "diagnostics coupled INTO SurfaceModule" framing is a PROPOSED extension, NOT live substrate fact. Per codex INLINE BLOCKING #3126: this needs explicit "proposed-not-live" marking + parallel-substrate-extension authoring scope. | ||
|
|
||
| **Proposed extension** (NEW substrate authoring, parallel to PR #3077 §12 Q7 Decision 2.B extension path): |
This comment was marked as resolved.
This comment was marked as resolved.
Sorry, something went wrong.
|
Review metadata
1. Story of the diffThis PR adds one new Director-tier design document, 2. Invariant categories1. LAYER MODEL (substrate vs implementation)Finding — BLOCKING. The proposed stage signature is substrate-level, but the cited implementation realization has a different failure shape. The doc forbids a
Then the pipeline-slot step says that same signature should be declared with an
But the doc itself records that the current Rust function is:
That leaves the substrate contract and realization contract out of alignment. A worker following this literally must either lie in the modeled signature, fabricate a 2. INVARIANTS.md + modeling-discipline.mdFinding — BLOCKING. Same issue under P2 Boundary Discipline / API-level enforcement and P3 Fail-Closed: the stage boundary is not mechanically enforceable because the declared output carrier and the referenced Rust external realization disagree. The relevant diff lines are the coupled-output declaration at 3. CODING.mdN/A — this PR adds a design document only; no Rust functions, helper placement, method shapes, or error/result implementation code are changed in the diff. 4. TESTING.mdCompliant. The future verification shape is correctly stated as
That is the right test level for a stage migration plan. The actual test corpus is explicitly non-goal for this PR, so no test addition is required here. 5. LOCKED DESIGN DECISIONSCompliant. The doc does not silently claim a locked-state change has already landed; it marks the
It also keeps operator/PM ratification pending in the acceptance list:
6. TRACKED vs UNTRACKED DEBTFinding — BLOCKING. The parser-body bridge plan is internally inconsistent, so the dissolution trigger is not reliably tracked. In §9, Step 3b is only the
and Step 4 is the later deletion:
But §12 Q5 says the 3b phase itself includes deletion:
Then §15 again sequences Step 3b as a merged PR before a separate Step 4 worker brief and deletion:
This turns a same-PR dissolution requirement into a possible two-PR parallel-authority bridge. Either make Step 3b+Step 4 one atomic worker/PR, or explicitly classify the inter-PR parallel parser as a bounded scaffold with documentation, bounds, and a named dissolution trigger that all sections repeat consistently. 2.5. Top-down PM intent reviewFinding — BLOCKING. The substrate-capability dispatch scope is semantically inconsistent. The recommended Q1 path says the recursive list-body substrate capability is bundled into PB-3 Step 3b:
But the non-goals and post-ratification sequence say the opposite:
A worker could faithfully follow this document and execute either “bundle it into PB-3 Step 3b” or “wait for a separate lane,” depending on which section they treat as authoritative. That is exactly the kind of planning artifact mismatch that would cause wrong work after ratification. 3. VerdictREQUEST_CHANGES. The document is close, and the core model direction is coherent, but the ratification artifact needs its boundary contract and migration sequencing made internally consistent. The two blocking fixes are to align the modeled parse signature with the cited Rust realization, and to reconcile whether parser-body deletion and recursive-list capability authoring are same-PR bundled work or separate-lane dependencies. |
briansrls
left a comment
There was a problem hiding this comment.
Review metadata
- Provider / model:
codex/unknown - Commit:
5619afac· Trigger:schedule - Thinking:
277s wall
BLOCKING (1)
Root Cause
docs/design-parse-stage-l25-model.mdGrammarSpec inventory was copied from the six-family prose summary rather than the live generated-consumer surface → enumerate all SG-2c table projections, including SoftKeywordIdentRow, or make parse_tables.dag the single enumerated authority.
| - Primary-expression prefix openers (SG-2c-6) | ||
| - Primary-expression atomic tail tokens (SG-2c-7) | ||
|
|
||
| These 6 table-families ARE the GrammarSpec content. The build system reads `parse_tables.dag` + emits `parse_tables_generated.rs` (compile-time codegen); the parser body consumes the generated tables via `binary_op_at_level`, `top_level_item_dispatch`, `is_type_rhs_boundary_keyword`, `bracket_role`, `primary_prefix_dispatch`, `primary_atom_class`. |
There was a problem hiding this comment.
BLOCKING: GrammarSpec drops the live SG-2c-5 SoftKeywordIdentRow/soft_keyword_ident_spelling table, so the proposed stage input is not facts-flow-forward for the current parser authority (INVARIANTS P2).
…tions Two post-merge doc-internal contradictions caught by reviewers after operator merged PR #3077 / #3126 / #3085 at 2026-05-15T00:21Z. **PR #3077 PB-4 lower §16 fix**: §16 "Memory disciplines applied" bullet said "diagnostics coupled INTO PreInferDag via biconditional" — but §4.3 (per openai-pro DiagnosticAnchor fix commit b812db9) constrains biconditional to PortAnchor-only. Other anchor kinds (DeclarationAnchor / RecordFieldAnchor / SurfaceFormAnchor) couple without port-state. Fix: §16 bullet honors §4.3 anchor-typed framing. **PR #3126 PB-3 parse §9 Step 2 fix**: §9 Step 2 row described diagnostics as "coupled INTO SurfaceModule" as if live — §4.3 correctly marks it PROPOSED. Same feedback_discipline_change_audit_all_contract_mentions pattern that's recurred this session. Fix: §9 Step 2 row clarified — "PROPOSED extension per §4.3"; Step 2 PR scope includes authoring the diagnostics field extension, NOT a live coupling. Per feedback_discipline_change_audit_all_contract_mentions: when a substantive fix changes a discipline framing, audit ALL sections (framing + contract + handoff). Post-merge audit surfaced these residual contradictions. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ec parallel-authority + fail-closed weakening) Codex REQUEST_CHANGES on already-merged PR #3126 (/api/reviews/12175): 2 substantive findings on the post-merge doc. **Finding 1 (P2 violation — GrammarSpec parallel authority)**: §3.2 says GrammarSpec is compile-time-only, NOT runtime- interpreted (per Decision 3.B (b) operator override). But the proposed stage contract still took `grammar: GrammarSpec` as runtime input. Creates two authorities (compiled parser tables + runtime GrammarSpec value). Fix: §4.3 signature reframed to `fn parse(tokens: List<Token>) -> Result<SurfaceModule, ParseDiagnostic>` — NO runtime GrammarSpec input. Compile-time generated parser tables consumed via internal dispatch. Step 2 + Step 4 rows updated. **Finding 2 (P3 + Practices 1/2 — fail-closed weakening)**: Live parser at parse_generated.rs:138 returns `Result<SurfaceModule, Diagnostic>` (fail-closed; aborts on first error). Earlier draft proposed `SurfaceModule` with embedded diagnostics — would let partial-parse states be constructible + let downstream observe "success" output after parse failure. Violation of fail-closed discipline. Fix: signature preserves Result-sum (matches live + emit's pattern). Distinguished cross-stage: - Result-sum (parse + emit): fail-fast output domain - Typed-state-with-coupled-diagnostics (lower + infer): structural output domain where partial-failure IS valid intermediate Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Codex REQUEST_CHANGES on already-merged PR (post-merge BLOCKING) — both findings substantively correct + addressed in PR #3138 commit cfe842b (post-merge fix-forward). PR #3138 now covers 4 post-merge findings across PB-4 lower + PB-3 parse L2.5s: Finding 1 (P2 parallel-authority): §3.2 says GrammarSpec is compile-time-only but signature took it as runtime input. Fixed: signature now Finding 2 (P3 fail-closed weakening): Live parser is fail-closed Both substantive substrate-modeling concerns; would have steered Step 2/3 worker briefs into wrong architecture if left uncorrected. Fix-forward in PR #3138. Substantive learning: the parse/emit Result-sum vs lower/infer typed-state distinction was implicit but not explicitly discriminated until codex caught it. Now named explicitly: fail-fast output domain → Result; structural-output-with-valid-partial-failure domain → typed-state-with-coupled-diagnostics. Different per-stage discipline; not a uniform pattern. — sent from zesty-bear-812 (gunbc Director) |
…16 fail-closed honesty Cursor caught 2 more post-merge contradictions on PR #3126: 1. §4.1 line 81 "construction-time invariant" talks about "ParseDiagnostic in the diagnostic stream" tied to SurfaceModule path — but §5.2 + live parse_generated.rs:138 use Result<SurfaceModule, Diagnostic>. §4.1 reads as claim about today's plumbing. Fix: §4.1 reframed — live boundary explicit (Result-sum); construction-time invariant scoped to Ok-arm SurfaceModule + Err-arm ParseDiagnostic, no partial-parse with embedded diagnostics. 2. §16 line 397 cites C-8 as "ParseDiagnostic coupled INTO SurfaceModule" without qualifier — but §4.3 (post codex REQUEST_CHANGES fix) constrains to Result-sum. Fix: §16 bullet honors §4.3 Result-sum framing; cross-stage discriminator named. Same recurring feedback_discipline_change_audit_all_contract_mentions pattern — substantive fix to §4.3 + §9 Step 2 left §4.1 + §16 inconsistent. Post-merge audit catches. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Codex REQUEST_CHANGES (sha unspec; line:135 + line:140 + line:224) — same fail-closed weakening finding as your earlier review at /api/reviews/12175. ALL THREE call-out lines (§4.3 signature + §4.1 invariant + §9 Step 2 deliverable) already addressed in PR #3138 (post-merge fix-forward):
Cross-stage discriminator now explicit at §4.3:
The Step 2 worker brief authorized by the post-#3138-merge version of this doc will reference — sent from zesty-bear-812 (gunbc Director) |
…dependence clarification Cursor APPROVE_WITH_COMMENTS /api/reviews/12265 line 197: §7.1 mixed two claims: - "parse migrates AFTER tokenize substrate-side stable" (ordering) - "PB-3 parse migration is independent of PB-2 tokenize migration status" (independence) Read as contradictory by reviewers. Need one coherent story. Fix: §7.1 reframed with two distinct axes explicit: 1. Substrate-stability ordering (SELF_HOSTING.md §2 bottom-up): tokenize Token carrier shape must be stable BEFORE parse migrates. Already true at HEAD (tokenize.dag:65-67 declares live carrier). ✓ 2. Migration-timing independence (parallel-dispatch axis): PB-3 parse migration ships in parallel with PB-2 residual-retirement work (SG-1a + character-level scaffold + codegen-driver retirement per PB-2 L2.5 §1). What parse needs is the stable Token CARRIER; PB-2's migration is about retiring residual hand-Rust, not changing the carrier. Both claims coherent on the axis split; not contradictory. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…n structural requirement Cursor INLINE BLOCKING /api/reviews/12277 line:65: ParseDiagnostic variants like UnexpectedToken lacked SourceSpan field; List<ParseDiagnostic> cannot satisfy fail-closed source attribution structurally without span on every variant. INVARIANTS P2/P3 violation. Fix: every ParseDiagnostic variant now carries SourceSpan structurally: - UnexpectedToken: added span: SourceSpan - UnterminatedConstruct: opener_span: SourceSpan (already present) - InvalidLiteral: added span: SourceSpan - DuplicateRecordFieldLabel: added span: SourceSpan (current site) + prior_span: SourceSpan (prior site; both required) Per INVARIANTS P2/P3 fail-closed source attribution discipline: every diagnostic emission carries structural source-span provenance; not optional. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…tom-reference fix Cursor INLINE BLOCKING /api/reviews/12279 line:29: §3.1 cited `src/v3/compiler/src/tokenize.rs` as "current hand-Rust" for Token carrier — but `tokenize.rs` (without _generated suffix) doesn't exist. Live state has tokenize.dag (live substrate) + tokenize_generated.rs (codegen artifact). Per design-pure-bootstrap.md PB-2 lane: tokenize retire has substantially landed. The reference was an earlier-draft phantom from when Token-was-hand-Rust framing was the assumption. Fix: §3.1 reframed — Token type lives in LIVE src/v3/std/tokenize.dag:65-67 shared taxonomy; tokenizer implementation also live at src/v3/compiler/tokenize.dag (154 lines); codegen artifact at tokenize_generated.rs. tokenize.rs phantom reference removed explicitly. PB-2 substantially landed per design-pure-bootstrap.md; residual scaffold-retirement scope per PB-2 L2.5 PR #3127. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…et fix (compiler.dag → pipeline.dag) Cursor INLINE BLOCKING /api/reviews/12281 line:138: §9 Step 2 referenced generic "compiler.dag" but dsl/gunbc/compiler.dag:24 explicitly directs internal pipeline (Tokenize → Parse → ...) to src/v3/compiler/pipeline.dag, NOT generic compiler.dag. Worker briefs authored against this doc would target the wrong file for pipeline-slot declaration. P2 single-authority violation. Fix: §9 Step 2 row in ALL 4 L2.5 docs (PB-2 / PB-3 / PB-4 / PB-5) updated: - "declared in compiler.dag" → "declared in src/v3/compiler/pipeline.dag (per dsl/gunbc/compiler.dag:24 — internal pipeline lives in pipeline.dag, NOT generic compiler.dag)" - substrate column: "compiler.dag refinement" → "pipeline.dag refinement" - §13 "Step 2 (pipeline-slot in compiler.dag)" → "pipeline-slot in src/v3/compiler/pipeline.dag" Same phantom-citation class as the tokenize.rs phantom (commit 8ae37b4): I cited generic file path without verifying which specific file is authoritative per project structure. Should have grep'd dsl/gunbc/compiler.dag header notes before authoring. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ipt unambiguity
Cursor INLINE BLOCKING /api/reviews/12283 line:181: Q5 said
Step 3b "full parser body .dag migration + parser body deletion
in same PR", but §15 sequence schedules Step 4 parity/deletion
AFTER Step 3b merges. P5 dissolution receipt ambiguous.
If Step 3b lands .dag parser body BEFORE Step 4 deletes Rust
parse() body, Rust + .dag parser bodies coexist temporarily —
paper-shrink-relocation risk per feedback_paper_shrink_variants.
Fix:
1. §9 Step 3b row reframed as "Step 3b/4 COMBINED" — atomic
single PR (full .dag parser body + parity TestClaim +
parse_generated.rs:138 deletion + census shrink). Cannot land
.dag parser body before Rust deletion.
2. §12 Q5 phasing clarified:
- Phase 3a (separate PR): grammar table extension; P5 receipt
= ROADMAP deferral row naming Step 3b/4 as future-receipt
- Phase 3b/4 COMBINED (single PR): atomic substrate substitution
3. §9 + §15 update notes: sequence collapses steps 12-17 into
single dispatch+merge for combined phase
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Codex high-level BLOCKING (sha 140eb6b) had 4 findings: - Findings 3 + 4 already addressed in PR #3138 commits 0159773 + a1607a8 - Findings 1 + 2 addressed in this commit **Finding 1 (Diagnostic kind/record conflated)**: §4.2 ParseDiagnostic was modeled as variants-directly with span + kind-fields mixed. Live Diagnostic at diagnostics.dag:150 uses record-wraps-kind pattern (`{ kind, span, message, correction }`). Need consistent shape. Fix: refactored to record-wraps-kind: - `type ParseDiagnostic { kind: ParseDiagnosticKind, span: SourceSpan }` - `type ParseDiagnosticKind = UnexpectedToken | UnterminatedConstruct | InvalidLiteral | DuplicateRecordFieldLabel | ...` Span lives on ParseDiagnostic record (single source of truth); variant-specific spans (opener_span / prior_span) remain on kind variants where meaningful. **Finding 2 (PB-2 §6 obsolete sibling-lane assumption)**: §6 line 198 said "PB-2 Tokenize | src/v3/std/tokenize.dag (NEW per PB-2 L2.5)" — but tokenize.dag is ALREADY LIVE per design-pure-bootstrap.md §"PB-2 — tokenize retire" (substantially landed). Fix: §6 prereq table row updated to reflect LIVE state. PB-2's residual scope is scaffold-retirement (SG-1a + character-level + codegen-driver per PB-2 L2.5 §1), not carrier authoring. PB-3 consumes the live Token carrier; carrier shape stable across PB-2 residual-retirement timing. Findings 3 + 4 already addressed: - Finding 3 (pipeline.dag target): commit 0159773 - Finding 4 (Step 3b/4 atomic vs sequential): commit a1607a8 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…el metadata" removed
Cursor APPROVE_WITH_COMMENTS line:79: §4.1 said "SurfaceModule
(verified live) carries List<SurfaceItem> + module-level
metadata" — but live parse_surface.dag:29 has ONLY
`{ items: List<SurfaceItem> }`. No metadata fields.
Phantom addition violated INVARIANTS P1 live-state honesty.
Fix: §4.1 reframed to match live carrier exactly. Same
phantom-addition class as tokenize.rs phantom (commit 8ae37b4).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…-variant + diagnostic-table PROPOSED Codex high-level BLOCKING (sha bf4d315) — 2 substantive findings: **Finding 1 (AtomPayload stale)**: §2 + §5 cited infer.rs:10 top-comment "Atom(Identifier { name, resolved })" — but live substrate.dag:87 has 5-variant AtomPayload sum: Literal | UnresolvedIdentifier | ResolvedByStructure | ResolvedByName | TypeParam. infer.rs top-comment is STALE vs live substrate. My doc inherited the drift. Fix: §2 enumeration corrected to all 5 AtomPayload variants per live substrate.dag:87. **Finding 2 (diagnostic-table PROPOSED, not live)**: §2 + §4.1 + §4.3 said "diagnostics.contains(port_id) biconditional" as if live — but Dag at substrate.dag:525 has ONLY { declarations, nodes, ports, clusters }. NO diagnostics field. Diagnostic-table is PROPOSED substrate extension. Fix: §2 fail-closed note flagged PROPOSED — Step 2 PR scope includes `diagnostics: Map<PortId, Diagnostic>` field extension to Dag, OR PB-Substrate prereq adds it before PB-5 dispatch. Same recurring feedback_grep_carrier_field_before_coupling_claim discipline (PR #3126 SurfaceModule analogous case); needed to grep type Dag fields BEFORE claiming the diagnostics field exists. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Codex REQUEST_CHANGES (/api/reviews/12302) — both findings already addressed in PR #3138 commit cfe842b (post-merge fix-forward). Finding 1 (GrammarSpec runtime parallel-authority): Finding 2 (Step 2 signature mismatch with live parse_generated.rs:138): Cross-stage discriminator added at §4.3:
Both fixes landed in PR #3138 (multiple post-merge findings across PB-2/3/4/5 L2.5 docs consolidated). 21 post-merge findings total addressed. Already replied multiple times on this PR per the BLOCKING relay queue. PR #3138 is the canonical fix-forward; this finding is duplicate of /api/reviews/12175 cluster. — sent from zesty-bear-812 (gunbc Director) |
…:Let + SurfaceLiteral span correction
Cursor INLINE BLOCKING line:151: §11 claimed "every Surface
variant carries SourceSpan" but live parse_surface.dag has:
- SurfaceItem::Let { name, type_ann, expr } — no direct span
- SurfaceLiteral = Int(String) | Bool(Bool) | String(String) —
plain-tuple variants with no direct span
Source-span provenance for these cases is via enclosing carrier:
SurfaceLiteral wraps within `Literal { value, span }` at
parse_surface.dag:150. Let-item inherits container span.
INVARIANTS P2/P3 source provenance is structurally guaranteed
via direct-OR-enclosing carrier, but my "every variant"
overstatement obscured this.
Fix: §11 corrected to "most Surface variants carry SourceSpan
directly" + explicit Let + SurfaceLiteral exceptions noted +
Step 2 PR scope audits whether exceptions are structural-honest
(enclosing-carrier-provides-span) OR require substrate extension.
Same recurring overstatement class as earlier "every SurfaceItem
maps 1:1 to Declaration" (commit 61e2b67) — need to grep live
substrate variant fields BEFORE claiming uniform shape.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Cursor INLINE BLOCKING line:241 — finding is INCORRECT after verification. Cursor's claim: "git ls-tree origin/main returned no blobs for those paths" (referring to Verified live state ( Both files ARE on origin/main (merged via PR #3077 at 2026-05-15T00:21:19Z + PR #3085 at 00:21:29Z). The cross-stage diagnostic pattern IS a repo authority — §16 primary-authority cite is correct. Reviewer-side context appears stale (possibly comparing against an older base or before the 2026-05-15 merge of PR #3077/#3085). Same reviewer-stale-context class as earlier No fix-forward needed; cite is correct. — sent from zesty-bear-812 (gunbc Director) |
|
Codex high-level BLOCKING (sha 41ec0a7) — both findings already addressed. Finding 1 (Surface provenance audit against live carriers) — addressed in PR #3138 commit cd6e8d1 (just landed). §11 corrected from "every Surface variant carries SourceSpan" to "most Surface variants carry SourceSpan directly; SurfaceItem::Let + SurfaceLiteral variants lack direct span (provenance via enclosing Literal carrier at parse_surface.dag:150 OR Let inherits container span); Step 2 PR scope audits whether exceptions are structural-honest OR require substrate extension". Finding 2 (Cross-stage pattern from PR-number lore vs repo authority) — finding INCORRECT after verification.
Both L2.5 docs ARE on origin/main (merged via PR #3077 + #3085 at 2026-05-15T00:21Z). The cross-stage pattern IS a live repo authority, not just PR-number lore. Reviewer-side context appears stale (comparing against pre-merge base). Same reviewer-stale-context class as earlier — sent from zesty-bear-812 (gunbc Director) |
…ncept, not carrier Earlier draft (now-merged PR #3126) framed `GrammarSpec` as a second declared `.dag` input type alongside `List<Token>`. Verified via grep that no `type GrammarSpec` exists anywhere under src/v3/ or dsl/ — the repo carries only `parse_tables.dag`'s 6 SG-2c table-families. Per cursor 2026-05-14T23:30:04Z inline finding, this violates INVARIANTS P2 (the Step-2 signature names a carrier the substrate doesn't declare). Reframed §3 (and downstream mentions in §3.2, §3 preamble line:33, §4.2 codex-correction recap line:165, §5.1 line:181, §12 Q6 line:344) so that: - Parse has ONE input at the API boundary: `List<Token>`. - "GrammarSpec" is a concept-level grouping for the 6 compile-time table-families in `parse_tables.dag`, not a substrate carrier and not a runtime parameter. - Step-2 signature stays `fn parse(tokens: List<Token>) -> Result<SurfaceModule, ParseDiagnostic>` per cfe842b (already applied in #3126); these edits remove the lingering "two input types" framing that contradicted that signature. Per Decision 3.B (b) compile-time parser tables: substrate authority is parse_tables.dag (6 table-families) consumed via direct table lookups inside the parser body — no runtime grammar value, no `GrammarSpec` carrier needed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ng resolved by PR #3077 merge Cursor inline BLOCKING at docs/design-parse-stage-l25-model.md:119 (sha at merge time of PR #3126) flagged a real internal contradiction: - §6 (lines 191, 207, 308) claimed "Step 2 (pipeline-slot declaration) is unblocked" - §7.2 (line 227) claimed "PR #3077 §12 Q7 must ratify before any Step 2 worker brief authoring" A worker reading the doc could land Step 2 (pipeline boundary) before the diagnostic carrier's P2/P3 failure shape was fixed. Resolution: PR #3077 (PB-4 lower L2.5) merged at 2026-05-15T00:21:19Z, carrying the §12 Q7 ratification of the Decision 2.B per-stage diagnostic extension path. The gate IS now satisfied at HEAD, so the resolution is fact-update (annotate Q7 as DONE with the merge timestamp) rather than retracting either §6 or §7.2. Edits: - §15 step 4: annotated "DONE 2026-05-15T00:21:19Z when PR #3077 merged" and added the explicit "Step 2 is now genuinely unblocked, not just procedurally next" framing so workers reading the sequence don't bypass the gate. - §7.2 line 227: rewritten from "Q7 must ratify before Step 2 brief authoring" (future tense, the contradiction surface) to "Gate satisfied 2026-05-15T00:21:19Z when PR #3077 merged; Step 2 worker brief authoring is unblocked at HEAD per §15 step 4." Cites the cursor finding as the resolution path. §6 unblocking statements stay as-is — they were correct at HEAD; the contradiction lived in §7.2's pre-merge framing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…tep 2 unblocking claim Codex BLOCKING finding 2 (sha 16d21f4, 216s thinking): the Q7 dependency was recorded in §7.2/§15 but not in the other Step-2-unblocking sites at §6 lines 191, 207, 308 — risking a worker reading "Step 2 unblocked" without also reading the Q7 prerequisite. Codex framing: "make Q7 a hard precondition wherever Step 2 is called unblocked, or split Step 2 into pre-Q7 and post-Q7 scopes with separate receipts." Chose the first option since PR #3077 has already merged (2026-05-15T00:21:19Z) and splitting into pre/post-Q7 scopes is no longer load-bearing. Annotated all three §6 sites: - Line 191 (Implication for PB-3 migration): cites gate + merge timestamp + explicit "must NOT be brief-authored before that merge timestamp." - Line 207 (Critical observation): cites the Step 2 gate as PR #3077 §12 Q7 + merge timestamp + P3 failure-shape consequence if violated. - Line 308 (Director-recommend phase list): cites gate + §7.2/§15 step 4 cross-refs + merge timestamp. Codex BLOCKING finding 1 (GrammarSpec carrier non-existence) verified already resolved at HEAD via commit c97dc15 — every GrammarSpec mention now explicitly marks it as a concept-not-carrier; Step 2 signature is `fn parse(tokens: List<Token>) -> Result<SurfaceModule, ParseDiagnostic>` with no GrammarSpec parameter. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…icity + Q1 ratification-pending status openai-pro REQUEST_CHANGES on PR #3126 sha 16d21f4 flagged three findings. Findings 1 + 2 (signature vs realization mismatch under LAYER MODEL + P2/P3 boundary discipline) were already resolved at HEAD by earlier fix-forward commits — Step 2 signature is now `fn parse(tokens: List<Token>) -> Result<SurfaceModule, ParseDiagnostic>` matching live `parse_generated.rs:138` with no GrammarSpec parameter and no diagnostics-coupled SurfaceModule extension (§4.3 Result-sum disposition). Finding 6 (TRACKED vs UNTRACKED DEBT — Step 3b/4 same-PR vs two-PR): §9 had both a "Step 3b/4 COMBINED" row (line 250) and a leftover separate "Step 4: Parity test" row (line 251) — internally contradictory. §15 also still sequenced Steps 3b + 4 as four separate authoring/dispatch/ratify beats (steps 12-17), contradicting §12 Q5's "same PR" decision and the explicit "Update to §15" note at §12 line 325. Resolution: collapsed §9 to one COMBINED row absorbing the parity-TestClaim mechanics + P5 dissolution receipt from the deleted Step 4 row; collapsed §15 steps 12-17 into single COMBINED authoring + dispatch + ratify (steps 12-14). Added explicit `feedback_paper_shrink_variants` reasoning in both sections. Finding 2.5 (PM intent — substrate-capability bundled vs separate): §12 Q1 line 288 said "Director-recommend: (b) bundled" while §13 line 340 listed substrate-capability as a non-goal of PB-3 and §15 step 11 had "WAIT for substrate-capability landing" — three sections, two different execution paths. Resolution: annotated Q1 as "PENDING operator/PM ratification" with explicit default-execution clause: until operator ratifies, the doc treats substrate-capability as path (a) separate lane (matching §13 + §15 + §9 row). If/when ratified to (b), §13 drops the non-goal and §15 step 11 collapses into the COMBINED Step 3b/4 brief. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Status reply for the openai-pro review at sha 16d21f4 (review id 12337, BLOCKING with four findings). PR #3126 is already merged; the substantive findings were carried into fix-forward branch
No further fixes needed against this review id on this merged PR; the parse L2.5 doc at PR #3138 HEAD reflects all four. Dashboard please stop re-relaying review id 12337. — sent from zesty-bear-812 |
… single enumerated authority Codex caught me copying the prose summary at parse_tables.dag:23-29 (which enumerates only SG-2c-numbered families) instead of grepping the live `^type [A-Z]` declarations. Result: SoftKeywordIdentRow (line 334) was missing from §3.2 / §5.1 / §6 / §12 because it lacks an SG-2c-N number in the prose summary. Per `feedback_parallel_representation_debt`: structural fix is to stop hand-enumerating in the doc — cite parse_tables.dag itself as the single enumerated authority and use `type`-declaration line-anchors for the worked example, not a hand-maintained count. Edits: - §3.2 §"Live substrate authority": replaced the SG-2c-numbered bullet list with `type`-declaration line-anchor enumeration including SoftKeywordIdentRow at parse_tables.dag:334 + the supporting enum BinaryOpLevel at line 133. Added codex-finding callout explaining the miss + the discipline shift. - §3 preamble line:33, §3.2 line:45 callout, §3.2 line:57 framing, §3.2 §"Substrate authority" line:71, §5.1 line:171-180, §12 Q2 line:298, §12 Q6 line:334: all hardcoded "6 table-families" counts dropped; doc now points readers to §3.2 enumeration / `parse_tables.dag` directly. - §5.1 sub-enumeration list (the parallel 6-item list at lines 173-178) deleted; replaced with redirect to §3.2 + restated 3a-vs-3b/4 scope split. Code-level check before commit: `grep -nE '^type [A-Z]' src/v3/compiler/parse_tables.dag` returns 7 types: BinaryOpLevel (133), BinaryOpRow (167), TopLevelItemKwRow (289), SoftKeywordIdentRow (334), BracketRow (385), PrimaryPrefixRow (449), PrimaryAtomRow (486). Doc enumeration matches. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
|
Status reply for the cursor INLINE BLOCKING at docs/design-parse-stage-l25-model.md:65 (sha at merge time of PR #3126). Already addressed by fix-forward commit 3eeee0c on branch
No further fixes needed against this inline on the merged PR; the parse L2.5 at PR #3138 HEAD reflects the enumerated authority. Dashboard please stop re-relaying this inline. — sent from zesty-bear-812 |
…ratification (#3127) * docs(r3): PB-2 tokenize pipeline-stage L2.5 domain model — DRAFT for ratification Director-tier L2.5 model for PB-2 tokenize per operator 2026-05-14 ratification (Decision 1.A scoping = Option A). PB-2 is the FURTHEST-ALONG pipeline stage — substrate authority already lives in `.dag`: - src/v3/std/tokenize.dag (Token + TokenKind taxonomy; LIVE 143 lines) - src/v3/compiler/tokenize.dag (tokenizer implementation; LIVE 154 lines) - src/v3/compiler/src/tokenize_generated.rs (AUTO-GENERATED; 362 lines) This is the END STATE that all other pipeline-stage migrations target. PB-2 L2.5 is correspondingly lighter — mostly verification + residual hand-Rust retirement, NOT new substrate authoring. Distinct §9 4-step framing: - Step 3 = VERIFY substrate completeness (audit per feedback_paper_shrink_variants) - Step 4 = HANDOFF/RETIRE residual hand-Rust scaffolding (coordinates with PB-Bootstrap-Process lane for codegen-driver retirement) Captures audit dimensions explicitly: - scanner-class definitions = declarative byte-pattern membership - recognition tables = closed-axis enums - state machine = structural transitions - no V2 `pub mod tokenize` absorption check §12 Q1: codegen-driver retirement scope — Director-recommend PB-Bootstrap-Process handles all codegen-driver retirement cross-cuttingly (not per-stage paper-shrink risk). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): §12.6 citation fix — tokenize is PB-2 lane scope per design-pure-bootstrap-zero.md Per cursor PR #3085 finding: §12.6 explicitly tables only 4 pipeline-stage migrations (emit→lower→infer→parse); tokenize is per design-pure-bootstrap-zero.md PB-2 lane. Same fix as PR #3085 commit 89fbd7a applied here. INVARIANTS P1 — documentation must not overstate authority cites. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): preemptive fix for PR #3126 codex BLOCKING propagation — PB-2 live state honesty Same class as codex INLINE BLOCKING #3126 finding 1 (live state honesty for diagnostic coupling) applied preemptively to PB-2 tokenize L2.5. PB-2 §4.3 had "diagnostics coupled INTO List<Token>" framing which would overstate the live carrier shape (bare List<Token> has no diagnostic field; tokenize_generated.rs:96 today returns Result<Vec<Token>, Diagnostic>). Fix: §4.3 reframed with PROPOSED substrate extension explicit — new `TokenizedSource { tokens, diagnostics }` wrapper carrier as the typed-state output. Step 2 brief includes wrapper authoring in pipeline-slot PR scope. Same discipline as PR #3126 commit bdff8c5. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3077 — fix PB-2 lane citation (design-pure-bootstrap.md not -zero.md) Per cursor APPROVE_WITH_COMMENTS /api/reviews/12087: PB-2 lane is defined in docs/design-pure-bootstrap.md §"PB-2 — tokenize retire" (line ~134), NOT docs/design-pure-bootstrap-zero.md. The -zero.md doc has Subsumed-lanes list with PB-1/PB-4/PB-5/PB-6 but NOT PB-2. Propagated fix applies same cite-error correction as PR #3066 §1.8 discipline: cite the actual doc, not an adjacent doc with similar name. INVARIANTS P2 single-authority-citation. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): fix cursor PR #3127 BLOCKING contradictions + add §12 Q6 Cursor APPROVE_WITH_COMMENTS (/api/reviews/12093) caught two substantive contradictions I introduced when adding TokenizedSource in commit 2b9756b: 1. §4.3 vs §9 Step 2 signature mismatch — §4.3 said `-> TokenizedSource` but §9 Step 2 row still said `-> List<Token>`. Same `feedback_discipline_change_audit_all_contract_mentions` issue that's recurred 4x this session. 2. §4.3 referenced "§12 Q-new" but §12 only had Q1-Q5; broken anchor. Fix: 1. §9 Step 2 row updated: signature `-> TokenizedSource` with wrapper carrier shape `{ tokens, diagnostics }` per §4.3 2. §4.3 anchor updated: "§12 Q6" (resolved) 3. Added §12 Q6: TokenizedSource carrier shape ratification — (a) wrapper record vs (b) per-Token diagnostic coupling; Director-recommend (a) for PB-3 SurfaceModule parallelism 4. §14 + §15 + §16 Q-list refs updated to Q1-Q6 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): fix codex BLOCKING PR #3127 — Token shape + Q4 audit boundary Codex REQUEST_CHANGES (sha b881de2) with 2 substantive findings: 1. §4.1 Token shape claim "optional lexeme: String" — wrong per live substrate at src/v3/std/tokenize.dag:65-67. Live Token has 2 fields only (kind + span); lexeme-content lives ON the TokenKind variants (Ident(String) / IntLit(String) / etc.). Fix: corrected §4.1 to reflect live carrier shape; payloads on TokenKind variants noted explicitly. 2. §12 Q4 substrate-completeness audit scoped only to tokenize_generated.rs — missed the regen_tokenize codegen- driver boundary. If regen_tokenize carries scanner-logic decisions (rather than mechanical template-rendering of substrate facts), the substrate isn't complete — the driver IS hand-Rust scanner logic in disguise. Fix: Q4 audit extended with (d) regen_tokenize codegen- driver logic audit + (e) ROADMAP.md deferral row option per feedback_paper_shrink_variants P5 receipt discipline. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): fix codex BLOCKING PR #3127 — TokenizeDiagnostic PROPOSED + scaffold disclosure Codex REQUEST_CHANGES (sha b881de2, full body) caught 2 substantive overstatements: 1. §2 line 46 claimed "tokenize failures produce typed TokenizeDiagnostic variants" — but live tokenize_generated.rs:96 returns generic `Result<Vec<Token>, Diagnostic>` with `Diagnostic::TokenizerError { message, span, correction }`. Typed TokenizeDiagnostic is a PROPOSED extension, not live state. Fix: §2 reframed with live state explicit + TokenizeDiagnostic marked PROPOSED per PR #3077 §12 Q7 ratification path. 2. §1 line 22 + §6 + §9 Step 2 line 198 framed PB-2 as "mostly verification" — but live tokenize.dag:16-30+ has TWO explicit tracked scaffold zones: - SG-1a: regen_tokenize parses raw source text for dag_keyword_set / dag_operators (ValueBody::Unparsed) - Character-level under-consumption: StringEscapeSpec / LocalPunctSpec.pattern / string_literal_delimiter as opaque Strings; hidden Rust character predicates (byte.is_ascii_digit etc.) at tokenize_generated.rs:15-22 leaking through codegen Residual hand-Rust is NOT just the codegen artifact — it includes (a) regen_tokenize logic, (b) SG-1a raw-text-extractor scaffold, (c) character-predicate scaffold leaking through codegen. Fix: §1 + §6 + §9 Step 2 reframed honestly. PB-2 is "FURTHER ALONG but not complete"; Step 4 carries scaffold-retirement scope, not just codegen-artifact retirement. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3127 BLOCKING (review id 12370) — drop TokenizedSource + cite concrete P5 receipts Codex review id 12370 on sha d15e1f2 raised two load-bearing planning-shape findings. Both addressed; this commit ports the same edits already living on fix-forward branch docs/director-l25-postmerge-cleanups (PR #3138 commit 6adb992) onto PR #3127's branch directly so codex BLOCKING resolves on this PR's own HEAD rather than waiting on PR #3138 merge. Finding 1 — parallel boundary carriers (INVARIANTS P2 / Practices 3+5): §4.3 + §9 Step 2 + §12 Q6 named `TokenizedSource { tokens, diagnostics }` as the output, while §2/§7.2/§7.3 named `List<Token>`. Same misclassification removed from the parse L2.5 (PR #3138 §4.3): tokenize sits in the fail-fast output domain alongside PB-3 parse + PB-6 emit (a partial token list with a corrupt token in the middle is not a valid downstream input for parse), so the failure couples via `Result`, not into the structural carrier. Resolution: - §4.3 rewritten to ratify `Result<List<Token>, TokenizeDiagnostic>` — the live `tokenize_generated.rs:96` shape — with no `TokenizedSource` extension. - §9 Step 2 row signature updated to match; explicit "single canonical boundary carrier: List<Token> on the Ok branch" framing. - §12 Q6 resolved REJECTED in-doc (no operator ratification needed; disposition follows from the cross-stage discriminator load-bearing in PR #3138 parse L2.5). - §16 memory-disciplines bullets rewritten parallel to PR #3138 parse §16: Result-sum, no diagnostics field on `List<Token>`. - §14 "Surfaces awaiting" trimmed Q6 from the operator-ratification list. Finding 2 — soft deferral of `regen_tokenize` retirement (INVARIANTS P5): deferral previously named "PB-Bootstrap-Process lane scope" without a concrete ROADMAP.md row. Updated §9 Step 2 + Step 4 rows to cite the named receipts: - `docs/design-pure-bootstrap-zero.md:116` (PB-Bootstrap-Process lane: author bootstrap.dag + generated trampoline; sized M). - `docs/design-pure-bootstrap-zero.md:118-123` (N=0 runtime verification gates). - ROADMAP.md:467 (Character-level under-consumption in tokenize + syntax authorities — phase-2 char-class retype owns the codegen-driver path). - ROADMAP.md:416 (Class 5 Gap 3 — top-level `ValueBody` boundary; gating substrate-capability for the phase-2 retype). - ROADMAP.md:53 (T-PB-A — non-test census → 0 floor). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3138 BLOCKING (sha f08b952) Finding 1 — bind to live CharClass authority Porting the same fix that landed on PR #3138 commit 367fdc2 onto PR #3127's own branch so codex BLOCKING resolves on this PR's HEAD directly. Codex Finding 1: §4.2 TokenizeDiagnostic + §5.1/§5.2 headings used `ScannerCharClass` / `ScannerClassRef` — names that exist only in the generated Rust enum spelling, not as a .dag substrate declaration. Live authority is `dsl/std/unicode.dag:62` `type CharClass = Whitespace | Digit | IdentStart | IdentContinue`, consumed at `src/v3/compiler/tokenize.dag:103`. Resolution: - §4.2: `expected_class: ScannerClassRef` → `expected_class: CharClass`; dropped the `type ScannerClassRef = ScannerCharClass` alias; added codex-finding callout citing the substrate authority. - §5.1: heading + intro now cite `dsl/std/unicode.dag:62` directly. - §5.2: heading "CharClass → token-recognition state machine". Same failure-mode as `feedback_grep_substrate_before_naming_ratification`: naming a substrate carrier without grep-verifying against live .dag. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3138 INLINE BLOCKING line:188 — §7.3 chain Ok-branch annotation Same edit as PR #3138 commit a8c0ff7 ported to this PR's branch. §7.3 cross-stage chain now annotates Ok-branch propagation + Err-branch fail-fast termination explicitly, eliminating the apparent contradiction between §4.3 (Result-sum) and §7.3 (List<Token> in the chain). They were already consistent — Ok-branch payload flows forward; Err terminates — but the annotation makes it self-evident at §7.3. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): openai-pro PR #3127 BLOCKING (sha d15e1f2) — character-level scaffold dissolution trigger Same edit as PR #3138 commit 5a93d93 ported to this PR's branch. §1 item 2 character-level under-consumption scaffold now carries the same SG-1a-shape dissolution trigger structure: substrate-consumption condition (a) + codegen-driver condition (b) + same-PR delete receipt, with cross-refs to §9 Step 4 gating prereqs already cited. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3127 APPROVE_WITH_COMMENTS — §14 + §15 Q6-already-rejected sweep Same edit as PR #3138 commit 887c696 ported to this PR's branch. §14 acceptance criterion 11 + §15 step 1 now say "Q1-Q5" with explicit Q6-rejected crossrefs, aligning with §12 Q6 + §14 "Surfaces awaiting" which already said "Q1-Q5 only". Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ctions (#3138) * docs(r3): PB-2 tokenize pipeline-stage L2.5 domain model — DRAFT for ratification Director-tier L2.5 model for PB-2 tokenize per operator 2026-05-14 ratification (Decision 1.A scoping = Option A). PB-2 is the FURTHEST-ALONG pipeline stage — substrate authority already lives in `.dag`: - src/v3/std/tokenize.dag (Token + TokenKind taxonomy; LIVE 143 lines) - src/v3/compiler/tokenize.dag (tokenizer implementation; LIVE 154 lines) - src/v3/compiler/src/tokenize_generated.rs (AUTO-GENERATED; 362 lines) This is the END STATE that all other pipeline-stage migrations target. PB-2 L2.5 is correspondingly lighter — mostly verification + residual hand-Rust retirement, NOT new substrate authoring. Distinct §9 4-step framing: - Step 3 = VERIFY substrate completeness (audit per feedback_paper_shrink_variants) - Step 4 = HANDOFF/RETIRE residual hand-Rust scaffolding (coordinates with PB-Bootstrap-Process lane for codegen-driver retirement) Captures audit dimensions explicitly: - scanner-class definitions = declarative byte-pattern membership - recognition tables = closed-axis enums - state machine = structural transitions - no V2 `pub mod tokenize` absorption check §12 Q1: codegen-driver retirement scope — Director-recommend PB-Bootstrap-Process handles all codegen-driver retirement cross-cuttingly (not per-stage paper-shrink risk). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): §12.6 citation fix — tokenize is PB-2 lane scope per design-pure-bootstrap-zero.md Per cursor PR #3085 finding: §12.6 explicitly tables only 4 pipeline-stage migrations (emit→lower→infer→parse); tokenize is per design-pure-bootstrap-zero.md PB-2 lane. Same fix as PR #3085 commit 89fbd7a applied here. INVARIANTS P1 — documentation must not overstate authority cites. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): preemptive fix for PR #3126 codex BLOCKING propagation — PB-2 live state honesty Same class as codex INLINE BLOCKING #3126 finding 1 (live state honesty for diagnostic coupling) applied preemptively to PB-2 tokenize L2.5. PB-2 §4.3 had "diagnostics coupled INTO List<Token>" framing which would overstate the live carrier shape (bare List<Token> has no diagnostic field; tokenize_generated.rs:96 today returns Result<Vec<Token>, Diagnostic>). Fix: §4.3 reframed with PROPOSED substrate extension explicit — new `TokenizedSource { tokens, diagnostics }` wrapper carrier as the typed-state output. Step 2 brief includes wrapper authoring in pipeline-slot PR scope. Same discipline as PR #3126 commit bdff8c5. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3077 — fix PB-2 lane citation (design-pure-bootstrap.md not -zero.md) Per cursor APPROVE_WITH_COMMENTS /api/reviews/12087: PB-2 lane is defined in docs/design-pure-bootstrap.md §"PB-2 — tokenize retire" (line ~134), NOT docs/design-pure-bootstrap-zero.md. The -zero.md doc has Subsumed-lanes list with PB-1/PB-4/PB-5/PB-6 but NOT PB-2. Propagated fix applies same cite-error correction as PR #3066 §1.8 discipline: cite the actual doc, not an adjacent doc with similar name. INVARIANTS P2 single-authority-citation. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): fix cursor PR #3127 BLOCKING contradictions + add §12 Q6 Cursor APPROVE_WITH_COMMENTS (/api/reviews/12093) caught two substantive contradictions I introduced when adding TokenizedSource in commit 2b9756b: 1. §4.3 vs §9 Step 2 signature mismatch — §4.3 said `-> TokenizedSource` but §9 Step 2 row still said `-> List<Token>`. Same `feedback_discipline_change_audit_all_contract_mentions` issue that's recurred 4x this session. 2. §4.3 referenced "§12 Q-new" but §12 only had Q1-Q5; broken anchor. Fix: 1. §9 Step 2 row updated: signature `-> TokenizedSource` with wrapper carrier shape `{ tokens, diagnostics }` per §4.3 2. §4.3 anchor updated: "§12 Q6" (resolved) 3. Added §12 Q6: TokenizedSource carrier shape ratification — (a) wrapper record vs (b) per-Token diagnostic coupling; Director-recommend (a) for PB-3 SurfaceModule parallelism 4. §14 + §15 + §16 Q-list refs updated to Q1-Q6 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): fix codex BLOCKING PR #3127 — Token shape + Q4 audit boundary Codex REQUEST_CHANGES (sha b881de2) with 2 substantive findings: 1. §4.1 Token shape claim "optional lexeme: String" — wrong per live substrate at src/v3/std/tokenize.dag:65-67. Live Token has 2 fields only (kind + span); lexeme-content lives ON the TokenKind variants (Ident(String) / IntLit(String) / etc.). Fix: corrected §4.1 to reflect live carrier shape; payloads on TokenKind variants noted explicitly. 2. §12 Q4 substrate-completeness audit scoped only to tokenize_generated.rs — missed the regen_tokenize codegen- driver boundary. If regen_tokenize carries scanner-logic decisions (rather than mechanical template-rendering of substrate facts), the substrate isn't complete — the driver IS hand-Rust scanner logic in disguise. Fix: Q4 audit extended with (d) regen_tokenize codegen- driver logic audit + (e) ROADMAP.md deferral row option per feedback_paper_shrink_variants P5 receipt discipline. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): fix codex BLOCKING PR #3127 — TokenizeDiagnostic PROPOSED + scaffold disclosure Codex REQUEST_CHANGES (sha b881de2, full body) caught 2 substantive overstatements: 1. §2 line 46 claimed "tokenize failures produce typed TokenizeDiagnostic variants" — but live tokenize_generated.rs:96 returns generic `Result<Vec<Token>, Diagnostic>` with `Diagnostic::TokenizerError { message, span, correction }`. Typed TokenizeDiagnostic is a PROPOSED extension, not live state. Fix: §2 reframed with live state explicit + TokenizeDiagnostic marked PROPOSED per PR #3077 §12 Q7 ratification path. 2. §1 line 22 + §6 + §9 Step 2 line 198 framed PB-2 as "mostly verification" — but live tokenize.dag:16-30+ has TWO explicit tracked scaffold zones: - SG-1a: regen_tokenize parses raw source text for dag_keyword_set / dag_operators (ValueBody::Unparsed) - Character-level under-consumption: StringEscapeSpec / LocalPunctSpec.pattern / string_literal_delimiter as opaque Strings; hidden Rust character predicates (byte.is_ascii_digit etc.) at tokenize_generated.rs:15-22 leaking through codegen Residual hand-Rust is NOT just the codegen artifact — it includes (a) regen_tokenize logic, (b) SG-1a raw-text-extractor scaffold, (c) character-predicate scaffold leaking through codegen. Fix: §1 + §6 + §9 Step 2 reframed honestly. PB-2 is "FURTHER ALONG but not complete"; Step 4 carries scaffold-retirement scope, not just codegen-artifact retirement. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): post-merge fix-forward — §16 + §9 Step 2 internal contradictions Two post-merge doc-internal contradictions caught by reviewers after operator merged PR #3077 / #3126 / #3085 at 2026-05-15T00:21Z. **PR #3077 PB-4 lower §16 fix**: §16 "Memory disciplines applied" bullet said "diagnostics coupled INTO PreInferDag via biconditional" — but §4.3 (per openai-pro DiagnosticAnchor fix commit b812db9) constrains biconditional to PortAnchor-only. Other anchor kinds (DeclarationAnchor / RecordFieldAnchor / SurfaceFormAnchor) couple without port-state. Fix: §16 bullet honors §4.3 anchor-typed framing. **PR #3126 PB-3 parse §9 Step 2 fix**: §9 Step 2 row described diagnostics as "coupled INTO SurfaceModule" as if live — §4.3 correctly marks it PROPOSED. Same feedback_discipline_change_audit_all_contract_mentions pattern that's recurred this session. Fix: §9 Step 2 row clarified — "PROPOSED extension per §4.3"; Step 2 PR scope includes authoring the diagnostics field extension, NOT a live coupling. Per feedback_discipline_change_audit_all_contract_mentions: when a substantive fix changes a discipline framing, audit ALL sections (framing + contract + handoff). Post-merge audit surfaced these residual contradictions. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): post-merge fix-forward — PR #3126 codex BLOCKING (GrammarSpec parallel-authority + fail-closed weakening) Codex REQUEST_CHANGES on already-merged PR #3126 (/api/reviews/12175): 2 substantive findings on the post-merge doc. **Finding 1 (P2 violation — GrammarSpec parallel authority)**: §3.2 says GrammarSpec is compile-time-only, NOT runtime- interpreted (per Decision 3.B (b) operator override). But the proposed stage contract still took `grammar: GrammarSpec` as runtime input. Creates two authorities (compiled parser tables + runtime GrammarSpec value). Fix: §4.3 signature reframed to `fn parse(tokens: List<Token>) -> Result<SurfaceModule, ParseDiagnostic>` — NO runtime GrammarSpec input. Compile-time generated parser tables consumed via internal dispatch. Step 2 + Step 4 rows updated. **Finding 2 (P3 + Practices 1/2 — fail-closed weakening)**: Live parser at parse_generated.rs:138 returns `Result<SurfaceModule, Diagnostic>` (fail-closed; aborts on first error). Earlier draft proposed `SurfaceModule` with embedded diagnostics — would let partial-parse states be constructible + let downstream observe "success" output after parse failure. Violation of fail-closed discipline. Fix: signature preserves Result-sum (matches live + emit's pattern). Distinguished cross-stage: - Result-sum (parse + emit): fail-fast output domain - Typed-state-with-coupled-diagnostics (lower + infer): structural output domain where partial-failure IS valid intermediate Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 post-merge APPROVE_WITH_COMMENTS — §4.1 + §16 fail-closed honesty Cursor caught 2 more post-merge contradictions on PR #3126: 1. §4.1 line 81 "construction-time invariant" talks about "ParseDiagnostic in the diagnostic stream" tied to SurfaceModule path — but §5.2 + live parse_generated.rs:138 use Result<SurfaceModule, Diagnostic>. §4.1 reads as claim about today's plumbing. Fix: §4.1 reframed — live boundary explicit (Result-sum); construction-time invariant scoped to Ok-arm SurfaceModule + Err-arm ParseDiagnostic, no partial-parse with embedded diagnostics. 2. §16 line 397 cites C-8 as "ParseDiagnostic coupled INTO SurfaceModule" without qualifier — but §4.3 (post codex REQUEST_CHANGES fix) constrains to Result-sum. Fix: §16 bullet honors §4.3 Result-sum framing; cross-stage discriminator named. Same recurring feedback_discipline_change_audit_all_contract_mentions pattern — substantive fix to §4.3 + §9 Step 2 left §4.1 + §16 inconsistent. Post-merge audit catches. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3085 INLINE BLOCKING — TypeConnective extension stop-signal Cursor INLINE BLOCKING caught §3.2 line 66 "rules extend automatically" weakens substrate-extension stop-signal. Thesis discipline: a 7th TypeConnective variant requires explicit C1 audit + named infer-rule receipt. Fix: §3.2 reframed. New TypeConnective variants do NOT extend automatically; require explicit C1 substrate-extension audit + named infer-rule receipt for the new variant's structural inference behavior. Per-variant structural facts means new variants need new per-variant facts, NOT silent inheritance. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3085 INLINE BLOCKING — AlgebraAxis + InferDiagnostic Practice 4 classification Cursor INLINE BLOCKING /api/reviews/12218 (line:112): proposed substrate coproducts (AlgebraAxis + InferDiagnostic) lack 🟢/🟡/🔴 classification + ledger/trigger per modeling-discipline Practice 4 (Coproduct dissolution). Fix: added 🟡 SCAFFOLD classification + named dissolution trigger for both: AlgebraAxis 🟡 SCAFFOLD: - Trigger: Step 2 brief enumerates full algebra-axiom set against infer.rs check sites + verifies coverage parity with live verification.dag:146 AlgebraicLawKind 3-variant subset → promote to 🟢 TERMINAL. InferDiagnostic 🟡 SCAFFOLD: - Trigger: Step 2 brief enumerates full variant set against parse_generated.rs / lower.rs / infer.rs diagnostic emission sites → promote to 🟢 TERMINAL. - Anti-bridge per Q6.5: does NOT collapse into CompilerDiagnosticKind without substrate-extension ratification per PR #3077 §12 Q7. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3077 INLINE BLOCKING — §5.1 SurfaceItem allocation correction Cursor INLINE BLOCKING /api/reviews/12251 line:130: §5.1 said "every SurfaceItem variant maps 1:1 to a Declaration placeholder" but live lower.rs:2950-2958 explicitly skips Let/Module/Import in collect_symbols. Verified via Read of lower.rs:2956-2958: SurfaceItem::Let { .. } => continue, SurfaceItem::Module { .. } => continue, SurfaceItem::Import { .. } => continue, Fix: §5.1 reframed — DeclarationAllocating variants (Fn / FnExternalBody / Data / TypeAtom / TypeRecord) map to placeholders; NonDeclarationAllocating variants (Let / Module / Import) skip allocation per live lower.rs behavior. Let-bodies lower to Bind expressions in Pass 2; Module/Import are parsed-facts preserved but un-declared. Earlier "every SurfaceItem variant" framing overstated; would have steered Step 2/3 worker into wrong allocation contract. Per INVARIANTS P1/P2 live-state honesty + facts-flow-forward. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3077 INLINE BLOCKING — ElaborationSpec scope broadened Cursor INLINE BLOCKING line:33: ElaborationSpec was defined only as Surface→Behavior recipe mapping, but lower constructs Declarations / TypeConnectives / BranchPatterns / Bindings as well. Non-Behavior lowering decisions outside declared authority violates THESIS substrate ownership + INVARIANTS P2. Fix: §3.2 ElaborationSpec scope broadened to ALL lowering decisions: 1. SurfaceItem → Declaration recipes (Fn / Data / Type variants + Let/Module/Import skip-allocation per §5.1) 2. SurfaceType → TypeConnective recipes (Atom / Arrow / Compose / Disj construction) 3. SurfaceExpr → Behavior recipes (Value / Transform / Branch / Loop / Bind construction) 4. SurfacePattern → BranchPattern recipes (ResolvedVariant / UnresolvedVariant / record-pattern construction) 5. Binding-site rules (Bind params + result_port construction) ElaborationSpec is single-authority across ALL axes; no axis lives in implementation-tier hand-Rust. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 APPROVE_WITH_COMMENTS — §7.1 ordering vs independence clarification Cursor APPROVE_WITH_COMMENTS /api/reviews/12265 line 197: §7.1 mixed two claims: - "parse migrates AFTER tokenize substrate-side stable" (ordering) - "PB-3 parse migration is independent of PB-2 tokenize migration status" (independence) Read as contradictory by reviewers. Need one coherent story. Fix: §7.1 reframed with two distinct axes explicit: 1. Substrate-stability ordering (SELF_HOSTING.md §2 bottom-up): tokenize Token carrier shape must be stable BEFORE parse migrates. Already true at HEAD (tokenize.dag:65-67 declares live carrier). ✓ 2. Migration-timing independence (parallel-dispatch axis): PB-3 parse migration ships in parallel with PB-2 residual-retirement work (SG-1a + character-level scaffold + codegen-driver retirement per PB-2 L2.5 §1). What parse needs is the stable Token CARRIER; PB-2's migration is about retiring residual hand-Rust, not changing the carrier. Both claims coherent on the axis split; not contradictory. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 INLINE BLOCKING — ParseDiagnostic SourceSpan structural requirement Cursor INLINE BLOCKING /api/reviews/12277 line:65: ParseDiagnostic variants like UnexpectedToken lacked SourceSpan field; List<ParseDiagnostic> cannot satisfy fail-closed source attribution structurally without span on every variant. INVARIANTS P2/P3 violation. Fix: every ParseDiagnostic variant now carries SourceSpan structurally: - UnexpectedToken: added span: SourceSpan - UnterminatedConstruct: opener_span: SourceSpan (already present) - InvalidLiteral: added span: SourceSpan - DuplicateRecordFieldLabel: added span: SourceSpan (current site) + prior_span: SourceSpan (prior site; both required) Per INVARIANTS P2/P3 fail-closed source attribution discipline: every diagnostic emission carries structural source-span provenance; not optional. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 INLINE BLOCKING — Token authority cite phantom-reference fix Cursor INLINE BLOCKING /api/reviews/12279 line:29: §3.1 cited `src/v3/compiler/src/tokenize.rs` as "current hand-Rust" for Token carrier — but `tokenize.rs` (without _generated suffix) doesn't exist. Live state has tokenize.dag (live substrate) + tokenize_generated.rs (codegen artifact). Per design-pure-bootstrap.md PB-2 lane: tokenize retire has substantially landed. The reference was an earlier-draft phantom from when Token-was-hand-Rust framing was the assumption. Fix: §3.1 reframed — Token type lives in LIVE src/v3/std/tokenize.dag:65-67 shared taxonomy; tokenizer implementation also live at src/v3/compiler/tokenize.dag (154 lines); codegen artifact at tokenize_generated.rs. tokenize.rs phantom reference removed explicitly. PB-2 substantially landed per design-pure-bootstrap.md; residual scaffold-retirement scope per PB-2 L2.5 PR #3127. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 INLINE BLOCKING — Step 2 pipeline-slot target fix (compiler.dag → pipeline.dag) Cursor INLINE BLOCKING /api/reviews/12281 line:138: §9 Step 2 referenced generic "compiler.dag" but dsl/gunbc/compiler.dag:24 explicitly directs internal pipeline (Tokenize → Parse → ...) to src/v3/compiler/pipeline.dag, NOT generic compiler.dag. Worker briefs authored against this doc would target the wrong file for pipeline-slot declaration. P2 single-authority violation. Fix: §9 Step 2 row in ALL 4 L2.5 docs (PB-2 / PB-3 / PB-4 / PB-5) updated: - "declared in compiler.dag" → "declared in src/v3/compiler/pipeline.dag (per dsl/gunbc/compiler.dag:24 — internal pipeline lives in pipeline.dag, NOT generic compiler.dag)" - substrate column: "compiler.dag refinement" → "pipeline.dag refinement" - §13 "Step 2 (pipeline-slot in compiler.dag)" → "pipeline-slot in src/v3/compiler/pipeline.dag" Same phantom-citation class as the tokenize.rs phantom (commit 8ae37b4): I cited generic file path without verifying which specific file is authoritative per project structure. Should have grep'd dsl/gunbc/compiler.dag header notes before authoring. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 INLINE BLOCKING — Step 3b/4 phasing P5 receipt unambiguity Cursor INLINE BLOCKING /api/reviews/12283 line:181: Q5 said Step 3b "full parser body .dag migration + parser body deletion in same PR", but §15 sequence schedules Step 4 parity/deletion AFTER Step 3b merges. P5 dissolution receipt ambiguous. If Step 3b lands .dag parser body BEFORE Step 4 deletes Rust parse() body, Rust + .dag parser bodies coexist temporarily — paper-shrink-relocation risk per feedback_paper_shrink_variants. Fix: 1. §9 Step 3b row reframed as "Step 3b/4 COMBINED" — atomic single PR (full .dag parser body + parity TestClaim + parse_generated.rs:138 deletion + census shrink). Cannot land .dag parser body before Rust deletion. 2. §12 Q5 phasing clarified: - Phase 3a (separate PR): grammar table extension; P5 receipt = ROADMAP deferral row naming Step 3b/4 as future-receipt - Phase 3b/4 COMBINED (single PR): atomic substrate substitution 3. §9 + §15 update notes: sequence collapses steps 12-17 into single dispatch+merge for combined phase Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3126 high-level BLOCKING findings 1 + 2 Codex high-level BLOCKING (sha 140eb6b) had 4 findings: - Findings 3 + 4 already addressed in PR #3138 commits 0159773 + a1607a8 - Findings 1 + 2 addressed in this commit **Finding 1 (Diagnostic kind/record conflated)**: §4.2 ParseDiagnostic was modeled as variants-directly with span + kind-fields mixed. Live Diagnostic at diagnostics.dag:150 uses record-wraps-kind pattern (`{ kind, span, message, correction }`). Need consistent shape. Fix: refactored to record-wraps-kind: - `type ParseDiagnostic { kind: ParseDiagnosticKind, span: SourceSpan }` - `type ParseDiagnosticKind = UnexpectedToken | UnterminatedConstruct | InvalidLiteral | DuplicateRecordFieldLabel | ...` Span lives on ParseDiagnostic record (single source of truth); variant-specific spans (opener_span / prior_span) remain on kind variants where meaningful. **Finding 2 (PB-2 §6 obsolete sibling-lane assumption)**: §6 line 198 said "PB-2 Tokenize | src/v3/std/tokenize.dag (NEW per PB-2 L2.5)" — but tokenize.dag is ALREADY LIVE per design-pure-bootstrap.md §"PB-2 — tokenize retire" (substantially landed). Fix: §6 prereq table row updated to reflect LIVE state. PB-2's residual scope is scaffold-retirement (SG-1a + character-level + codegen-driver per PB-2 L2.5 §1), not carrier authoring. PB-3 consumes the live Token carrier; carrier shape stable across PB-2 residual-retirement timing. Findings 3 + 4 already addressed: - Finding 3 (pipeline.dag target): commit 0159773 - Finding 4 (Step 3b/4 atomic vs sequential): commit a1607a8 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 APPROVE_WITH_COMMENTS — phantom "module-level metadata" removed Cursor APPROVE_WITH_COMMENTS line:79: §4.1 said "SurfaceModule (verified live) carries List<SurfaceItem> + module-level metadata" — but live parse_surface.dag:29 has ONLY `{ items: List<SurfaceItem> }`. No metadata fields. Phantom addition violated INVARIANTS P1 live-state honesty. Fix: §4.1 reframed to match live carrier exactly. Same phantom-addition class as tokenize.rs phantom (commit 8ae37b4). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3085 high-level BLOCKING findings — AtomPayload 5-variant + diagnostic-table PROPOSED Codex high-level BLOCKING (sha bf4d315) — 2 substantive findings: **Finding 1 (AtomPayload stale)**: §2 + §5 cited infer.rs:10 top-comment "Atom(Identifier { name, resolved })" — but live substrate.dag:87 has 5-variant AtomPayload sum: Literal | UnresolvedIdentifier | ResolvedByStructure | ResolvedByName | TypeParam. infer.rs top-comment is STALE vs live substrate. My doc inherited the drift. Fix: §2 enumeration corrected to all 5 AtomPayload variants per live substrate.dag:87. **Finding 2 (diagnostic-table PROPOSED, not live)**: §2 + §4.1 + §4.3 said "diagnostics.contains(port_id) biconditional" as if live — but Dag at substrate.dag:525 has ONLY { declarations, nodes, ports, clusters }. NO diagnostics field. Diagnostic-table is PROPOSED substrate extension. Fix: §2 fail-closed note flagged PROPOSED — Step 2 PR scope includes `diagnostics: Map<PortId, Diagnostic>` field extension to Dag, OR PB-Substrate prereq adds it before PB-5 dispatch. Same recurring feedback_grep_carrier_field_before_coupling_claim discipline (PR #3126 SurfaceModule analogous case); needed to grep type Dag fields BEFORE claiming the diagnostics field exists. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3085 INLINE BLOCKING line:94 — §4.1 + §4.3 PROPOSED diagnostic-table marking Cursor INLINE BLOCKING line:94: §4.1 + §4.3 said "diagnostics coupled INTO InferredDag" without flagging the diagnostic-table as a substrate extension. Live Dag at substrate.dag:525 has { declarations, nodes, ports, clusters } — NO diagnostics field. Earlier commit c0d96af added PROPOSED marking only in §2; §4.1 + §4.3 needed same treatment. Fix: §4.1 + §4.3 reframed with explicit PROPOSED substrate- extension marking + reference to §2 for extension scope. Construction-time invariant + structural coupling are both contingent on the substrate-extension landing (Step 2 PR scope or PB-Substrate prereq). Same recurring feedback_grep_carrier_field_before_coupling_claim discipline applied to §4.1 + §4.3 consistently with §2. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3077 high-level BLOCKING — Practice 4 classifications for PB-4 coproducts Codex high-level BLOCKING (sha b812db9): "Diagnostic substrate shape was repaired around anchoring but not re-audited as new substrate type declarations" — meaning DiagnosticAnchor + LowerDiagnostic + SurfaceFormRef + IdentifierRef need 🟢/🟡/🔴 classifications per modeling-discipline Practice 4 (Coproduct dissolution). Same pattern as PB-5 fix in commit 040681f (AlgebraAxis + InferDiagnostic) applied here. Fix: added classifications + dissolution triggers: - SurfaceFormRef 🟢 TERMINAL: closed-axis sum over live Surface* carriers; no further dissolution. - IdentifierRef 🟡 SCAFFOLD: dissolution trigger = Step 2 brief enumerates full identifier-kind set against lower.rs identifier-resolution sites; promote to 🟢 TERMINAL when SurfaceVarRef + TypePathRef + ModulePathRef cover actual axes. - LowerDiagnostic 🟡 SCAFFOLD: dissolution trigger = Step 2 brief enumerates variant set against lower.rs Diagnostic emission sites + Q6.5 anti-bridge preserved + PR #3077 §12 Q7 ratification path. - DiagnosticAnchor 🟢 TERMINAL: closed-axis covering all lowering-stage anchor kinds; no further dissolution. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3077 INLINE BLOCKING line:161 — DiagnosticSource Practice 4 classification Cursor inline finding adds DiagnosticSource to Practice 4 classification scope. Earlier commit aba79a1 classified SurfaceFormRef + IdentifierRef + LowerDiagnostic + DiagnosticAnchor but missed DiagnosticSource. Fix: DiagnosticSource 🟢 TERMINAL at pipeline-stage discrimination scope. Closed-axis sum (Parse | Lower | Infer | Emit); adding new pipeline stage requires explicit substrate- extension audit per Practice 4 + stop-signal discipline (same shape as PB-5 §3.2 TypeConnective stop-signal). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 INLINE BLOCKING line:151 — §11 SurfaceItem::Let + SurfaceLiteral span correction Cursor INLINE BLOCKING line:151: §11 claimed "every Surface variant carries SourceSpan" but live parse_surface.dag has: - SurfaceItem::Let { name, type_ann, expr } — no direct span - SurfaceLiteral = Int(String) | Bool(Bool) | String(String) — plain-tuple variants with no direct span Source-span provenance for these cases is via enclosing carrier: SurfaceLiteral wraps within `Literal { value, span }` at parse_surface.dag:150. Let-item inherits container span. INVARIANTS P2/P3 source provenance is structurally guaranteed via direct-OR-enclosing carrier, but my "every variant" overstatement obscured this. Fix: §11 corrected to "most Surface variants carry SourceSpan directly" + explicit Let + SurfaceLiteral exceptions noted + Step 2 PR scope audits whether exceptions are structural-honest (enclosing-carrier-provides-span) OR require substrate extension. Same recurring overstatement class as earlier "every SurfaceItem maps 1:1 to Declaration" (commit 61e2b67) — need to grep live substrate variant fields BEFORE claiming uniform shape. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * WIP: gunbc Director * docs(r3): cursor PR #3126 INLINE BLOCKING line:32 — GrammarSpec is concept, not carrier Earlier draft (now-merged PR #3126) framed `GrammarSpec` as a second declared `.dag` input type alongside `List<Token>`. Verified via grep that no `type GrammarSpec` exists anywhere under src/v3/ or dsl/ — the repo carries only `parse_tables.dag`'s 6 SG-2c table-families. Per cursor 2026-05-14T23:30:04Z inline finding, this violates INVARIANTS P2 (the Step-2 signature names a carrier the substrate doesn't declare). Reframed §3 (and downstream mentions in §3.2, §3 preamble line:33, §4.2 codex-correction recap line:165, §5.1 line:181, §12 Q6 line:344) so that: - Parse has ONE input at the API boundary: `List<Token>`. - "GrammarSpec" is a concept-level grouping for the 6 compile-time table-families in `parse_tables.dag`, not a substrate carrier and not a runtime parameter. - Step-2 signature stays `fn parse(tokens: List<Token>) -> Result<SurfaceModule, ParseDiagnostic>` per cfe842b (already applied in #3126); these edits remove the lingering "two input types" framing that contradicted that signature. Per Decision 3.B (b) compile-time parser tables: substrate authority is parse_tables.dag (6 table-families) consumed via direct table lookups inside the parser body — no runtime grammar value, no `GrammarSpec` carrier needed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3138 BLOCKING — §4.3 + §16 internal contradictions resolved Codex review id 12391 on sha cd6e8d1 flagged two live statements of the already-rejected typed-state-with-coupled-diagnostics model still sitting inside the parse L2.5, contradicting the corrected Result-sum framing in §4.2 and §6 Step 2: 1. §4.3 still proposed a `SurfaceModule { items, diagnostics }` extension modeled on PB-4/PB-5 patterns. Reframed: §4.3 now states explicitly that parse-stage uses Result-sum (no diagnostics field on SurfaceModule), restates the cross-stage discriminator (Result-sum for fail-fast output domains: parse + emit; typed-state for structural output domains: lower + infer), and cites `parse_generated.rs:138` as the live shape. 2. §16 "Memory disciplines applied" bullet read "feedback_state_space_vs_behavioral_invariants (typed-state SurfaceModule at output)". Rewritten to "parse output is `Result<SurfaceModule, ParseDiagnostic>` — the type rules out partial-parse states by construction; SurfaceModule itself carries no diagnostic field per §4.3". Per `feedback_discipline_change_audit_all_contract_mentions`: when a contract changes (here: SurfaceModule extension dropped in favor of Result-sum), all §-internal restatements must be swept in the same diff or they leak through as authoritative parallel claims. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3127 BLOCKING — drop TokenizedSource extension + cite concrete P5 receipts Codex review id 12370 on sha d15e1f2 raised two load-bearing planning-shape findings on the tokenize L2.5. Addressed in this fix-forward branch (PR #3138) since PR #3127 is still open but accumulating cycles. Finding 1 — parallel boundary carriers (INVARIANTS P2 / Modeling Practices 3+5): §4.3 + §9 Step 2 + §12 Q6 named `TokenizedSource { tokens, diagnostics }` as the output, while §2/§7.2/§7.3 named `List<Token>`. Same misclassification I just removed from the parse L2.5 in PR #3138 §4.3: tokenize sits in the fail-fast output domain alongside PB-3 parse + PB-6 emit (a partial token list with a corrupt token in the middle is not a valid downstream input for parse), so the failure couples via `Result`, not into the structural carrier. Resolution: - §4.3 rewritten to ratify `Result<List<Token>, TokenizeDiagnostic>` — the live `tokenize_generated.rs:96` shape — with no `TokenizedSource` extension. - §9 Step 2 row signature updated to match; explicit "single canonical boundary carrier: List<Token> on the Ok branch" framing. - §12 Q6 resolved REJECTED in-doc (no operator ratification needed; disposition follows from the cross-stage discriminator that's also load-bearing in PR #3138 parse L2.5). - §16 memory-disciplines bullets rewritten parallel to PR #3138 parse §16: Result-sum, no diagnostics field on `List<Token>`. - §14 "Surfaces awaiting" trimmed Q6 from the operator-ratification list. Finding 2 — soft deferral of `regen_tokenize` retirement (INVARIANTS P5): deferral previously named "PB-Bootstrap-Process lane scope" without a concrete ROADMAP.md row. Updated §9 Step 2 + Step 4 rows to cite the named receipts: - `docs/design-pure-bootstrap-zero.md:116` (PB-Bootstrap-Process lane: author bootstrap.dag + generated trampoline; sized M). - `docs/design-pure-bootstrap-zero.md:118-123` (N=0 runtime verification gates). - ROADMAP.md:467 (Character-level under-consumption in tokenize + syntax authorities — phase-2 char-class retype owns the codegen-driver path). - ROADMAP.md:416 (Class 5 Gap 3 — top-level `ValueBody` boundary; gating substrate-capability for the phase-2 retype). - ROADMAP.md:53 (T-PB-A — non-test census → 0 floor). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 BLOCKING line:119 — §6/§7.2/§15 Q7 sequencing resolved by PR #3077 merge Cursor inline BLOCKING at docs/design-parse-stage-l25-model.md:119 (sha at merge time of PR #3126) flagged a real internal contradiction: - §6 (lines 191, 207, 308) claimed "Step 2 (pipeline-slot declaration) is unblocked" - §7.2 (line 227) claimed "PR #3077 §12 Q7 must ratify before any Step 2 worker brief authoring" A worker reading the doc could land Step 2 (pipeline boundary) before the diagnostic carrier's P2/P3 failure shape was fixed. Resolution: PR #3077 (PB-4 lower L2.5) merged at 2026-05-15T00:21:19Z, carrying the §12 Q7 ratification of the Decision 2.B per-stage diagnostic extension path. The gate IS now satisfied at HEAD, so the resolution is fact-update (annotate Q7 as DONE with the merge timestamp) rather than retracting either §6 or §7.2. Edits: - §15 step 4: annotated "DONE 2026-05-15T00:21:19Z when PR #3077 merged" and added the explicit "Step 2 is now genuinely unblocked, not just procedurally next" framing so workers reading the sequence don't bypass the gate. - §7.2 line 227: rewritten from "Q7 must ratify before Step 2 brief authoring" (future tense, the contradiction surface) to "Gate satisfied 2026-05-15T00:21:19Z when PR #3077 merged; Step 2 worker brief authoring is unblocked at HEAD per §15 step 4." Cites the cursor finding as the resolution path. §6 unblocking statements stay as-is — they were correct at HEAD; the contradiction lived in §7.2's pre-merge framing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3126 BLOCKING (sha 16d21f4) — Q7 cited at every Step 2 unblocking claim Codex BLOCKING finding 2 (sha 16d21f4, 216s thinking): the Q7 dependency was recorded in §7.2/§15 but not in the other Step-2-unblocking sites at §6 lines 191, 207, 308 — risking a worker reading "Step 2 unblocked" without also reading the Q7 prerequisite. Codex framing: "make Q7 a hard precondition wherever Step 2 is called unblocked, or split Step 2 into pre-Q7 and post-Q7 scopes with separate receipts." Chose the first option since PR #3077 has already merged (2026-05-15T00:21:19Z) and splitting into pre/post-Q7 scopes is no longer load-bearing. Annotated all three §6 sites: - Line 191 (Implication for PB-3 migration): cites gate + merge timestamp + explicit "must NOT be brief-authored before that merge timestamp." - Line 207 (Critical observation): cites the Step 2 gate as PR #3077 §12 Q7 + merge timestamp + P3 failure-shape consequence if violated. - Line 308 (Director-recommend phase list): cites gate + §7.2/§15 step 4 cross-refs + merge timestamp. Codex BLOCKING finding 1 (GrammarSpec carrier non-existence) verified already resolved at HEAD via commit c97dc15 — every GrammarSpec mention now explicitly marks it as a concept-not-carrier; Step 2 signature is `fn parse(tokens: List<Token>) -> Result<SurfaceModule, ParseDiagnostic>` with no GrammarSpec parameter. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): openai-pro PR #3126 BLOCKING (sha 16d21f4) — Step 3b/4 atomicity + Q1 ratification-pending status openai-pro REQUEST_CHANGES on PR #3126 sha 16d21f4 flagged three findings. Findings 1 + 2 (signature vs realization mismatch under LAYER MODEL + P2/P3 boundary discipline) were already resolved at HEAD by earlier fix-forward commits — Step 2 signature is now `fn parse(tokens: List<Token>) -> Result<SurfaceModule, ParseDiagnostic>` matching live `parse_generated.rs:138` with no GrammarSpec parameter and no diagnostics-coupled SurfaceModule extension (§4.3 Result-sum disposition). Finding 6 (TRACKED vs UNTRACKED DEBT — Step 3b/4 same-PR vs two-PR): §9 had both a "Step 3b/4 COMBINED" row (line 250) and a leftover separate "Step 4: Parity test" row (line 251) — internally contradictory. §15 also still sequenced Steps 3b + 4 as four separate authoring/dispatch/ratify beats (steps 12-17), contradicting §12 Q5's "same PR" decision and the explicit "Update to §15" note at §12 line 325. Resolution: collapsed §9 to one COMBINED row absorbing the parity-TestClaim mechanics + P5 dissolution receipt from the deleted Step 4 row; collapsed §15 steps 12-17 into single COMBINED authoring + dispatch + ratify (steps 12-14). Added explicit `feedback_paper_shrink_variants` reasoning in both sections. Finding 2.5 (PM intent — substrate-capability bundled vs separate): §12 Q1 line 288 said "Director-recommend: (b) bundled" while §13 line 340 listed substrate-capability as a non-goal of PB-3 and §15 step 11 had "WAIT for substrate-capability landing" — three sections, two different execution paths. Resolution: annotated Q1 as "PENDING operator/PM ratification" with explicit default-execution clause: until operator ratifies, the doc treats substrate-capability as path (a) separate lane (matching §13 + §15 + §9 row). If/when ratified to (b), §13 drops the non-goal and §15 step 11 collapses into the COMBINED Step 3b/4 brief. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3126 BLOCKING (sha 5619afa) — parse_tables.dag as single enumerated authority Codex caught me copying the prose summary at parse_tables.dag:23-29 (which enumerates only SG-2c-numbered families) instead of grepping the live `^type [A-Z]` declarations. Result: SoftKeywordIdentRow (line 334) was missing from §3.2 / §5.1 / §6 / §12 because it lacks an SG-2c-N number in the prose summary. Per `feedback_parallel_representation_debt`: structural fix is to stop hand-enumerating in the doc — cite parse_tables.dag itself as the single enumerated authority and use `type`-declaration line-anchors for the worked example, not a hand-maintained count. Edits: - §3.2 §"Live substrate authority": replaced the SG-2c-numbered bullet list with `type`-declaration line-anchor enumeration including SoftKeywordIdentRow at parse_tables.dag:334 + the supporting enum BinaryOpLevel at line 133. Added codex-finding callout explaining the miss + the discipline shift. - §3 preamble line:33, §3.2 line:45 callout, §3.2 line:57 framing, §3.2 §"Substrate authority" line:71, §5.1 line:171-180, §12 Q2 line:298, §12 Q6 line:334: all hardcoded "6 table-families" counts dropped; doc now points readers to §3.2 enumeration / `parse_tables.dag` directly. - §5.1 sub-enumeration list (the parallel 6-item list at lines 173-178) deleted; replaced with redirect to §3.2 + restated 3a-vs-3b/4 scope split. Code-level check before commit: `grep -nE '^type [A-Z]' src/v3/compiler/parse_tables.dag` returns 7 types: BinaryOpLevel (133), BinaryOpRow (167), TopLevelItemKwRow (289), SoftKeywordIdentRow (334), BracketRow (385), PrimaryPrefixRow (449), PrimaryAtomRow (486). Doc enumeration matches. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3138 BLOCKING (sha f08b952) — bind TokenizeDiagnostic to live CharClass authority Codex Finding 1 (sha f08b952, 216s thinking): the §4.2 TokenizeDiagnostic draft and the §5.1/§5.2 headings used `ScannerCharClass` / `ScannerClassRef` — names that exist only as the *generated Rust enum spelling*, not as a declared .dag substrate type. Verified via grep: grep -rn '^type CharClass\|^type ScannerC' dsl/ src/v3/ returns ONE authority: `dsl/std/unicode.dag:62` type CharClass = Whitespace | Digit | IdentStart | IdentContinue consumed at `src/v3/compiler/tokenize.dag:103` data ascii_scan_order: List<CharClass> = [Whitespace, Digit, IdentStart, IdentContinue] There is no `ScannerCharClass` declaration anywhere — that name was copied from generated Rust without grep-verification, the same failure mode as `feedback_grep_substrate_before_naming_ratification` (carrier-name collision discipline). Resolution: - §4.2 TokenizeDiagnostic carrier: `expected_class: ScannerClassRef` → `expected_class: CharClass`, dropped the `type ScannerClassRef = ScannerCharClass` alias entirely; added a codex-finding callout citing the substrate authority + naming the failure mode. - §5.1 heading "Byte → ScannerCharClass dispatch" → "Byte → CharClass dispatch"; bullets unchanged; added line-anchor cites for the substrate authority + explicit "NOT ScannerCharClass" disclaimer. - §5.2 heading "ScannerCharClass → token-recognition state machine" → "CharClass → token-recognition state machine". Finding 2 (TokenizedSource not reconciled with parse input contract): no new fix required — already resolved by commit 6adb992 (TokenizedSource extension dropped entirely; tokenize uses Result<List<Token>, TokenizeDiagnostic>; List<Token> is the single canonical boundary carrier consumed by parse). Codex was reviewing sha f08b952, which predated the TokenizedSource drop. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3138 INLINE BLOCKING line:188 — clarify §7.3 chain is Ok-branch propagation Cursor INLINE at sha f08b952 worried that §7.3's cross-stage chain "tokenize → List<Token> → parse → ..." was inconsistent with §4.3's TokenizedSource carrier (diagnostics not flowing forward). At HEAD the TokenizedSource extension is dropped (commit 6adb992); tokenize uses Result<List<Token>, TokenizeDiagnostic>, so List<Token> IS the canonical Ok-branch payload that flows forward and Err branches terminate the pipeline fail-fast. To make this explicit at §7.3 (instead of leaving readers to infer it from §4.3), annotated the chain with: - "Ok-branch propagation; Err branches are stage-terminal fail-fast per §4.3 Result-sum discriminator" framing prefix. - Per-stage Result/typed-state annotations: tokenize/parse show Result<Ok, Err>; lower/infer show typed-state structural-output; emit shows Result<EmittedArtifact, EmissionDiagnostic>. - Explicit "on any stage's Err branch the pipeline aborts at that stage (no partial-output propagation across boundaries)" trailer. This makes the chain self-consistent vis-a-vis §4.3 without requiring the reader to walk back-and-forth, and prevents future readers from re-introducing a TokenizedSource-shaped extension to "make diagnostics flow forward" — they already do, just via the Err branch terminating the pipeline. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): openai-pro PR #3127 BLOCKING (sha d15e1f2) — character-level scaffold dissolution trigger openai-pro REQUEST_CHANGES on sha d15e1f2: §1 line:26 character-level under-consumption scaffold named the problem but lacked a checkable dissolution trigger. SG-1a scaffold above had the right shape — "once those bodies lower structurally under compile_to_dag, delete the raw-text extractor + derive directly from lowered Dag in same PR." Character-level scaffold just said "PB-2 Step 4 carries this scope" — a lane assignment, not a trigger. Resolution: rewrote §1 item 2 with the same SG-1a-shape trigger structure: - Substrate-consumption condition (a): scanner classes / string escape / local punctuation retype to `dsl/std/unicode.dag` `CharClass` / `char_in_class` (concrete field retypes named: `StringEscapeSpec.suffix: Char`, `LocalPunctSpec.pattern: List<Char>`, `string_literal_delimiter: Char`). - Codegen-driver condition (b): `tokenize_generated.rs` no longer emits hidden `byte.is_ascii_*` predicates because the driver reads class facts structurally from lowered `tokenize.dag`. - Same-PR dissolution: delete the parallel character-predicate scaffold in the same PR that flips substrate consumption — no Rust-and-`.dag` coexistence per `feedback_paper_shrink_variants`. - Cross-ref to §9 Step 4 gating prereqs: ROADMAP.md:467 + ROADMAP.md:416 Class 5 Gap 3 + std.unicode bootstrap/load-set decision (already cited in §9 from earlier commit 6adb992). Per openai-pro's framing: "small fix — mirror the SG-1a scaffold wording by naming the exact substrate-consumption condition and same-PR deletion receipt for the hidden Rust character predicates." Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * WIP: gunbc Director * docs(r3): cursor PR #3127 APPROVE_WITH_COMMENTS — §14 + §15 Q6-already-rejected sweep Cursor review id 12405 (APPROVE_WITH_COMMENTS) caught the same `feedback_discipline_change_audit_all_contract_mentions` failure mode recurring: §12 Q6 was resolved REJECTED in commit 6adb992, and §14 "Surfaces awaiting" + §12 Q6 heading + §9 Step 2 row were updated, but two §-internal contract restatements were missed: - §14 acceptance criterion 11: "Operator/PM ratification on §12 Q1-Q6" - §15 step 1: "Operator / PM-delegate ratifies §12 Q1-Q6" Both contradicted §12 Q6 + §14 "Surfaces awaiting" (which already said "Q1-Q5 only"). A worker reading §14/§15 could schedule sign-offs on Q6 after it was already resolved-rejected elsewhere. Resolution: both sites now say "Q1–Q5" with the explicit Q6-rejected crossref + "see §14/§15 for same scoping" pointer at the §14 criterion so the three sections agree internally. Cursor verdict was APPROVE_WITH_COMMENTS (substantive APPROVE — "fix the checklist/sequence so every section agrees Q6 is closed"); the exploratory volatile-line-anchor note is harmless and out-of-scope for this PR. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…r inline Q7 sweep (#3140) * docs(r3): PB-2 tokenize pipeline-stage L2.5 domain model — DRAFT for ratification Director-tier L2.5 model for PB-2 tokenize per operator 2026-05-14 ratification (Decision 1.A scoping = Option A). PB-2 is the FURTHEST-ALONG pipeline stage — substrate authority already lives in `.dag`: - src/v3/std/tokenize.dag (Token + TokenKind taxonomy; LIVE 143 lines) - src/v3/compiler/tokenize.dag (tokenizer implementation; LIVE 154 lines) - src/v3/compiler/src/tokenize_generated.rs (AUTO-GENERATED; 362 lines) This is the END STATE that all other pipeline-stage migrations target. PB-2 L2.5 is correspondingly lighter — mostly verification + residual hand-Rust retirement, NOT new substrate authoring. Distinct §9 4-step framing: - Step 3 = VERIFY substrate completeness (audit per feedback_paper_shrink_variants) - Step 4 = HANDOFF/RETIRE residual hand-Rust scaffolding (coordinates with PB-Bootstrap-Process lane for codegen-driver retirement) Captures audit dimensions explicitly: - scanner-class definitions = declarative byte-pattern membership - recognition tables = closed-axis enums - state machine = structural transitions - no V2 `pub mod tokenize` absorption check §12 Q1: codegen-driver retirement scope — Director-recommend PB-Bootstrap-Process handles all codegen-driver retirement cross-cuttingly (not per-stage paper-shrink risk). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): §12.6 citation fix — tokenize is PB-2 lane scope per design-pure-bootstrap-zero.md Per cursor PR #3085 finding: §12.6 explicitly tables only 4 pipeline-stage migrations (emit→lower→infer→parse); tokenize is per design-pure-bootstrap-zero.md PB-2 lane. Same fix as PR #3085 commit 89fbd7a applied here. INVARIANTS P1 — documentation must not overstate authority cites. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): preemptive fix for PR #3126 codex BLOCKING propagation — PB-2 live state honesty Same class as codex INLINE BLOCKING #3126 finding 1 (live state honesty for diagnostic coupling) applied preemptively to PB-2 tokenize L2.5. PB-2 §4.3 had "diagnostics coupled INTO List<Token>" framing which would overstate the live carrier shape (bare List<Token> has no diagnostic field; tokenize_generated.rs:96 today returns Result<Vec<Token>, Diagnostic>). Fix: §4.3 reframed with PROPOSED substrate extension explicit — new `TokenizedSource { tokens, diagnostics }` wrapper carrier as the typed-state output. Step 2 brief includes wrapper authoring in pipeline-slot PR scope. Same discipline as PR #3126 commit bdff8c5. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3077 — fix PB-2 lane citation (design-pure-bootstrap.md not -zero.md) Per cursor APPROVE_WITH_COMMENTS /api/reviews/12087: PB-2 lane is defined in docs/design-pure-bootstrap.md §"PB-2 — tokenize retire" (line ~134), NOT docs/design-pure-bootstrap-zero.md. The -zero.md doc has Subsumed-lanes list with PB-1/PB-4/PB-5/PB-6 but NOT PB-2. Propagated fix applies same cite-error correction as PR #3066 §1.8 discipline: cite the actual doc, not an adjacent doc with similar name. INVARIANTS P2 single-authority-citation. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): fix cursor PR #3127 BLOCKING contradictions + add §12 Q6 Cursor APPROVE_WITH_COMMENTS (/api/reviews/12093) caught two substantive contradictions I introduced when adding TokenizedSource in commit 2b9756b: 1. §4.3 vs §9 Step 2 signature mismatch — §4.3 said `-> TokenizedSource` but §9 Step 2 row still said `-> List<Token>`. Same `feedback_discipline_change_audit_all_contract_mentions` issue that's recurred 4x this session. 2. §4.3 referenced "§12 Q-new" but §12 only had Q1-Q5; broken anchor. Fix: 1. §9 Step 2 row updated: signature `-> TokenizedSource` with wrapper carrier shape `{ tokens, diagnostics }` per §4.3 2. §4.3 anchor updated: "§12 Q6" (resolved) 3. Added §12 Q6: TokenizedSource carrier shape ratification — (a) wrapper record vs (b) per-Token diagnostic coupling; Director-recommend (a) for PB-3 SurfaceModule parallelism 4. §14 + §15 + §16 Q-list refs updated to Q1-Q6 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): fix codex BLOCKING PR #3127 — Token shape + Q4 audit boundary Codex REQUEST_CHANGES (sha b881de2) with 2 substantive findings: 1. §4.1 Token shape claim "optional lexeme: String" — wrong per live substrate at src/v3/std/tokenize.dag:65-67. Live Token has 2 fields only (kind + span); lexeme-content lives ON the TokenKind variants (Ident(String) / IntLit(String) / etc.). Fix: corrected §4.1 to reflect live carrier shape; payloads on TokenKind variants noted explicitly. 2. §12 Q4 substrate-completeness audit scoped only to tokenize_generated.rs — missed the regen_tokenize codegen- driver boundary. If regen_tokenize carries scanner-logic decisions (rather than mechanical template-rendering of substrate facts), the substrate isn't complete — the driver IS hand-Rust scanner logic in disguise. Fix: Q4 audit extended with (d) regen_tokenize codegen- driver logic audit + (e) ROADMAP.md deferral row option per feedback_paper_shrink_variants P5 receipt discipline. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): fix codex BLOCKING PR #3127 — TokenizeDiagnostic PROPOSED + scaffold disclosure Codex REQUEST_CHANGES (sha b881de2, full body) caught 2 substantive overstatements: 1. §2 line 46 claimed "tokenize failures produce typed TokenizeDiagnostic variants" — but live tokenize_generated.rs:96 returns generic `Result<Vec<Token>, Diagnostic>` with `Diagnostic::TokenizerError { message, span, correction }`. Typed TokenizeDiagnostic is a PROPOSED extension, not live state. Fix: §2 reframed with live state explicit + TokenizeDiagnostic marked PROPOSED per PR #3077 §12 Q7 ratification path. 2. §1 line 22 + §6 + §9 Step 2 line 198 framed PB-2 as "mostly verification" — but live tokenize.dag:16-30+ has TWO explicit tracked scaffold zones: - SG-1a: regen_tokenize parses raw source text for dag_keyword_set / dag_operators (ValueBody::Unparsed) - Character-level under-consumption: StringEscapeSpec / LocalPunctSpec.pattern / string_literal_delimiter as opaque Strings; hidden Rust character predicates (byte.is_ascii_digit etc.) at tokenize_generated.rs:15-22 leaking through codegen Residual hand-Rust is NOT just the codegen artifact — it includes (a) regen_tokenize logic, (b) SG-1a raw-text-extractor scaffold, (c) character-predicate scaffold leaking through codegen. Fix: §1 + §6 + §9 Step 2 reframed honestly. PB-2 is "FURTHER ALONG but not complete"; Step 4 carries scaffold-retirement scope, not just codegen-artifact retirement. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): post-merge fix-forward — §16 + §9 Step 2 internal contradictions Two post-merge doc-internal contradictions caught by reviewers after operator merged PR #3077 / #3126 / #3085 at 2026-05-15T00:21Z. **PR #3077 PB-4 lower §16 fix**: §16 "Memory disciplines applied" bullet said "diagnostics coupled INTO PreInferDag via biconditional" — but §4.3 (per openai-pro DiagnosticAnchor fix commit b812db9) constrains biconditional to PortAnchor-only. Other anchor kinds (DeclarationAnchor / RecordFieldAnchor / SurfaceFormAnchor) couple without port-state. Fix: §16 bullet honors §4.3 anchor-typed framing. **PR #3126 PB-3 parse §9 Step 2 fix**: §9 Step 2 row described diagnostics as "coupled INTO SurfaceModule" as if live — §4.3 correctly marks it PROPOSED. Same feedback_discipline_change_audit_all_contract_mentions pattern that's recurred this session. Fix: §9 Step 2 row clarified — "PROPOSED extension per §4.3"; Step 2 PR scope includes authoring the diagnostics field extension, NOT a live coupling. Per feedback_discipline_change_audit_all_contract_mentions: when a substantive fix changes a discipline framing, audit ALL sections (framing + contract + handoff). Post-merge audit surfaced these residual contradictions. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): post-merge fix-forward — PR #3126 codex BLOCKING (GrammarSpec parallel-authority + fail-closed weakening) Codex REQUEST_CHANGES on already-merged PR #3126 (/api/reviews/12175): 2 substantive findings on the post-merge doc. **Finding 1 (P2 violation — GrammarSpec parallel authority)**: §3.2 says GrammarSpec is compile-time-only, NOT runtime- interpreted (per Decision 3.B (b) operator override). But the proposed stage contract still took `grammar: GrammarSpec` as runtime input. Creates two authorities (compiled parser tables + runtime GrammarSpec value). Fix: §4.3 signature reframed to `fn parse(tokens: List<Token>) -> Result<SurfaceModule, ParseDiagnostic>` — NO runtime GrammarSpec input. Compile-time generated parser tables consumed via internal dispatch. Step 2 + Step 4 rows updated. **Finding 2 (P3 + Practices 1/2 — fail-closed weakening)**: Live parser at parse_generated.rs:138 returns `Result<SurfaceModule, Diagnostic>` (fail-closed; aborts on first error). Earlier draft proposed `SurfaceModule` with embedded diagnostics — would let partial-parse states be constructible + let downstream observe "success" output after parse failure. Violation of fail-closed discipline. Fix: signature preserves Result-sum (matches live + emit's pattern). Distinguished cross-stage: - Result-sum (parse + emit): fail-fast output domain - Typed-state-with-coupled-diagnostics (lower + infer): structural output domain where partial-failure IS valid intermediate Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 post-merge APPROVE_WITH_COMMENTS — §4.1 + §16 fail-closed honesty Cursor caught 2 more post-merge contradictions on PR #3126: 1. §4.1 line 81 "construction-time invariant" talks about "ParseDiagnostic in the diagnostic stream" tied to SurfaceModule path — but §5.2 + live parse_generated.rs:138 use Result<SurfaceModule, Diagnostic>. §4.1 reads as claim about today's plumbing. Fix: §4.1 reframed — live boundary explicit (Result-sum); construction-time invariant scoped to Ok-arm SurfaceModule + Err-arm ParseDiagnostic, no partial-parse with embedded diagnostics. 2. §16 line 397 cites C-8 as "ParseDiagnostic coupled INTO SurfaceModule" without qualifier — but §4.3 (post codex REQUEST_CHANGES fix) constrains to Result-sum. Fix: §16 bullet honors §4.3 Result-sum framing; cross-stage discriminator named. Same recurring feedback_discipline_change_audit_all_contract_mentions pattern — substantive fix to §4.3 + §9 Step 2 left §4.1 + §16 inconsistent. Post-merge audit catches. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3085 INLINE BLOCKING — TypeConnective extension stop-signal Cursor INLINE BLOCKING caught §3.2 line 66 "rules extend automatically" weakens substrate-extension stop-signal. Thesis discipline: a 7th TypeConnective variant requires explicit C1 audit + named infer-rule receipt. Fix: §3.2 reframed. New TypeConnective variants do NOT extend automatically; require explicit C1 substrate-extension audit + named infer-rule receipt for the new variant's structural inference behavior. Per-variant structural facts means new variants need new per-variant facts, NOT silent inheritance. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3085 INLINE BLOCKING — AlgebraAxis + InferDiagnostic Practice 4 classification Cursor INLINE BLOCKING /api/reviews/12218 (line:112): proposed substrate coproducts (AlgebraAxis + InferDiagnostic) lack 🟢/🟡/🔴 classification + ledger/trigger per modeling-discipline Practice 4 (Coproduct dissolution). Fix: added 🟡 SCAFFOLD classification + named dissolution trigger for both: AlgebraAxis 🟡 SCAFFOLD: - Trigger: Step 2 brief enumerates full algebra-axiom set against infer.rs check sites + verifies coverage parity with live verification.dag:146 AlgebraicLawKind 3-variant subset → promote to 🟢 TERMINAL. InferDiagnostic 🟡 SCAFFOLD: - Trigger: Step 2 brief enumerates full variant set against parse_generated.rs / lower.rs / infer.rs diagnostic emission sites → promote to 🟢 TERMINAL. - Anti-bridge per Q6.5: does NOT collapse into CompilerDiagnosticKind without substrate-extension ratification per PR #3077 §12 Q7. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3077 INLINE BLOCKING — §5.1 SurfaceItem allocation correction Cursor INLINE BLOCKING /api/reviews/12251 line:130: §5.1 said "every SurfaceItem variant maps 1:1 to a Declaration placeholder" but live lower.rs:2950-2958 explicitly skips Let/Module/Import in collect_symbols. Verified via Read of lower.rs:2956-2958: SurfaceItem::Let { .. } => continue, SurfaceItem::Module { .. } => continue, SurfaceItem::Import { .. } => continue, Fix: §5.1 reframed — DeclarationAllocating variants (Fn / FnExternalBody / Data / TypeAtom / TypeRecord) map to placeholders; NonDeclarationAllocating variants (Let / Module / Import) skip allocation per live lower.rs behavior. Let-bodies lower to Bind expressions in Pass 2; Module/Import are parsed-facts preserved but un-declared. Earlier "every SurfaceItem variant" framing overstated; would have steered Step 2/3 worker into wrong allocation contract. Per INVARIANTS P1/P2 live-state honesty + facts-flow-forward. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3077 INLINE BLOCKING — ElaborationSpec scope broadened Cursor INLINE BLOCKING line:33: ElaborationSpec was defined only as Surface→Behavior recipe mapping, but lower constructs Declarations / TypeConnectives / BranchPatterns / Bindings as well. Non-Behavior lowering decisions outside declared authority violates THESIS substrate ownership + INVARIANTS P2. Fix: §3.2 ElaborationSpec scope broadened to ALL lowering decisions: 1. SurfaceItem → Declaration recipes (Fn / Data / Type variants + Let/Module/Import skip-allocation per §5.1) 2. SurfaceType → TypeConnective recipes (Atom / Arrow / Compose / Disj construction) 3. SurfaceExpr → Behavior recipes (Value / Transform / Branch / Loop / Bind construction) 4. SurfacePattern → BranchPattern recipes (ResolvedVariant / UnresolvedVariant / record-pattern construction) 5. Binding-site rules (Bind params + result_port construction) ElaborationSpec is single-authority across ALL axes; no axis lives in implementation-tier hand-Rust. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 APPROVE_WITH_COMMENTS — §7.1 ordering vs independence clarification Cursor APPROVE_WITH_COMMENTS /api/reviews/12265 line 197: §7.1 mixed two claims: - "parse migrates AFTER tokenize substrate-side stable" (ordering) - "PB-3 parse migration is independent of PB-2 tokenize migration status" (independence) Read as contradictory by reviewers. Need one coherent story. Fix: §7.1 reframed with two distinct axes explicit: 1. Substrate-stability ordering (SELF_HOSTING.md §2 bottom-up): tokenize Token carrier shape must be stable BEFORE parse migrates. Already true at HEAD (tokenize.dag:65-67 declares live carrier). ✓ 2. Migration-timing independence (parallel-dispatch axis): PB-3 parse migration ships in parallel with PB-2 residual-retirement work (SG-1a + character-level scaffold + codegen-driver retirement per PB-2 L2.5 §1). What parse needs is the stable Token CARRIER; PB-2's migration is about retiring residual hand-Rust, not changing the carrier. Both claims coherent on the axis split; not contradictory. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 INLINE BLOCKING — ParseDiagnostic SourceSpan structural requirement Cursor INLINE BLOCKING /api/reviews/12277 line:65: ParseDiagnostic variants like UnexpectedToken lacked SourceSpan field; List<ParseDiagnostic> cannot satisfy fail-closed source attribution structurally without span on every variant. INVARIANTS P2/P3 violation. Fix: every ParseDiagnostic variant now carries SourceSpan structurally: - UnexpectedToken: added span: SourceSpan - UnterminatedConstruct: opener_span: SourceSpan (already present) - InvalidLiteral: added span: SourceSpan - DuplicateRecordFieldLabel: added span: SourceSpan (current site) + prior_span: SourceSpan (prior site; both required) Per INVARIANTS P2/P3 fail-closed source attribution discipline: every diagnostic emission carries structural source-span provenance; not optional. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 INLINE BLOCKING — Token authority cite phantom-reference fix Cursor INLINE BLOCKING /api/reviews/12279 line:29: §3.1 cited `src/v3/compiler/src/tokenize.rs` as "current hand-Rust" for Token carrier — but `tokenize.rs` (without _generated suffix) doesn't exist. Live state has tokenize.dag (live substrate) + tokenize_generated.rs (codegen artifact). Per design-pure-bootstrap.md PB-2 lane: tokenize retire has substantially landed. The reference was an earlier-draft phantom from when Token-was-hand-Rust framing was the assumption. Fix: §3.1 reframed — Token type lives in LIVE src/v3/std/tokenize.dag:65-67 shared taxonomy; tokenizer implementation also live at src/v3/compiler/tokenize.dag (154 lines); codegen artifact at tokenize_generated.rs. tokenize.rs phantom reference removed explicitly. PB-2 substantially landed per design-pure-bootstrap.md; residual scaffold-retirement scope per PB-2 L2.5 PR #3127. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 INLINE BLOCKING — Step 2 pipeline-slot target fix (compiler.dag → pipeline.dag) Cursor INLINE BLOCKING /api/reviews/12281 line:138: §9 Step 2 referenced generic "compiler.dag" but dsl/gunbc/compiler.dag:24 explicitly directs internal pipeline (Tokenize → Parse → ...) to src/v3/compiler/pipeline.dag, NOT generic compiler.dag. Worker briefs authored against this doc would target the wrong file for pipeline-slot declaration. P2 single-authority violation. Fix: §9 Step 2 row in ALL 4 L2.5 docs (PB-2 / PB-3 / PB-4 / PB-5) updated: - "declared in compiler.dag" → "declared in src/v3/compiler/pipeline.dag (per dsl/gunbc/compiler.dag:24 — internal pipeline lives in pipeline.dag, NOT generic compiler.dag)" - substrate column: "compiler.dag refinement" → "pipeline.dag refinement" - §13 "Step 2 (pipeline-slot in compiler.dag)" → "pipeline-slot in src/v3/compiler/pipeline.dag" Same phantom-citation class as the tokenize.rs phantom (commit 8ae37b4): I cited generic file path without verifying which specific file is authoritative per project structure. Should have grep'd dsl/gunbc/compiler.dag header notes before authoring. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 INLINE BLOCKING — Step 3b/4 phasing P5 receipt unambiguity Cursor INLINE BLOCKING /api/reviews/12283 line:181: Q5 said Step 3b "full parser body .dag migration + parser body deletion in same PR", but §15 sequence schedules Step 4 parity/deletion AFTER Step 3b merges. P5 dissolution receipt ambiguous. If Step 3b lands .dag parser body BEFORE Step 4 deletes Rust parse() body, Rust + .dag parser bodies coexist temporarily — paper-shrink-relocation risk per feedback_paper_shrink_variants. Fix: 1. §9 Step 3b row reframed as "Step 3b/4 COMBINED" — atomic single PR (full .dag parser body + parity TestClaim + parse_generated.rs:138 deletion + census shrink). Cannot land .dag parser body before Rust deletion. 2. §12 Q5 phasing clarified: - Phase 3a (separate PR): grammar table extension; P5 receipt = ROADMAP deferral row naming Step 3b/4 as future-receipt - Phase 3b/4 COMBINED (single PR): atomic substrate substitution 3. §9 + §15 update notes: sequence collapses steps 12-17 into single dispatch+merge for combined phase Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3126 high-level BLOCKING findings 1 + 2 Codex high-level BLOCKING (sha 140eb6b) had 4 findings: - Findings 3 + 4 already addressed in PR #3138 commits 0159773 + a1607a8 - Findings 1 + 2 addressed in this commit **Finding 1 (Diagnostic kind/record conflated)**: §4.2 ParseDiagnostic was modeled as variants-directly with span + kind-fields mixed. Live Diagnostic at diagnostics.dag:150 uses record-wraps-kind pattern (`{ kind, span, message, correction }`). Need consistent shape. Fix: refactored to record-wraps-kind: - `type ParseDiagnostic { kind: ParseDiagnosticKind, span: SourceSpan }` - `type ParseDiagnosticKind = UnexpectedToken | UnterminatedConstruct | InvalidLiteral | DuplicateRecordFieldLabel | ...` Span lives on ParseDiagnostic record (single source of truth); variant-specific spans (opener_span / prior_span) remain on kind variants where meaningful. **Finding 2 (PB-2 §6 obsolete sibling-lane assumption)**: §6 line 198 said "PB-2 Tokenize | src/v3/std/tokenize.dag (NEW per PB-2 L2.5)" — but tokenize.dag is ALREADY LIVE per design-pure-bootstrap.md §"PB-2 — tokenize retire" (substantially landed). Fix: §6 prereq table row updated to reflect LIVE state. PB-2's residual scope is scaffold-retirement (SG-1a + character-level + codegen-driver per PB-2 L2.5 §1), not carrier authoring. PB-3 consumes the live Token carrier; carrier shape stable across PB-2 residual-retirement timing. Findings 3 + 4 already addressed: - Finding 3 (pipeline.dag target): commit 0159773 - Finding 4 (Step 3b/4 atomic vs sequential): commit a1607a8 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 APPROVE_WITH_COMMENTS — phantom "module-level metadata" removed Cursor APPROVE_WITH_COMMENTS line:79: §4.1 said "SurfaceModule (verified live) carries List<SurfaceItem> + module-level metadata" — but live parse_surface.dag:29 has ONLY `{ items: List<SurfaceItem> }`. No metadata fields. Phantom addition violated INVARIANTS P1 live-state honesty. Fix: §4.1 reframed to match live carrier exactly. Same phantom-addition class as tokenize.rs phantom (commit 8ae37b4). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3085 high-level BLOCKING findings — AtomPayload 5-variant + diagnostic-table PROPOSED Codex high-level BLOCKING (sha bf4d315) — 2 substantive findings: **Finding 1 (AtomPayload stale)**: §2 + §5 cited infer.rs:10 top-comment "Atom(Identifier { name, resolved })" — but live substrate.dag:87 has 5-variant AtomPayload sum: Literal | UnresolvedIdentifier | ResolvedByStructure | ResolvedByName | TypeParam. infer.rs top-comment is STALE vs live substrate. My doc inherited the drift. Fix: §2 enumeration corrected to all 5 AtomPayload variants per live substrate.dag:87. **Finding 2 (diagnostic-table PROPOSED, not live)**: §2 + §4.1 + §4.3 said "diagnostics.contains(port_id) biconditional" as if live — but Dag at substrate.dag:525 has ONLY { declarations, nodes, ports, clusters }. NO diagnostics field. Diagnostic-table is PROPOSED substrate extension. Fix: §2 fail-closed note flagged PROPOSED — Step 2 PR scope includes `diagnostics: Map<PortId, Diagnostic>` field extension to Dag, OR PB-Substrate prereq adds it before PB-5 dispatch. Same recurring feedback_grep_carrier_field_before_coupling_claim discipline (PR #3126 SurfaceModule analogous case); needed to grep type Dag fields BEFORE claiming the diagnostics field exists. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3085 INLINE BLOCKING line:94 — §4.1 + §4.3 PROPOSED diagnostic-table marking Cursor INLINE BLOCKING line:94: §4.1 + §4.3 said "diagnostics coupled INTO InferredDag" without flagging the diagnostic-table as a substrate extension. Live Dag at substrate.dag:525 has { declarations, nodes, ports, clusters } — NO diagnostics field. Earlier commit c0d96af added PROPOSED marking only in §2; §4.1 + §4.3 needed same treatment. Fix: §4.1 + §4.3 reframed with explicit PROPOSED substrate- extension marking + reference to §2 for extension scope. Construction-time invariant + structural coupling are both contingent on the substrate-extension landing (Step 2 PR scope or PB-Substrate prereq). Same recurring feedback_grep_carrier_field_before_coupling_claim discipline applied to §4.1 + §4.3 consistently with §2. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3077 high-level BLOCKING — Practice 4 classifications for PB-4 coproducts Codex high-level BLOCKING (sha b812db9): "Diagnostic substrate shape was repaired around anchoring but not re-audited as new substrate type declarations" — meaning DiagnosticAnchor + LowerDiagnostic + SurfaceFormRef + IdentifierRef need 🟢/🟡/🔴 classifications per modeling-discipline Practice 4 (Coproduct dissolution). Same pattern as PB-5 fix in commit 040681f (AlgebraAxis + InferDiagnostic) applied here. Fix: added classifications + dissolution triggers: - SurfaceFormRef 🟢 TERMINAL: closed-axis sum over live Surface* carriers; no further dissolution. - IdentifierRef 🟡 SCAFFOLD: dissolution trigger = Step 2 brief enumerates full identifier-kind set against lower.rs identifier-resolution sites; promote to 🟢 TERMINAL when SurfaceVarRef + TypePathRef + ModulePathRef cover actual axes. - LowerDiagnostic 🟡 SCAFFOLD: dissolution trigger = Step 2 brief enumerates variant set against lower.rs Diagnostic emission sites + Q6.5 anti-bridge preserved + PR #3077 §12 Q7 ratification path. - DiagnosticAnchor 🟢 TERMINAL: closed-axis covering all lowering-stage anchor kinds; no further dissolution. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3077 INLINE BLOCKING line:161 — DiagnosticSource Practice 4 classification Cursor inline finding adds DiagnosticSource to Practice 4 classification scope. Earlier commit aba79a1 classified SurfaceFormRef + IdentifierRef + LowerDiagnostic + DiagnosticAnchor but missed DiagnosticSource. Fix: DiagnosticSource 🟢 TERMINAL at pipeline-stage discrimination scope. Closed-axis sum (Parse | Lower | Infer | Emit); adding new pipeline stage requires explicit substrate- extension audit per Practice 4 + stop-signal discipline (same shape as PB-5 §3.2 TypeConnective stop-signal). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 INLINE BLOCKING line:151 — §11 SurfaceItem::Let + SurfaceLiteral span correction Cursor INLINE BLOCKING line:151: §11 claimed "every Surface variant carries SourceSpan" but live parse_surface.dag has: - SurfaceItem::Let { name, type_ann, expr } — no direct span - SurfaceLiteral = Int(String) | Bool(Bool) | String(String) — plain-tuple variants with no direct span Source-span provenance for these cases is via enclosing carrier: SurfaceLiteral wraps within `Literal { value, span }` at parse_surface.dag:150. Let-item inherits container span. INVARIANTS P2/P3 source provenance is structurally guaranteed via direct-OR-enclosing carrier, but my "every variant" overstatement obscured this. Fix: §11 corrected to "most Surface variants carry SourceSpan directly" + explicit Let + SurfaceLiteral exceptions noted + Step 2 PR scope audits whether exceptions are structural-honest (enclosing-carrier-provides-span) OR require substrate extension. Same recurring overstatement class as earlier "every SurfaceItem maps 1:1 to Declaration" (commit 61e2b67) — need to grep live substrate variant fields BEFORE claiming uniform shape. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * WIP: gunbc Director * docs(r3): cursor PR #3126 INLINE BLOCKING line:32 — GrammarSpec is concept, not carrier Earlier draft (now-merged PR #3126) framed `GrammarSpec` as a second declared `.dag` input type alongside `List<Token>`. Verified via grep that no `type GrammarSpec` exists anywhere under src/v3/ or dsl/ — the repo carries only `parse_tables.dag`'s 6 SG-2c table-families. Per cursor 2026-05-14T23:30:04Z inline finding, this violates INVARIANTS P2 (the Step-2 signature names a carrier the substrate doesn't declare). Reframed §3 (and downstream mentions in §3.2, §3 preamble line:33, §4.2 codex-correction recap line:165, §5.1 line:181, §12 Q6 line:344) so that: - Parse has ONE input at the API boundary: `List<Token>`. - "GrammarSpec" is a concept-level grouping for the 6 compile-time table-families in `parse_tables.dag`, not a substrate carrier and not a runtime parameter. - Step-2 signature stays `fn parse(tokens: List<Token>) -> Result<SurfaceModule, ParseDiagnostic>` per cfe842b (already applied in #3126); these edits remove the lingering "two input types" framing that contradicted that signature. Per Decision 3.B (b) compile-time parser tables: substrate authority is parse_tables.dag (6 table-families) consumed via direct table lookups inside the parser body — no runtime grammar value, no `GrammarSpec` carrier needed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3138 BLOCKING — §4.3 + §16 internal contradictions resolved Codex review id 12391 on sha cd6e8d1 flagged two live statements of the already-rejected typed-state-with-coupled-diagnostics model still sitting inside the parse L2.5, contradicting the corrected Result-sum framing in §4.2 and §6 Step 2: 1. §4.3 still proposed a `SurfaceModule { items, diagnostics }` extension modeled on PB-4/PB-5 patterns. Reframed: §4.3 now states explicitly that parse-stage uses Result-sum (no diagnostics field on SurfaceModule), restates the cross-stage discriminator (Result-sum for fail-fast output domains: parse + emit; typed-state for structural output domains: lower + infer), and cites `parse_generated.rs:138` as the live shape. 2. §16 "Memory disciplines applied" bullet read "feedback_state_space_vs_behavioral_invariants (typed-state SurfaceModule at output)". Rewritten to "parse output is `Result<SurfaceModule, ParseDiagnostic>` — the type rules out partial-parse states by construction; SurfaceModule itself carries no diagnostic field per §4.3". Per `feedback_discipline_change_audit_all_contract_mentions`: when a contract changes (here: SurfaceModule extension dropped in favor of Result-sum), all §-internal restatements must be swept in the same diff or they leak through as authoritative parallel claims. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3127 BLOCKING — drop TokenizedSource extension + cite concrete P5 receipts Codex review id 12370 on sha d15e1f2 raised two load-bearing planning-shape findings on the tokenize L2.5. Addressed in this fix-forward branch (PR #3138) since PR #3127 is still open but accumulating cycles. Finding 1 — parallel boundary carriers (INVARIANTS P2 / Modeling Practices 3+5): §4.3 + §9 Step 2 + §12 Q6 named `TokenizedSource { tokens, diagnostics }` as the output, while §2/§7.2/§7.3 named `List<Token>`. Same misclassification I just removed from the parse L2.5 in PR #3138 §4.3: tokenize sits in the fail-fast output domain alongside PB-3 parse + PB-6 emit (a partial token list with a corrupt token in the middle is not a valid downstream input for parse), so the failure couples via `Result`, not into the structural carrier. Resolution: - §4.3 rewritten to ratify `Result<List<Token>, TokenizeDiagnostic>` — the live `tokenize_generated.rs:96` shape — with no `TokenizedSource` extension. - §9 Step 2 row signature updated to match; explicit "single canonical boundary carrier: List<Token> on the Ok branch" framing. - §12 Q6 resolved REJECTED in-doc (no operator ratification needed; disposition follows from the cross-stage discriminator that's also load-bearing in PR #3138 parse L2.5). - §16 memory-disciplines bullets rewritten parallel to PR #3138 parse §16: Result-sum, no diagnostics field on `List<Token>`. - §14 "Surfaces awaiting" trimmed Q6 from the operator-ratification list. Finding 2 — soft deferral of `regen_tokenize` retirement (INVARIANTS P5): deferral previously named "PB-Bootstrap-Process lane scope" without a concrete ROADMAP.md row. Updated §9 Step 2 + Step 4 rows to cite the named receipts: - `docs/design-pure-bootstrap-zero.md:116` (PB-Bootstrap-Process lane: author bootstrap.dag + generated trampoline; sized M). - `docs/design-pure-bootstrap-zero.md:118-123` (N=0 runtime verification gates). - ROADMAP.md:467 (Character-level under-consumption in tokenize + syntax authorities — phase-2 char-class retype owns the codegen-driver path). - ROADMAP.md:416 (Class 5 Gap 3 — top-level `ValueBody` boundary; gating substrate-capability for the phase-2 retype). - ROADMAP.md:53 (T-PB-A — non-test census → 0 floor). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 BLOCKING line:119 — §6/§7.2/§15 Q7 sequencing resolved by PR #3077 merge Cursor inline BLOCKING at docs/design-parse-stage-l25-model.md:119 (sha at merge time of PR #3126) flagged a real internal contradiction: - §6 (lines 191, 207, 308) claimed "Step 2 (pipeline-slot declaration) is unblocked" - §7.2 (line 227) claimed "PR #3077 §12 Q7 must ratify before any Step 2 worker brief authoring" A worker reading the doc could land Step 2 (pipeline boundary) before the diagnostic carrier's P2/P3 failure shape was fixed. Resolution: PR #3077 (PB-4 lower L2.5) merged at 2026-05-15T00:21:19Z, carrying the §12 Q7 ratification of the Decision 2.B per-stage diagnostic extension path. The gate IS now satisfied at HEAD, so the resolution is fact-update (annotate Q7 as DONE with the merge timestamp) rather than retracting either §6 or §7.2. Edits: - §15 step 4: annotated "DONE 2026-05-15T00:21:19Z when PR #3077 merged" and added the explicit "Step 2 is now genuinely unblocked, not just procedurally next" framing so workers reading the sequence don't bypass the gate. - §7.2 line 227: rewritten from "Q7 must ratify before Step 2 brief authoring" (future tense, the contradiction surface) to "Gate satisfied 2026-05-15T00:21:19Z when PR #3077 merged; Step 2 worker brief authoring is unblocked at HEAD per §15 step 4." Cites the cursor finding as the resolution path. §6 unblocking statements stay as-is — they were correct at HEAD; the contradiction lived in §7.2's pre-merge framing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3126 BLOCKING (sha 16d21f4) — Q7 cited at every Step 2 unblocking claim Codex BLOCKING finding 2 (sha 16d21f4, 216s thinking): the Q7 dependency was recorded in §7.2/§15 but not in the other Step-2-unblocking sites at §6 lines 191, 207, 308 — risking a worker reading "Step 2 unblocked" without also reading the Q7 prerequisite. Codex framing: "make Q7 a hard precondition wherever Step 2 is called unblocked, or split Step 2 into pre-Q7 and post-Q7 scopes with separate receipts." Chose the first option since PR #3077 has already merged (2026-05-15T00:21:19Z) and splitting into pre/post-Q7 scopes is no longer load-bearing. Annotated all three §6 sites: - Line 191 (Implication for PB-3 migration): cites gate + merge timestamp + explicit "must NOT be brief-authored before that merge timestamp." - Line 207 (Critical observation): cites the Step 2 gate as PR #3077 §12 Q7 + merge timestamp + P3 failure-shape consequence if violated. - Line 308 (Director-recommend phase list): cites gate + §7.2/§15 step 4 cross-refs + merge timestamp. Codex BLOCKING finding 1 (GrammarSpec carrier non-existence) verified already resolved at HEAD via commit c97dc15 — every GrammarSpec mention now explicitly marks it as a concept-not-carrier; Step 2 signature is `fn parse(tokens: List<Token>) -> Result<SurfaceModule, ParseDiagnostic>` with no GrammarSpec parameter. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): openai-pro PR #3126 BLOCKING (sha 16d21f4) — Step 3b/4 atomicity + Q1 ratification-pending status openai-pro REQUEST_CHANGES on PR #3126 sha 16d21f4 flagged three findings. Findings 1 + 2 (signature vs realization mismatch under LAYER MODEL + P2/P3 boundary discipline) were already resolved at HEAD by earlier fix-forward commits — Step 2 signature is now `fn parse(tokens: List<Token>) -> Result<SurfaceModule, ParseDiagnostic>` matching live `parse_generated.rs:138` with no GrammarSpec parameter and no diagnostics-coupled SurfaceModule extension (§4.3 Result-sum disposition). Finding 6 (TRACKED vs UNTRACKED DEBT — Step 3b/4 same-PR vs two-PR): §9 had both a "Step 3b/4 COMBINED" row (line 250) and a leftover separate "Step 4: Parity test" row (line 251) — internally contradictory. §15 also still sequenced Steps 3b + 4 as four separate authoring/dispatch/ratify beats (steps 12-17), contradicting §12 Q5's "same PR" decision and the explicit "Update to §15" note at §12 line 325. Resolution: collapsed §9 to one COMBINED row absorbing the parity-TestClaim mechanics + P5 dissolution receipt from the deleted Step 4 row; collapsed §15 steps 12-17 into single COMBINED authoring + dispatch + ratify (steps 12-14). Added explicit `feedback_paper_shrink_variants` reasoning in both sections. Finding 2.5 (PM intent — substrate-capability bundled vs separate): §12 Q1 line 288 said "Director-recommend: (b) bundled" while §13 line 340 listed substrate-capability as a non-goal of PB-3 and §15 step 11 had "WAIT for substrate-capability landing" — three sections, two different execution paths. Resolution: annotated Q1 as "PENDING operator/PM ratification" with explicit default-execution clause: until operator ratifies, the doc treats substrate-capability as path (a) separate lane (matching §13 + §15 + §9 row). If/when ratified to (b), §13 drops the non-goal and §15 step 11 collapses into the COMBINED Step 3b/4 brief. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3126 BLOCKING (sha 5619afa) — parse_tables.dag as single enumerated authority Codex caught me copying the prose summary at parse_tables.dag:23-29 (which enumerates only SG-2c-numbered families) instead of grepping the live `^type [A-Z]` declarations. Result: SoftKeywordIdentRow (line 334) was missing from §3.2 / §5.1 / §6 / §12 because it lacks an SG-2c-N number in the prose summary. Per `feedback_parallel_representation_debt`: structural fix is to stop hand-enumerating in the doc — cite parse_tables.dag itself as the single enumerated authority and use `type`-declaration line-anchors for the worked example, not a hand-maintained count. Edits: - §3.2 §"Live substrate authority": replaced the SG-2c-numbered bullet list with `type`-declaration line-anchor enumeration including SoftKeywordIdentRow at parse_tables.dag:334 + the supporting enum BinaryOpLevel at line 133. Added codex-finding callout explaining the miss + the discipline shift. - §3 preamble line:33, §3.2 line:45 callout, §3.2 line:57 framing, §3.2 §"Substrate authority" line:71, §5.1 line:171-180, §12 Q2 line:298, §12 Q6 line:334: all hardcoded "6 table-families" counts dropped; doc now points readers to §3.2 enumeration / `parse_tables.dag` directly. - §5.1 sub-enumeration list (the parallel 6-item list at lines 173-178) deleted; replaced with redirect to §3.2 + restated 3a-vs-3b/4 scope split. Code-level check before commit: `grep -nE '^type [A-Z]' src/v3/compiler/parse_tables.dag` returns 7 types: BinaryOpLevel (133), BinaryOpRow (167), TopLevelItemKwRow (289), SoftKeywordIdentRow (334), BracketRow (385), PrimaryPrefixRow (449), PrimaryAtomRow (486). Doc enumeration matches. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3138 BLOCKING (sha f08b952) — bind TokenizeDiagnostic to live CharClass authority Codex Finding 1 (sha f08b952, 216s thinking): the §4.2 TokenizeDiagnostic draft and the §5.1/§5.2 headings used `ScannerCharClass` / `ScannerClassRef` — names that exist only as the *generated Rust enum spelling*, not as a declared .dag substrate type. Verified via grep: grep -rn '^type CharClass\|^type ScannerC' dsl/ src/v3/ returns ONE authority: `dsl/std/unicode.dag:62` type CharClass = Whitespace | Digit | IdentStart | IdentContinue consumed at `src/v3/compiler/tokenize.dag:103` data ascii_scan_order: List<CharClass> = [Whitespace, Digit, IdentStart, IdentContinue] There is no `ScannerCharClass` declaration anywhere — that name was copied from generated Rust without grep-verification, the same failure mode as `feedback_grep_substrate_before_naming_ratification` (carrier-name collision discipline). Resolution: - §4.2 TokenizeDiagnostic carrier: `expected_class: ScannerClassRef` → `expected_class: CharClass`, dropped the `type ScannerClassRef = ScannerCharClass` alias entirely; added a codex-finding callout citing the substrate authority + naming the failure mode. - §5.1 heading "Byte → ScannerCharClass dispatch" → "Byte → CharClass dispatch"; bullets unchanged; added line-anchor cites for the substrate authority + explicit "NOT ScannerCharClass" disclaimer. - §5.2 heading "ScannerCharClass → token-recognition state machine" → "CharClass → token-recognition state machine". Finding 2 (TokenizedSource not reconciled with parse input contract): no new fix required — already resolved by commit 6adb992 (TokenizedSource extension dropped entirely; tokenize uses Result<List<Token>, TokenizeDiagnostic>; List<Token> is the single canonical boundary carrier consumed by parse). Codex was reviewing sha f08b952, which predated the TokenizedSource drop. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3138 INLINE BLOCKING line:188 — clarify §7.3 chain is Ok-branch propagation Cursor INLINE at sha f08b952 worried that §7.3's cross-stage chain "tokenize → List<Token> → parse → ..." was inconsistent with §4.3's TokenizedSource carrier (diagnostics not flowing forward). At HEAD the TokenizedSource extension is dropped (commit 6adb992); tokenize uses Result<List<Token>, TokenizeDiagnostic>, so List<Token> IS the canonical Ok-branch payload that flows forward and Err branches terminate the pipeline fail-fast. To make this explicit at §7.3 (instead of leaving readers to infer it from §4.3), annotated the chain with: - "Ok-branch propagation; Err branches are stage-terminal fail-fast per §4.3 Result-sum discriminator" framing prefix. - Per-stage Result/typed-state annotations: tokenize/parse show Result<Ok, Err>; lower/infer show typed-state structural-output; emit shows Result<EmittedArtifact, EmissionDiagnostic>. - Explicit "on any stage's Err branch the pipeline aborts at that stage (no partial-output propagation across boundaries)" trailer. This makes the chain self-consistent vis-a-vis §4.3 without requiring the reader to walk back-and-forth, and prevents future readers from re-introducing a TokenizedSource-shaped extension to "make diagnostics flow forward" — they already do, just via the Err branch terminating the pipeline. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): openai-pro PR #3127 BLOCKING (sha d15e1f2) — character-level scaffold dissolution trigger openai-pro REQUEST_CHANGES on sha d15e1f2: §1 line:26 character-level under-consumption scaffold named the problem but lacked a checkable dissolution trigger. SG-1a scaffold above had the right shape — "once those bodies lower structurally under compile_to_dag, delete the raw-text extractor + derive directly from lowered Dag in same PR." Character-level scaffold just said "PB-2 Step 4 carries this scope" — a lane assignment, not a trigger. Resolution: rewrote §1 item 2 with the same SG-1a-shape trigger structure: - Substrate-consumption condition (a): scanner classes / string escape / local punctuation retype to `dsl/std/unicode.dag` `CharClass` / `char_in_class` (concrete field retypes named: `StringEscapeSpec.suffix: Char`, `LocalPunctSpec.pattern: List<Char>`, `string_literal_delimiter: Char`). - Codegen-driver condition (b): `tokenize_generated.rs` no longer emits hidden `byte.is_ascii_*` predicates because the driver reads class facts structurally from lowered `tokenize.dag`. - Same-PR dissolution: delete the parallel character-predicate scaffold in the same PR that flips substrate consumption — no Rust-and-`.dag` coexistence per `feedback_paper_shrink_variants`. - Cross-ref to §9 Step 4 gating prereqs: ROADMAP.md:467 + ROADMAP.md:416 Class 5 Gap 3 + std.unicode bootstrap/load-set decision (already cited in §9 from earlier commit 6adb992). Per openai-pro's framing: "small fix — mirror the SG-1a scaffold wording by naming the exact substrate-consumption condition and same-PR deletion receipt for the hidden Rust character predicates." Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * WIP: gunbc Director * docs(r3): cursor PR #3127 APPROVE_WITH_COMMENTS — §14 + §15 Q6-already-rejected sweep Cursor review id 12405 (APPROVE_WITH_COMMENTS) caught the same `feedback_discipline_change_audit_all_contract_mentions` failure mode recurring: §12 Q6 was resolved REJECTED in commit 6adb992, and §14 "Surfaces awaiting" + §12 Q6 heading + §9 Step 2 row were updated, but two §-internal contract restatements were missed: - §14 acceptance criterion 11: "Operator/PM ratification on §12 Q1-Q6" - §15 step 1: "Operator / PM-delegate ratifies §12 Q1-Q6" Both contradicted §12 Q6 + §14 "Surfaces awaiting" (which already said "Q1-Q5 only"). A worker reading §14/§15 could schedule sign-offs on Q6 after it was already resolved-rejected elsewhere. Resolution: both sites now say "Q1–Q5" with the explicit Q6-rejected crossref + "see §14/§15 for same scoping" pointer at the §14 criterion so the three sections agree internally. Cursor verdict was APPROVE_WITH_COMMENTS (substantive APPROVE — "fix the checklist/sequence so every section agrees Q6 is closed"); the exploratory volatile-line-anchor note is harmless and out-of-scope for this PR. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3138 BLOCKING (sha 887c696) — 3 findings swept across 3 L2.5 docs Codex review id (sha 887c696, 333s thinking) flagged three findings, all `feedback_discipline_change_audit_all_contract_mentions` recurrences where partial sweeps left §-internal contradictions. Finding 1 — infer doc cross-stage trigger leak: §4.2 InferDiagnostic dissolution trigger said "when Step 2 worker brief enumerates the full variant set against `parse_generated.rs` Diagnostic::ParseError, lower.rs Diagnostic construction sites, and infer.rs Dag::mark_unresolved emission sites." That cross-stage trigger surface is wrong for the infer-specific scaffold. Narrowed to infer-only: "against `src/v3/compiler/src/infer.rs` Diagnostic construction sites + `Dag::mark_unresolved` emission sites (infer-stage only)." Parse and lower have their own per-stage carriers + own Q7 mapping; this doc no longer reaches into their dissolution-trigger surface. Finding 2 — parse + tokenize coproduct receipts: `ParseDiagnosticKind` (parse §4.2) and `TokenizeDiagnostic` (tokenize §4.2) sums were declared without the 🟡 SCAFFOLD / 🟢 TERMINAL classification + dissolution trigger that the infer doc carries (per modeling-discipline Practice 4 + `feedback_coproduct_dissolution`). Added matching scaffold receipts to both: 🟡 SCAFFOLD at PROPOSED stage with stage-local dissolution trigger (Step 2 brief enumerates against parse_generated.rs / tokenize_generated.rs Diagnostic::* construction sites — stage-only, not cross-stage); promote to 🟢 TERMINAL when full variant set lands. Both also carry the anti-bridge note per Q6.5. Finding 3 — tokenize Q7 reconciliation: The parse doc has the "Q7 DONE 2026-05-15T00:21:19Z" annotation at §15 step 4 (commit f85fa1f) but the tokenize doc still framed Q7 as a pending lane dependency at §4.2 line:113 ("Lane dependency"), §15 step 3, and §14 "Surfaces awaiting". Annotated all three: - §4.2 "Lane dependency": Q7 DONE timestamp + "TokenizeDiagnostic per-stage variant authoring is the remaining lane work." - §15 step 3: full DONE annotation matching parse doc §15 step 4 shape + cross-ref to the parse doc. - §14 "Surfaces awaiting": strikethrough + DONE annotation. PR #3127 also carries the tokenize doc; same edits will port there in a companion commit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3138 INLINE BLOCKING line:372 — §16 Surfaces awaiting Q7 contradiction Cursor inline at sha 887c696 caught the symmetric finding to the codex 5-finding BLOCKING #3: parse-doc §15 step 4 already annotated Q7 as DONE (commit f85fa1f) but parse-doc §16 "Surfaces awaiting" still listed Q7 as pending. Same `feedback_discipline_change_audit_all_contract_mentions` sweep failure — the tokenize doc had three sites carrying the pending framing (commit e9739ea fixed those) but the parse doc's §16 site was missed in the original Q7-DONE sweep. Resolution: §16 bullet now strikes through + "DONE 2026-05-15T00:21:19Z (PR #3077 merged carrying Q7 ratification; see §15 step 4)" — same shape as the tokenize doc's §14 "Surfaces awaiting" Q7-DONE annotation landed in e9739ea. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…+ cursor inlines (#3141) * docs(r3): PB-2 tokenize pipeline-stage L2.5 domain model — DRAFT for ratification Director-tier L2.5 model for PB-2 tokenize per operator 2026-05-14 ratification (Decision 1.A scoping = Option A). PB-2 is the FURTHEST-ALONG pipeline stage — substrate authority already lives in `.dag`: - src/v3/std/tokenize.dag (Token + TokenKind taxonomy; LIVE 143 lines) - src/v3/compiler/tokenize.dag (tokenizer implementation; LIVE 154 lines) - src/v3/compiler/src/tokenize_generated.rs (AUTO-GENERATED; 362 lines) This is the END STATE that all other pipeline-stage migrations target. PB-2 L2.5 is correspondingly lighter — mostly verification + residual hand-Rust retirement, NOT new substrate authoring. Distinct §9 4-step framing: - Step 3 = VERIFY substrate completeness (audit per feedback_paper_shrink_variants) - Step 4 = HANDOFF/RETIRE residual hand-Rust scaffolding (coordinates with PB-Bootstrap-Process lane for codegen-driver retirement) Captures audit dimensions explicitly: - scanner-class definitions = declarative byte-pattern membership - recognition tables = closed-axis enums - state machine = structural transitions - no V2 `pub mod tokenize` absorption check §12 Q1: codegen-driver retirement scope — Director-recommend PB-Bootstrap-Process handles all codegen-driver retirement cross-cuttingly (not per-stage paper-shrink risk). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): §12.6 citation fix — tokenize is PB-2 lane scope per design-pure-bootstrap-zero.md Per cursor PR #3085 finding: §12.6 explicitly tables only 4 pipeline-stage migrations (emit→lower→infer→parse); tokenize is per design-pure-bootstrap-zero.md PB-2 lane. Same fix as PR #3085 commit 89fbd7a2a applied here. INVARIANTS P1 — documentation must not overstate authority cites. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): preemptive fix for PR #3126 codex BLOCKING propagation — PB-2 live state honesty Same class as codex INLINE BLOCKING #3126 finding 1 (live state honesty for diagnostic coupling) applied preemptively to PB-2 tokenize L2.5. PB-2 §4.3 had "diagnostics coupled INTO List<Token>" framing which would overstate the live carrier shape (bare List<Token> has no diagnostic field; tokenize_generated.rs:96 today returns Result<Vec<Token>, Diagnostic>). Fix: §4.3 reframed with PROPOSED substrate extension explicit — new `TokenizedSource { tokens, diagnostics }` wrapper carrier as the typed-state output. Step 2 brief includes wrapper authoring in pipeline-slot PR scope. Same discipline as PR #3126 commit bdff8c500. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3077 — fix PB-2 lane citation (design-pure-bootstrap.md not -zero.md) Per cursor APPROVE_WITH_COMMENTS /api/reviews/12087: PB-2 lane is defined in docs/design-pure-bootstrap.md §"PB-2 — tokenize retire" (line ~134), NOT docs/design-pure-bootstrap-zero.md. The -zero.md doc has Subsumed-lanes list with PB-1/PB-4/PB-5/PB-6 but NOT PB-2. Propagated fix applies same cite-error correction as PR #3066 §1.8 discipline: cite the actual doc, not an adjacent doc with similar name. INVARIANTS P2 single-authority-citation. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): fix cursor PR #3127 BLOCKING contradictions + add §12 Q6 Cursor APPROVE_WITH_COMMENTS (/api/reviews/12093) caught two substantive contradictions I introduced when adding TokenizedSource in commit 2b9756bb5: 1. §4.3 vs §9 Step 2 signature mismatch — §4.3 said `-> TokenizedSource` but §9 Step 2 row still said `-> List<Token>`. Same `feedback_discipline_change_audit_all_contract_mentions` issue that's recurred 4x this session. 2. §4.3 referenced "§12 Q-new" but §12 only had Q1-Q5; broken anchor. Fix: 1. §9 Step 2 row updated: signature `-> TokenizedSource` with wrapper carrier shape `{ tokens, diagnostics }` per §4.3 2. §4.3 anchor updated: "§12 Q6" (resolved) 3. Added §12 Q6: TokenizedSource carrier shape ratification — (a) wrapper record vs (b) per-Token diagnostic coupling; Director-recommend (a) for PB-3 SurfaceModule parallelism 4. §14 + §15 + §16 Q-list refs updated to Q1-Q6 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): fix codex BLOCKING PR #3127 — Token shape + Q4 audit boundary Codex REQUEST_CHANGES (sha b881de23) with 2 substantive findings: 1. §4.1 Token shape claim "optional lexeme: String" — wrong per live substrate at src/v3/std/tokenize.dag:65-67. Live Token has 2 fields only (kind + span); lexeme-content lives ON the TokenKind variants (Ident(String) / IntLit(String) / etc.). Fix: corrected §4.1 to reflect live carrier shape; payloads on TokenKind variants noted explicitly. 2. §12 Q4 substrate-completeness audit scoped only to tokenize_generated.rs — missed the regen_tokenize codegen- driver boundary. If regen_tokenize carries scanner-logic decisions (rather than mechanical template-rendering of substrate facts), the substrate isn't complete — the driver IS hand-Rust scanner logic in disguise. Fix: Q4 audit extended with (d) regen_tokenize codegen- driver logic audit + (e) ROADMAP.md deferral row option per feedback_paper_shrink_variants P5 receipt discipline. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): fix codex BLOCKING PR #3127 — TokenizeDiagnostic PROPOSED + scaffold disclosure Codex REQUEST_CHANGES (sha b881de23, full body) caught 2 substantive overstatements: 1. §2 line 46 claimed "tokenize failures produce typed TokenizeDiagnostic variants" — but live tokenize_generated.rs:96 returns generic `Result<Vec<Token>, Diagnostic>` with `Diagnostic::TokenizerError { message, span, correction }`. Typed TokenizeDiagnostic is a PROPOSED extension, not live state. Fix: §2 reframed with live state explicit + TokenizeDiagnostic marked PROPOSED per PR #3077 §12 Q7 ratification path. 2. §1 line 22 + §6 + §9 Step 2 line 198 framed PB-2 as "mostly verification" — but live tokenize.dag:16-30+ has TWO explicit tracked scaffold zones: - SG-1a: regen_tokenize parses raw source text for dag_keyword_set / dag_operators (ValueBody::Unparsed) - Character-level under-consumption: StringEscapeSpec / LocalPunctSpec.pattern / string_literal_delimiter as opaque Strings; hidden Rust character predicates (byte.is_ascii_digit etc.) at tokenize_generated.rs:15-22 leaking through codegen Residual hand-Rust is NOT just the codegen artifact — it includes (a) regen_tokenize logic, (b) SG-1a raw-text-extractor scaffold, (c) character-predicate scaffold leaking through codegen. Fix: §1 + §6 + §9 Step 2 reframed honestly. PB-2 is "FURTHER ALONG but not complete"; Step 4 carries scaffold-retirement scope, not just codegen-artifact retirement. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): post-merge fix-forward — §16 + §9 Step 2 internal contradictions Two post-merge doc-internal contradictions caught by reviewers after operator merged PR #3077 / #3126 / #3085 at 2026-05-15T00:21Z. **PR #3077 PB-4 lower §16 fix**: §16 "Memory disciplines applied" bullet said "diagnostics coupled INTO PreInferDag via biconditional" — but §4.3 (per openai-pro DiagnosticAnchor fix commit b812db91b) constrains biconditional to PortAnchor-only. Other anchor kinds (DeclarationAnchor / RecordFieldAnchor / SurfaceFormAnchor) couple without port-state. Fix: §16 bullet honors §4.3 anchor-typed framing. **PR #3126 PB-3 parse §9 Step 2 fix**: §9 Step 2 row described diagnostics as "coupled INTO SurfaceModule" as if live — §4.3 correctly marks it PROPOSED. Same feedback_discipline_change_audit_all_contract_mentions pattern that's recurred this session. Fix: §9 Step 2 row clarified — "PROPOSED extension per §4.3"; Step 2 PR scope includes authoring the diagnostics field extension, NOT a live coupling. Per feedback_discipline_change_audit_all_contract_mentions: when a substantive fix changes a discipline framing, audit ALL sections (framing + contract + handoff). Post-merge audit surfaced these residual contradictions. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): post-merge fix-forward — PR #3126 codex BLOCKING (GrammarSpec parallel-authority + fail-closed weakening) Codex REQUEST_CHANGES on already-merged PR #3126 (/api/reviews/12175): 2 substantive findings on the post-merge doc. **Finding 1 (P2 violation — GrammarSpec parallel authority)**: §3.2 says GrammarSpec is compile-time-only, NOT runtime- interpreted (per Decision 3.B (b) operator override). But the proposed stage contract still took `grammar: GrammarSpec` as runtime input. Creates two authorities (compiled parser tables + runtime GrammarSpec value). Fix: §4.3 signature reframed to `fn parse(tokens: List<Token>) -> Result<SurfaceModule, ParseDiagnostic>` — NO runtime GrammarSpec input. Compile-time generated parser tables consumed via internal dispatch. Step 2 + Step 4 rows updated. **Finding 2 (P3 + Practices 1/2 — fail-closed weakening)**: Live parser at parse_generated.rs:138 returns `Result<SurfaceModule, Diagnostic>` (fail-closed; aborts on first error). Earlier draft proposed `SurfaceModule` with embedded diagnostics — would let partial-parse states be constructible + let downstream observe "success" output after parse failure. Violation of fail-closed discipline. Fix: signature preserves Result-sum (matches live + emit's pattern). Distinguished cross-stage: - Result-sum (parse + emit): fail-fast output domain - Typed-state-with-coupled-diagnostics (lower + infer): structural output domain where partial-failure IS valid intermediate Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 post-merge APPROVE_WITH_COMMENTS — §4.1 + §16 fail-closed honesty Cursor caught 2 more post-merge contradictions on PR #3126: 1. §4.1 line 81 "construction-time invariant" talks about "ParseDiagnostic in the diagnostic stream" tied to SurfaceModule path — but §5.2 + live parse_generated.rs:138 use Result<SurfaceModule, Diagnostic>. §4.1 reads as claim about today's plumbing. Fix: §4.1 reframed — live boundary explicit (Result-sum); construction-time invariant scoped to Ok-arm SurfaceModule + Err-arm ParseDiagnostic, no partial-parse with embedded diagnostics. 2. §16 line 397 cites C-8 as "ParseDiagnostic coupled INTO SurfaceModule" without qualifier — but §4.3 (post codex REQUEST_CHANGES fix) constrains to Result-sum. Fix: §16 bullet honors §4.3 Result-sum framing; cross-stage discriminator named. Same recurring feedback_discipline_change_audit_all_contract_mentions pattern — substantive fix to §4.3 + §9 Step 2 left §4.1 + §16 inconsistent. Post-merge audit catches. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3085 INLINE BLOCKING — TypeConnective extension stop-signal Cursor INLINE BLOCKING caught §3.2 line 66 "rules extend automatically" weakens substrate-extension stop-signal. Thesis discipline: a 7th TypeConnective variant requires explicit C1 audit + named infer-rule receipt. Fix: §3.2 reframed. New TypeConnective variants do NOT extend automatically; require explicit C1 substrate-extension audit + named infer-rule receipt for the new variant's structural inference behavior. Per-variant structural facts means new variants need new per-variant facts, NOT silent inheritance. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3085 INLINE BLOCKING — AlgebraAxis + InferDiagnostic Practice 4 classification Cursor INLINE BLOCKING /api/reviews/12218 (line:112): proposed substrate coproducts (AlgebraAxis + InferDiagnostic) lack 🟢/🟡/🔴 classification + ledger/trigger per modeling-discipline Practice 4 (Coproduct dissolution). Fix: added 🟡 SCAFFOLD classification + named dissolution trigger for both: AlgebraAxis 🟡 SCAFFOLD: - Trigger: Step 2 brief enumerates full algebra-axiom set against infer.rs check sites + verifies coverage parity with live verification.dag:146 AlgebraicLawKind 3-variant subset → promote to 🟢 TERMINAL. InferDiagnostic 🟡 SCAFFOLD: - Trigger: Step 2 brief enumerates full variant set against parse_generated.rs / lower.rs / infer.rs diagnostic emission sites → promote to 🟢 TERMINAL. - Anti-bridge per Q6.5: does NOT collapse into CompilerDiagnosticKind without substrate-extension ratification per PR #3077 §12 Q7. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3077 INLINE BLOCKING — §5.1 SurfaceItem allocation correction Cursor INLINE BLOCKING /api/reviews/12251 line:130: §5.1 said "every SurfaceItem variant maps 1:1 to a Declaration placeholder" but live lower.rs:2950-2958 explicitly skips Let/Module/Import in collect_symbols. Verified via Read of lower.rs:2956-2958: SurfaceItem::Let { .. } => continue, SurfaceItem::Module { .. } => continue, SurfaceItem::Import { .. } => continue, Fix: §5.1 reframed — DeclarationAllocating variants (Fn / FnExternalBody / Data / TypeAtom / TypeRecord) map to placeholders; NonDeclarationAllocating variants (Let / Module / Import) skip allocation per live lower.rs behavior. Let-bodies lower to Bind expressions in Pass 2; Module/Import are parsed-facts preserved but un-declared. Earlier "every SurfaceItem variant" framing overstated; would have steered Step 2/3 worker into wrong allocation contract. Per INVARIANTS P1/P2 live-state honesty + facts-flow-forward. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3077 INLINE BLOCKING — ElaborationSpec scope broadened Cursor INLINE BLOCKING line:33: ElaborationSpec was defined only as Surface→Behavior recipe mapping, but lower constructs Declarations / TypeConnectives / BranchPatterns / Bindings as well. Non-Behavior lowering decisions outside declared authority violates THESIS substrate ownership + INVARIANTS P2. Fix: §3.2 ElaborationSpec scope broadened to ALL lowering decisions: 1. SurfaceItem → Declaration recipes (Fn / Data / Type variants + Let/Module/Import skip-allocation per §5.1) 2. SurfaceType → TypeConnective recipes (Atom / Arrow / Compose / Disj construction) 3. SurfaceExpr → Behavior recipes (Value / Transform / Branch / Loop / Bind construction) 4. SurfacePattern → BranchPattern recipes (ResolvedVariant / UnresolvedVariant / record-pattern construction) 5. Binding-site rules (Bind params + result_port construction) ElaborationSpec is single-authority across ALL axes; no axis lives in implementation-tier hand-Rust. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 APPROVE_WITH_COMMENTS — §7.1 ordering vs independence clarification Cursor APPROVE_WITH_COMMENTS /api/reviews/12265 line 197: §7.1 mixed two claims: - "parse migrates AFTER tokenize substrate-side stable" (ordering) - "PB-3 parse migration is independent of PB-2 tokenize migration status" (independence) Read as contradictory by reviewers. Need one coherent story. Fix: §7.1 reframed with two distinct axes explicit: 1. Substrate-stability ordering (SELF_HOSTING.md §2 bottom-up): tokenize Token carrier shape must be stable BEFORE parse migrates. Already true at HEAD (tokenize.dag:65-67 declares live carrier). ✓ 2. Migration-timing independence (parallel-dispatch axis): PB-3 parse migration ships in parallel with PB-2 residual-retirement work (SG-1a + character-level scaffold + codegen-driver retirement per PB-2 L2.5 §1). What parse needs is the stable Token CARRIER; PB-2's migration is about retiring residual hand-Rust, not changing the carrier. Both claims coherent on the axis split; not contradictory. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 INLINE BLOCKING — ParseDiagnostic SourceSpan structural requirement Cursor INLINE BLOCKING /api/reviews/12277 line:65: ParseDiagnostic variants like UnexpectedToken lacked SourceSpan field; List<ParseDiagnostic> cannot satisfy fail-closed source attribution structurally without span on every variant. INVARIANTS P2/P3 violation. Fix: every ParseDiagnostic variant now carries SourceSpan structurally: - UnexpectedToken: added span: SourceSpan - UnterminatedConstruct: opener_span: SourceSpan (already present) - InvalidLiteral: added span: SourceSpan - DuplicateRecordFieldLabel: added span: SourceSpan (current site) + prior_span: SourceSpan (prior site; both required) Per INVARIANTS P2/P3 fail-closed source attribution discipline: every diagnostic emission carries structural source-span provenance; not optional. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 INLINE BLOCKING — Token authority cite phantom-reference fix Cursor INLINE BLOCKING /api/reviews/12279 line:29: §3.1 cited `src/v3/compiler/src/tokenize.rs` as "current hand-Rust" for Token carrier — but `tokenize.rs` (without _generated suffix) doesn't exist. Live state has tokenize.dag (live substrate) + tokenize_generated.rs (codegen artifact). Per design-pure-bootstrap.md PB-2 lane: tokenize retire has substantially landed. The reference was an earlier-draft phantom from when Token-was-hand-Rust framing was the assumption. Fix: §3.1 reframed — Token type lives in LIVE src/v3/std/tokenize.dag:65-67 shared taxonomy; tokenizer implementation also live at src/v3/compiler/tokenize.dag (154 lines); codegen artifact at tokenize_generated.rs. tokenize.rs phantom reference removed explicitly. PB-2 substantially landed per design-pure-bootstrap.md; residual scaffold-retirement scope per PB-2 L2.5 PR #3127. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 INLINE BLOCKING — Step 2 pipeline-slot target fix (compiler.dag → pipeline.dag) Cursor INLINE BLOCKING /api/reviews/12281 line:138: §9 Step 2 referenced generic "compiler.dag" but dsl/gunbc/compiler.dag:24 explicitly directs internal pipeline (Tokenize → Parse → ...) to src/v3/compiler/pipeline.dag, NOT generic compiler.dag. Worker briefs authored against this doc would target the wrong file for pipeline-slot declaration. P2 single-authority violation. Fix: §9 Step 2 row in ALL 4 L2.5 docs (PB-2 / PB-3 / PB-4 / PB-5) updated: - "declared in compiler.dag" → "declared in src/v3/compiler/pipeline.dag (per dsl/gunbc/compiler.dag:24 — internal pipeline lives in pipeline.dag, NOT generic compiler.dag)" - substrate column: "compiler.dag refinement" → "pipeline.dag refinement" - §13 "Step 2 (pipeline-slot in compiler.dag)" → "pipeline-slot in src/v3/compiler/pipeline.dag" Same phantom-citation class as the tokenize.rs phantom (commit 8ae37b4a5): I cited generic file path without verifying which specific file is authoritative per project structure. Should have grep'd dsl/gunbc/compiler.dag header notes before authoring. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 INLINE BLOCKING — Step 3b/4 phasing P5 receipt unambiguity Cursor INLINE BLOCKING /api/reviews/12283 line:181: Q5 said Step 3b "full parser body .dag migration + parser body deletion in same PR", but §15 sequence schedules Step 4 parity/deletion AFTER Step 3b merges. P5 dissolution receipt ambiguous. If Step 3b lands .dag parser body BEFORE Step 4 deletes Rust parse() body, Rust + .dag parser bodies coexist temporarily — paper-shrink-relocation risk per feedback_paper_shrink_variants. Fix: 1. §9 Step 3b row reframed as "Step 3b/4 COMBINED" — atomic single PR (full .dag parser body + parity TestClaim + parse_generated.rs:138 deletion + census shrink). Cannot land .dag parser body before Rust deletion. 2. §12 Q5 phasing clarified: - Phase 3a (separate PR): grammar table extension; P5 receipt = ROADMAP deferral row naming Step 3b/4 as future-receipt - Phase 3b/4 COMBINED (single PR): atomic substrate substitution 3. §9 + §15 update notes: sequence collapses steps 12-17 into single dispatch+merge for combined phase Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3126 high-level BLOCKING findings 1 + 2 Codex high-level BLOCKING (sha 140eb6bb) had 4 findings: - Findings 3 + 4 already addressed in PR #3138 commits 015977347 + a1607a88d - Findings 1 + 2 addressed in this commit **Finding 1 (Diagnostic kind/record conflated)**: §4.2 ParseDiagnostic was modeled as variants-directly with span + kind-fields mixed. Live Diagnostic at diagnostics.dag:150 uses record-wraps-kind pattern (`{ kind, span, message, correction }`). Need consistent shape. Fix: refactored to record-wraps-kind: - `type ParseDiagnostic { kind: ParseDiagnosticKind, span: SourceSpan }` - `type ParseDiagnosticKind = UnexpectedToken | UnterminatedConstruct | InvalidLiteral | DuplicateRecordFieldLabel | ...` Span lives on ParseDiagnostic record (single source of truth); variant-specific spans (opener_span / prior_span) remain on kind variants where meaningful. **Finding 2 (PB-2 §6 obsolete sibling-lane assumption)**: §6 line 198 said "PB-2 Tokenize | src/v3/std/tokenize.dag (NEW per PB-2 L2.5)" — but tokenize.dag is ALREADY LIVE per design-pure-bootstrap.md §"PB-2 — tokenize retire" (substantially landed). Fix: §6 prereq table row updated to reflect LIVE state. PB-2's residual scope is scaffold-retirement (SG-1a + character-level + codegen-driver per PB-2 L2.5 §1), not carrier authoring. PB-3 consumes the live Token carrier; carrier shape stable across PB-2 residual-retirement timing. Findings 3 + 4 already addressed: - Finding 3 (pipeline.dag target): commit 015977347 - Finding 4 (Step 3b/4 atomic vs sequential): commit a1607a88d Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 APPROVE_WITH_COMMENTS — phantom "module-level metadata" removed Cursor APPROVE_WITH_COMMENTS line:79: §4.1 said "SurfaceModule (verified live) carries List<SurfaceItem> + module-level metadata" — but live parse_surface.dag:29 has ONLY `{ items: List<SurfaceItem> }`. No metadata fields. Phantom addition violated INVARIANTS P1 live-state honesty. Fix: §4.1 reframed to match live carrier exactly. Same phantom-addition class as tokenize.rs phantom (commit 8ae37b4a5). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3085 high-level BLOCKING findings — AtomPayload 5-variant + diagnostic-table PROPOSED Codex high-level BLOCKING (sha bf4d3152) — 2 substantive findings: **Finding 1 (AtomPayload stale)**: §2 + §5 cited infer.rs:10 top-comment "Atom(Identifier { name, resolved })" — but live substrate.dag:87 has 5-variant AtomPayload sum: Literal | UnresolvedIdentifier | ResolvedByStructure | ResolvedByName | TypeParam. infer.rs top-comment is STALE vs live substrate. My doc inherited the drift. Fix: §2 enumeration corrected to all 5 AtomPayload variants per live substrate.dag:87. **Finding 2 (diagnostic-table PROPOSED, not live)**: §2 + §4.1 + §4.3 said "diagnostics.contains(port_id) biconditional" as if live — but Dag at substrate.dag:525 has ONLY { declarations, nodes, ports, clusters }. NO diagnostics field. Diagnostic-table is PROPOSED substrate extension. Fix: §2 fail-closed note flagged PROPOSED — Step 2 PR scope includes `diagnostics: Map<PortId, Diagnostic>` field extension to Dag, OR PB-Substrate prereq adds it before PB-5 dispatch. Same recurring feedback_grep_carrier_field_before_coupling_claim discipline (PR #3126 SurfaceModule analogous case); needed to grep type Dag fields BEFORE claiming the diagnostics field exists. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3085 INLINE BLOCKING line:94 — §4.1 + §4.3 PROPOSED diagnostic-table marking Cursor INLINE BLOCKING line:94: §4.1 + §4.3 said "diagnostics coupled INTO InferredDag" without flagging the diagnostic-table as a substrate extension. Live Dag at substrate.dag:525 has { declarations, nodes, ports, clusters } — NO diagnostics field. Earlier commit c0d96af25 added PROPOSED marking only in §2; §4.1 + §4.3 needed same treatment. Fix: §4.1 + §4.3 reframed with explicit PROPOSED substrate- extension marking + reference to §2 for extension scope. Construction-time invariant + structural coupling are both contingent on the substrate-extension landing (Step 2 PR scope or PB-Substrate prereq). Same recurring feedback_grep_carrier_field_before_coupling_claim discipline applied to §4.1 + §4.3 consistently with §2. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3077 high-level BLOCKING — Practice 4 classifications for PB-4 coproducts Codex high-level BLOCKING (sha b812db91): "Diagnostic substrate shape was repaired around anchoring but not re-audited as new substrate type declarations" — meaning DiagnosticAnchor + LowerDiagnostic + SurfaceFormRef + IdentifierRef need 🟢/🟡/🔴 classifications per modeling-discipline Practice 4 (Coproduct dissolution). Same pattern as PB-5 fix in commit 040681f21 (AlgebraAxis + InferDiagnostic) applied here. Fix: added classifications + dissolution triggers: - SurfaceFormRef 🟢 TERMINAL: closed-axis sum over live Surface* carriers; no further dissolution. - IdentifierRef 🟡 SCAFFOLD: dissolution trigger = Step 2 brief enumerates full identifier-kind set against lower.rs identifier-resolution sites; promote to 🟢 TERMINAL when SurfaceVarRef + TypePathRef + ModulePathRef cover actual axes. - LowerDiagnostic 🟡 SCAFFOLD: dissolution trigger = Step 2 brief enumerates variant set against lower.rs Diagnostic emission sites + Q6.5 anti-bridge preserved + PR #3077 §12 Q7 ratification path. - DiagnosticAnchor 🟢 TERMINAL: closed-axis covering all lowering-stage anchor kinds; no further dissolution. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3077 INLINE BLOCKING line:161 — DiagnosticSource Practice 4 classification Cursor inline finding adds DiagnosticSource to Practice 4 classification scope. Earlier commit aba79a142 classified SurfaceFormRef + IdentifierRef + LowerDiagnostic + DiagnosticAnchor but missed DiagnosticSource. Fix: DiagnosticSource 🟢 TERMINAL at pipeline-stage discrimination scope. Closed-axis sum (Parse | Lower | Infer | Emit); adding new pipeline stage requires explicit substrate- extension audit per Practice 4 + stop-signal discipline (same shape as PB-5 §3.2 TypeConnective stop-signal). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 INLINE BLOCKING line:151 — §11 SurfaceItem::Let + SurfaceLiteral span correction Cursor INLINE BLOCKING line:151: §11 claimed "every Surface variant carries SourceSpan" but live parse_surface.dag has: - SurfaceItem::Let { name, type_ann, expr } — no direct span - SurfaceLiteral = Int(String) | Bool(Bool) | String(String) — plain-tuple variants with no direct span Source-span provenance for these cases is via enclosing carrier: SurfaceLiteral wraps within `Literal { value, span }` at parse_surface.dag:150. Let-item inherits container span. INVARIANTS P2/P3 source provenance is structurally guaranteed via direct-OR-enclosing carrier, but my "every variant" overstatement obscured this. Fix: §11 corrected to "most Surface variants carry SourceSpan directly" + explicit Let + SurfaceLiteral exceptions noted + Step 2 PR scope audits whether exceptions are structural-honest (enclosing-carrier-provides-span) OR require substrate extension. Same recurring overstatement class as earlier "every SurfaceItem maps 1:1 to Declaration" (commit 61e2b67cd) — need to grep live substrate variant fields BEFORE claiming uniform shape. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * WIP: gunbc Director * docs(r3): cursor PR #3126 INLINE BLOCKING line:32 — GrammarSpec is concept, not carrier Earlier draft (now-merged PR #3126) framed `GrammarSpec` as a second declared `.dag` input type alongside `List<Token>`. Verified via grep that no `type GrammarSpec` exists anywhere under src/v3/ or dsl/ — the repo carries only `parse_tables.dag`'s 6 SG-2c table-families. Per cursor 2026-05-14T23:30:04Z inline finding, this violates INVARIANTS P2 (the Step-2 signature names a carrier the substrate doesn't declare). Reframed §3 (and downstream mentions in §3.2, §3 preamble line:33, §4.2 codex-correction recap line:165, §5.1 line:181, §12 Q6 line:344) so that: - Parse has ONE input at the API boundary: `List<Token>`. - "GrammarSpec" is a concept-level grouping for the 6 compile-time table-families in `parse_tables.dag`, not a substrate carrier and not a runtime parameter. - Step-2 signature stays `fn parse(tokens: List<Token>) -> Result<SurfaceModule, ParseDiagnostic>` per cfe842b2d (already applied in #3126); these edits remove the lingering "two input types" framing that contradicted that signature. Per Decision 3.B (b) compile-time parser tables: substrate authority is parse_tables.dag (6 table-families) consumed via direct table lookups inside the parser body — no runtime grammar value, no `GrammarSpec` carrier needed. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3138 BLOCKING — §4.3 + §16 internal contradictions resolved Codex review id 12391 on sha cd6e8d15 flagged two live statements of the already-rejected typed-state-with-coupled-diagnostics model still sitting inside the parse L2.5, contradicting the corrected Result-sum framing in §4.2 and §6 Step 2: 1. §4.3 still proposed a `SurfaceModule { items, diagnostics }` extension modeled on PB-4/PB-5 patterns. Reframed: §4.3 now states explicitly that parse-stage uses Result-sum (no diagnostics field on SurfaceModule), restates the cross-stage discriminator (Result-sum for fail-fast output domains: parse + emit; typed-state for structural output domains: lower + infer), and cites `parse_generated.rs:138` as the live shape. 2. §16 "Memory disciplines applied" bullet read "feedback_state_space_vs_behavioral_invariants (typed-state SurfaceModule at output)". Rewritten to "parse output is `Result<SurfaceModule, ParseDiagnostic>` — the type rules out partial-parse states by construction; SurfaceModule itself carries no diagnostic field per §4.3". Per `feedback_discipline_change_audit_all_contract_mentions`: when a contract changes (here: SurfaceModule extension dropped in favor of Result-sum), all §-internal restatements must be swept in the same diff or they leak through as authoritative parallel claims. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3127 BLOCKING — drop TokenizedSource extension + cite concrete P5 receipts Codex review id 12370 on sha d15e1f29 raised two load-bearing planning-shape findings on the tokenize L2.5. Addressed in this fix-forward branch (PR #3138) since PR #3127 is still open but accumulating cycles. Finding 1 — parallel boundary carriers (INVARIANTS P2 / Modeling Practices 3+5): §4.3 + §9 Step 2 + §12 Q6 named `TokenizedSource { tokens, diagnostics }` as the output, while §2/§7.2/§7.3 named `List<Token>`. Same misclassification I just removed from the parse L2.5 in PR #3138 §4.3: tokenize sits in the fail-fast output domain alongside PB-3 parse + PB-6 emit (a partial token list with a corrupt token in the middle is not a valid downstream input for parse), so the failure couples via `Result`, not into the structural carrier. Resolution: - §4.3 rewritten to ratify `Result<List<Token>, TokenizeDiagnostic>` — the live `tokenize_generated.rs:96` shape — with no `TokenizedSource` extension. - §9 Step 2 row signature updated to match; explicit "single canonical boundary carrier: List<Token> on the Ok branch" framing. - §12 Q6 resolved REJECTED in-doc (no operator ratification needed; disposition follows from the cross-stage discriminator that's also load-bearing in PR #3138 parse L2.5). - §16 memory-disciplines bullets rewritten parallel to PR #3138 parse §16: Result-sum, no diagnostics field on `List<Token>`. - §14 "Surfaces awaiting" trimmed Q6 from the operator-ratification list. Finding 2 — soft deferral of `regen_tokenize` retirement (INVARIANTS P5): deferral previously named "PB-Bootstrap-Process lane scope" without a concrete ROADMAP.md row. Updated §9 Step 2 + Step 4 rows to cite the named receipts: - `docs/design-pure-bootstrap-zero.md:116` (PB-Bootstrap-Process lane: author bootstrap.dag + generated trampoline; sized M). - `docs/design-pure-bootstrap-zero.md:118-123` (N=0 runtime verification gates). - ROADMAP.md:467 (Character-level under-consumption in tokenize + syntax authorities — phase-2 char-class retype owns the codegen-driver path). - ROADMAP.md:416 (Class 5 Gap 3 — top-level `ValueBody` boundary; gating substrate-capability for the phase-2 retype). - ROADMAP.md:53 (T-PB-A — non-test census → 0 floor). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3126 BLOCKING line:119 — §6/§7.2/§15 Q7 sequencing resolved by PR #3077 merge Cursor inline BLOCKING at docs/design-parse-stage-l25-model.md:119 (sha at merge time of PR #3126) flagged a real internal contradiction: - §6 (lines 191, 207, 308) claimed "Step 2 (pipeline-slot declaration) is unblocked" - §7.2 (line 227) claimed "PR #3077 §12 Q7 must ratify before any Step 2 worker brief authoring" A worker reading the doc could land Step 2 (pipeline boundary) before the diagnostic carrier's P2/P3 failure shape was fixed. Resolution: PR #3077 (PB-4 lower L2.5) merged at 2026-05-15T00:21:19Z, carrying the §12 Q7 ratification of the Decision 2.B per-stage diagnostic extension path. The gate IS now satisfied at HEAD, so the resolution is fact-update (annotate Q7 as DONE with the merge timestamp) rather than retracting either §6 or §7.2. Edits: - §15 step 4: annotated "DONE 2026-05-15T00:21:19Z when PR #3077 merged" and added the explicit "Step 2 is now genuinely unblocked, not just procedurally next" framing so workers reading the sequence don't bypass the gate. - §7.2 line 227: rewritten from "Q7 must ratify before Step 2 brief authoring" (future tense, the contradiction surface) to "Gate satisfied 2026-05-15T00:21:19Z when PR #3077 merged; Step 2 worker brief authoring is unblocked at HEAD per §15 step 4." Cites the cursor finding as the resolution path. §6 unblocking statements stay as-is — they were correct at HEAD; the contradiction lived in §7.2's pre-merge framing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3126 BLOCKING (sha 16d21f4a) — Q7 cited at every Step 2 unblocking claim Codex BLOCKING finding 2 (sha 16d21f4a, 216s thinking): the Q7 dependency was recorded in §7.2/§15 but not in the other Step-2-unblocking sites at §6 lines 191, 207, 308 — risking a worker reading "Step 2 unblocked" without also reading the Q7 prerequisite. Codex framing: "make Q7 a hard precondition wherever Step 2 is called unblocked, or split Step 2 into pre-Q7 and post-Q7 scopes with separate receipts." Chose the first option since PR #3077 has already merged (2026-05-15T00:21:19Z) and splitting into pre/post-Q7 scopes is no longer load-bearing. Annotated all three §6 sites: - Line 191 (Implication for PB-3 migration): cites gate + merge timestamp + explicit "must NOT be brief-authored before that merge timestamp." - Line 207 (Critical observation): cites the Step 2 gate as PR #3077 §12 Q7 + merge timestamp + P3 failure-shape consequence if violated. - Line 308 (Director-recommend phase list): cites gate + §7.2/§15 step 4 cross-refs + merge timestamp. Codex BLOCKING finding 1 (GrammarSpec carrier non-existence) verified already resolved at HEAD via commit c97dc15ae — every GrammarSpec mention now explicitly marks it as a concept-not-carrier; Step 2 signature is `fn parse(tokens: List<Token>) -> Result<SurfaceModule, ParseDiagnostic>` with no GrammarSpec parameter. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): openai-pro PR #3126 BLOCKING (sha 16d21f4a) — Step 3b/4 atomicity + Q1 ratification-pending status openai-pro REQUEST_CHANGES on PR #3126 sha 16d21f4a flagged three findings. Findings 1 + 2 (signature vs realization mismatch under LAYER MODEL + P2/P3 boundary discipline) were already resolved at HEAD by earlier fix-forward commits — Step 2 signature is now `fn parse(tokens: List<Token>) -> Result<SurfaceModule, ParseDiagnostic>` matching live `parse_generated.rs:138` with no GrammarSpec parameter and no diagnostics-coupled SurfaceModule extension (§4.3 Result-sum disposition). Finding 6 (TRACKED vs UNTRACKED DEBT — Step 3b/4 same-PR vs two-PR): §9 had both a "Step 3b/4 COMBINED" row (line 250) and a leftover separate "Step 4: Parity test" row (line 251) — internally contradictory. §15 also still sequenced Steps 3b + 4 as four separate authoring/dispatch/ratify beats (steps 12-17), contradicting §12 Q5's "same PR" decision and the explicit "Update to §15" note at §12 line 325. Resolution: collapsed §9 to one COMBINED row absorbing the parity-TestClaim mechanics + P5 dissolution receipt from the deleted Step 4 row; collapsed §15 steps 12-17 into single COMBINED authoring + dispatch + ratify (steps 12-14). Added explicit `feedback_paper_shrink_variants` reasoning in both sections. Finding 2.5 (PM intent — substrate-capability bundled vs separate): §12 Q1 line 288 said "Director-recommend: (b) bundled" while §13 line 340 listed substrate-capability as a non-goal of PB-3 and §15 step 11 had "WAIT for substrate-capability landing" — three sections, two different execution paths. Resolution: annotated Q1 as "PENDING operator/PM ratification" with explicit default-execution clause: until operator ratifies, the doc treats substrate-capability as path (a) separate lane (matching §13 + §15 + §9 row). If/when ratified to (b), §13 drops the non-goal and §15 step 11 collapses into the COMBINED Step 3b/4 brief. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3126 BLOCKING (sha 5619afac) — parse_tables.dag as single enumerated authority Codex caught me copying the prose summary at parse_tables.dag:23-29 (which enumerates only SG-2c-numbered families) instead of grepping the live `^type [A-Z]` declarations. Result: SoftKeywordIdentRow (line 334) was missing from §3.2 / §5.1 / §6 / §12 because it lacks an SG-2c-N number in the prose summary. Per `feedback_parallel_representation_debt`: structural fix is to stop hand-enumerating in the doc — cite parse_tables.dag itself as the single enumerated authority and use `type`-declaration line-anchors for the worked example, not a hand-maintained count. Edits: - §3.2 §"Live substrate authority": replaced the SG-2c-numbered bullet list with `type`-declaration line-anchor enumeration including SoftKeywordIdentRow at parse_tables.dag:334 + the supporting enum BinaryOpLevel at line 133. Added codex-finding callout explaining the miss + the discipline shift. - §3 preamble line:33, §3.2 line:45 callout, §3.2 line:57 framing, §3.2 §"Substrate authority" line:71, §5.1 line:171-180, §12 Q2 line:298, §12 Q6 line:334: all hardcoded "6 table-families" counts dropped; doc now points readers to §3.2 enumeration / `parse_tables.dag` directly. - §5.1 sub-enumeration list (the parallel 6-item list at lines 173-178) deleted; replaced with redirect to §3.2 + restated 3a-vs-3b/4 scope split. Code-level check before commit: `grep -nE '^type [A-Z]' src/v3/compiler/parse_tables.dag` returns 7 types: BinaryOpLevel (133), BinaryOpRow (167), TopLevelItemKwRow (289), SoftKeywordIdentRow (334), BracketRow (385), PrimaryPrefixRow (449), PrimaryAtomRow (486). Doc enumeration matches. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3138 BLOCKING (sha f08b9525) — bind TokenizeDiagnostic to live CharClass authority Codex Finding 1 (sha f08b9525, 216s thinking): the §4.2 TokenizeDiagnostic draft and the §5.1/§5.2 headings used `ScannerCharClass` / `ScannerClassRef` — names that exist only as the *generated Rust enum spelling*, not as a declared .dag substrate type. Verified via grep: grep -rn '^type CharClass\|^type ScannerC' dsl/ src/v3/ returns ONE authority: `dsl/std/unicode.dag:62` type CharClass = Whitespace | Digit | IdentStart | IdentContinue consumed at `src/v3/compiler/tokenize.dag:103` data ascii_scan_order: List<CharClass> = [Whitespace, Digit, IdentStart, IdentContinue] There is no `ScannerCharClass` declaration anywhere — that name was copied from generated Rust without grep-verification, the same failure mode as `feedback_grep_substrate_before_naming_ratification` (carrier-name collision discipline). Resolution: - §4.2 TokenizeDiagnostic carrier: `expected_class: ScannerClassRef` → `expected_class: CharClass`, dropped the `type ScannerClassRef = ScannerCharClass` alias entirely; added a codex-finding callout citing the substrate authority + naming the failure mode. - §5.1 heading "Byte → ScannerCharClass dispatch" → "Byte → CharClass dispatch"; bullets unchanged; added line-anchor cites for the substrate authority + explicit "NOT ScannerCharClass" disclaimer. - §5.2 heading "ScannerCharClass → token-recognition state machine" → "CharClass → token-recognition state machine". Finding 2 (TokenizedSource not reconciled with parse input contract): no new fix required — already resolved by commit 6adb99227 (TokenizedSource extension dropped entirely; tokenize uses Result<List<Token>, TokenizeDiagnostic>; List<Token> is the single canonical boundary carrier consumed by parse). Codex was reviewing sha f08b9525, which predated the TokenizedSource drop. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3138 INLINE BLOCKING line:188 — clarify §7.3 chain is Ok-branch propagation Cursor INLINE at sha f08b9525 worried that §7.3's cross-stage chain "tokenize → List<Token> → parse → ..." was inconsistent with §4.3's TokenizedSource carrier (diagnostics not flowing forward). At HEAD the TokenizedSource extension is dropped (commit 6adb99227); tokenize uses Result<List<Token>, TokenizeDiagnostic>, so List<Token> IS the canonical Ok-branch payload that flows forward and Err branches terminate the pipeline fail-fast. To make this explicit at §7.3 (instead of leaving readers to infer it from §4.3), annotated the chain with: - "Ok-branch propagation; Err branches are stage-terminal fail-fast per §4.3 Result-sum discriminator" framing prefix. - Per-stage Result/typed-state annotations: tokenize/parse show Result<Ok, Err>; lower/infer show typed-state structural-output; emit shows Result<EmittedArtifact, EmissionDiagnostic>. - Explicit "on any stage's Err branch the pipeline aborts at that stage (no partial-output propagation across boundaries)" trailer. This makes the chain self-consistent vis-a-vis §4.3 without requiring the reader to walk back-and-forth, and prevents future readers from re-introducing a TokenizedSource-shaped extension to "make diagnostics flow forward" — they already do, just via the Err branch terminating the pipeline. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): openai-pro PR #3127 BLOCKING (sha d15e1f29) — character-level scaffold dissolution trigger openai-pro REQUEST_CHANGES on sha d15e1f29: §1 line:26 character-level under-consumption scaffold named the problem but lacked a checkable dissolution trigger. SG-1a scaffold above had the right shape — "once those bodies lower structurally under compile_to_dag, delete the raw-text extractor + derive directly from lowered Dag in same PR." Character-level scaffold just said "PB-2 Step 4 carries this scope" — a lane assignment, not a trigger. Resolution: rewrote §1 item 2 with the same SG-1a-shape trigger structure: - Substrate-consumption condition (a): scanner classes / string escape / local punctuation retype to `dsl/std/unicode.dag` `CharClass` / `char_in_class` (concrete field retypes named: `StringEscapeSpec.suffix: Char`, `LocalPunctSpec.pattern: List<Char>`, `string_literal_delimiter: Char`). - Codegen-driver condition (b): `tokenize_generated.rs` no longer emits hidden `byte.is_ascii_*` predicates because the driver reads class facts structurally from lowered `tokenize.dag`. - Same-PR dissolution: delete the parallel character-predicate scaffold in the same PR that flips substrate consumption — no Rust-and-`.dag` coexistence per `feedback_paper_shrink_variants`. - Cross-ref to §9 Step 4 gating prereqs: ROADMAP.md:467 + ROADMAP.md:416 Class 5 Gap 3 + std.unicode bootstrap/load-set decision (already cited in §9 from earlier commit 6adb99227). Per openai-pro's framing: "small fix — mirror the SG-1a scaffold wording by naming the exact substrate-consumption condition and same-PR deletion receipt for the hidden Rust character predicates." Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * WIP: gunbc Director * docs(r3): cursor PR #3127 APPROVE_WITH_COMMENTS — §14 + §15 Q6-already-rejected sweep Cursor review id 12405 (APPROVE_WITH_COMMENTS) caught the same `feedback_discipline_change_audit_all_contract_mentions` failure mode recurring: §12 Q6 was resolved REJECTED in commit 6adb99227, and §14 "Surfaces awaiting" + §12 Q6 heading + §9 Step 2 row were updated, but two §-internal contract restatements were missed: - §14 acceptance criterion 11: "Operator/PM ratification on §12 Q1-Q6" - §15 step 1: "Operator / PM-delegate ratifies §12 Q1-Q6" Both contradicted §12 Q6 + §14 "Surfaces awaiting" (which already said "Q1-Q5 only"). A worker reading §14/§15 could schedule sign-offs on Q6 after it was already resolved-rejected elsewhere. Resolution: both sites now say "Q1–Q5" with the explicit Q6-rejected crossref + "see §14/§15 for same scoping" pointer at the §14 criterion so the three sections agree internally. Cursor verdict was APPROVE_WITH_COMMENTS (substantive APPROVE — "fix the checklist/sequence so every section agrees Q6 is closed"); the exploratory volatile-line-anchor note is harmless and out-of-scope for this PR. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3138 BLOCKING (sha 887c69671) — 3 findings swept across 3 L2.5 docs Codex review id (sha 887c69671, 333s thinking) flagged three findings, all `feedback_discipline_change_audit_all_contract_mentions` recurrences where partial sweeps left §-internal contradictions. Finding 1 — infer doc cross-stage trigger leak: §4.2 InferDiagnostic dissolution trigger said "when Step 2 worker brief enumerates the full variant set against `parse_generated.rs` Diagnostic::ParseError, lower.rs Diagnostic construction sites, and infer.rs Dag::mark_unresolved emission sites." That cross-stage trigger surface is wrong for the infer-specific scaffold. Narrowed to infer-only: "against `src/v3/compiler/src/infer.rs` Diagnostic construction sites + `Dag::mark_unresolved` emission sites (infer-stage only)." Parse and lower have their own per-stage carriers + own Q7 mapping; this doc no longer reaches into their dissolution-trigger surface. Finding 2 — parse + tokenize coproduct receipts: `ParseDiagnosticKind` (parse §4.2) and `TokenizeDiagnostic` (tokenize §4.2) sums were declared without the 🟡 SCAFFOLD / 🟢 TERMINAL classification + dissolution trigger that the infer doc carries (per modeling-discipline Practice 4 + `feedback_coproduct_dissolution`). Added matching scaffold receipts to both: 🟡 SCAFFOLD at PROPOSED stage with stage-local dissolution trigger (Step 2 brief enumerates against parse_generated.rs / tokenize_generated.rs Diagnostic::* construction sites — stage-only, not cross-stage); promote to 🟢 TERMINAL when full variant set lands. Both also carry the anti-bridge note per Q6.5. Finding 3 — tokenize Q7 reconciliation: The parse doc has the "Q7 DONE 2026-05-15T00:21:19Z" annotation at §15 step 4 (commit f85fa1f6b) but the tokenize doc still framed Q7 as a pending lane dependency at §4.2 line:113 ("Lane dependency"), §15 step 3, and §14 "Surfaces awaiting". Annotated all three: - §4.2 "Lane dependency": Q7 DONE timestamp + "TokenizeDiagnostic per-stage variant authoring is the remaining lane work." - §15 step 3: full DONE annotation matching parse doc §15 step 4 shape + cross-ref to the parse doc. - §14 "Surfaces awaiting": strikethrough + DONE annotation. PR #3127 also carries the tokenize doc; same edits will port there in a companion commit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3138 INLINE BLOCKING line:372 — §16 Surfaces awaiting Q7 contradiction Cursor inline at sha 887c69671 caught the symmetric finding to the codex 5-finding BLOCKING #3: parse-doc §15 step 4 already annotated Q7 as DONE (commit f85fa1f6b) but parse-doc §16 "Surfaces awaiting" still listed Q7 as pending. Same `feedback_discipline_change_audit_all_contract_mentions` sweep failure — the tokenize doc had three sites carrying the pending framing (commit e9739ea4f fixed those) but the parse doc's §16 site was missed in the original Q7-DONE sweep. Resolution: §16 bullet now strikes through + "DONE 2026-05-15T00:21:19Z (PR #3077 merged carrying Q7 ratification; see §15 step 4)" — same shape as the tokenize doc's §14 "Surfaces awaiting" Q7-DONE annotation landed in e9739ea4f. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): codex PR #3127 BLOCKING (sha 8e682eef) — §3.1 source identity + §4.2 live-vs-proposed clarity PR #3127 was merged at 02:04:22Z but codex's later review on sha 8e682eef caught two findings that still live in main. Both addressed in this PR (PR #3140) since the tokenize doc lives on main and this is the open post-merge cleanup branch. Finding 1 — §3.1 source-identity drop: Earlier draft framed tokenize input as bare `String → List<Token>`. That contradicts live `tokenize_generated.rs:96`: pub fn tokenize(source: &str, file: &str) -> Result<Vec<Token>, Diagnostic> The `file` parameter is load-bearing because `SourceSpan` requires a file/source-id field for byte ranges to be attributable; without it the Token + Diagnostic span fields would have to fabricate source-id at the pipeline boundary (P3 fail-closed violation). §3.1 now ratifies the live two-input shape: - `source: String` — UTF-8 source text (primitive). - `file: SourceFileId` — source-identity carrier; Step 2 brief ratifies the appropriate `.dag` shape (NonEmptyStr newtype or richer sum if multiple source-class kinds). Finding 2 — §4.2 live-vs-proposed blur: Prior framing said "TokenizeDiagnostic (substrate extension per Decision 2.B)" without making clear that this is a PROPOSED per-stage carrier, not the live one. The live carrier at `diagnostics.dag:150` is generic `Diagnostic { kind: AnyDiagnosticKind, ... }` with kind sum at `:139-142` discriminating CompilerKind vs LensInstanceKind; tokenize emits today via `Diagnostic::TokenizerError`-shaped sites carrying `kind: CompilerKind(...)`. §4.2 heading now reads "PROPOSED — NOT yet live" + a codex-finding callout explicitly distinguishing the live carrier from the proposed per-stage refinement + Q7 status DONE. Both fixes preserve the e9739ea4f 🟡 SCAFFOLD coproduct receipt that was already addressing codex sha 887c69671 Finding 2. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3127 INLINE BLOCKING line:121 — §4.3 + §9 Step 2 signature sweep Cursor inline at sha 8e682eef line:121 (the §4.3 Step 2 signature site) caught the same source-identity drop my §3.1 fix already addressed at the input-type framing — but two companion sites still had the single-input signature: - §4.3 line:151 Step 2 signature recap - §9 Step 2 row (4-step migration table) Both now read: fn tokenize(source: String, file: SourceFileId) -> Result<List<Token>, TokenizeDiagnostic> matching the §3.1 source-identity discipline + live `tokenize_generated.rs:96` `pub fn tokenize(source: &str, file: &str)` shape. Same `feedback_discipline_change_audit_all_contract_mentions` recurrence — my Finding 1 fix at §3.1 (commit 18af49fad) didn't sweep the §4.3 + §9 contract-signature restatements. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3127 INLINE BLOCKING line:166 — §6 row TokenizeDiagnostic LIVE/PROPOSED clarity Cursor inline caught ambiguity in the §6 prereq-table row for "TokenizeDiagnostic substrate extension." Old wording in column 4 read "Carrier LIVE; per-stage variant authoring NEW" which could be parsed as "TokenizeDiagnostic carrier itself is LIVE" — but no `type TokenizeDiagnostic` exists in `dsl/std/` or `src/v3/std/`. Only the generic `type Diagnostic` at `diagnostics.dag:150` is live. Cursor's secondary claim that "line 150 is EmissionDiagnostic receipt prose" is INCORRECT — verified via grep + read: `diagnostics.dag:150` is the `type Diagnostic { kind: AnyDiagnosticKind, ... }` declaration header. `type EmissionDiagnostic` lives separately at `diagnostics.dag:201`. The §6 row's citation of `:150` for the underlying Diagnostic carrier is correct. But the ambiguity-in-wording finding stands. Reframed the row: - Column 1: explicitly "PROPOSED — no `type TokenizeDiagnostic` exists yet" - Column 2: clarifies the LIVE underlying carrier is `type Diagnostic` with `kind: AnyDiagnosticKind` sum at `:139-142`; cites Q7 ratification done timestamp. - Column 4: explicit "Underlying Diagnostic carrier LIVE at HEAD; per-stage TokenizeDiagnostic variant authoring is NEW work, NOT live substrate" with cursor-finding callout. Consistent with §4.2's "PROPOSED — NOT yet live" framing from commit 18af49fad. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3141 INLINE BLOCKING line:68 — §2 structural-signature sweep Cursor inline caught §2 still framing tokenize structural signature as `String → List<Token>` — single bare-string input, no source-identity, no Result-sum failure shape — while §3.1 + §4.3 + §9 Step 2 row all ratify the live two-input + fail-fast Result-sum shape. Same `feedback_discipline_change_audit_all_contract_mentions` recurrence that's been compounding across this fix-forward sequence: each finding fix needs a doc-wide signature-restatement sweep, not just the §-local sentence. Resolution: §2 structural-shape sentence now reads `(String, SourceFileId) → Result<List<Token>, TokenizeDiagnostic>` matching §3.1 (source-identity), §4.3 (Result-sum cross-stage discriminator), §9 Step 2 row, and live `tokenize_generated.rs:96` `pub fn tokenize(source: &str, file: &str) -> Result<Vec<Token>, Diagnostic>`. Cross-refs added to §3.1 + §4.3 to make the discipline visible at the high-level framing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * docs(r3): cursor PR #3141 INLINE BLOCKING line:73 — replace invented SourceFileId with live FilePath Cursor caught me inventing `SourceFileId` as the Step 2 boundary type without a live `.dag` declaration. Verified via grep: grep -rn '^type SourceFileId' dsl/ src/v3/ returns empty. Same `feedback_grep_substrate_before_naming_ratification` family error as the earlier `ScannerCharClass` miss — naming a substrate carrier without grep-verification. Live carrier already exists at `dsl/std/types.dag:276`: type FilePath = String where non_empty referenced by `type SourceSpan { file: FilePath, ... }` at `dsl/std/types.dag:293`. So source identity flows through every Token + Diagnostic span field via the live `FilePath` carrier — no new carrier authoring needed at Step 2. Edits: - §2 structural-signature: `(String, SourceFileId)` → `(String, FilePath)` - §3.1 source-identity bullet: replaces fictional SourceFileId with the live `FilePath` declaration cite (dsl/std/types.dag:276), points out that `SourceSpan.file` already references this same carrier, and adds a cursor-finding callout naming the failure mode. - §4.3 + §9 Step 2 signature restatements: `file: SourceFileId` → `file: FilePath`. Single substrate authority (INVARIANTS P1/P2) restored: FilePath is the one carrier for source identity across SourceSpan + tokenize input + Token construction. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…afts) (#3139) * docs(r3): rust retirement catalogue + emit.rs modeling doc (format-validation drafts) Per operator 2026-05-15 directive — replace SG-0 file-path ratchet (which rewards file-path manipulation / paper-shrink) with a substrate-authority planning artifact. Focus on actual `.dag` substrate growth, not ratchet file-list shrinkage. Two docs: (1) `docs/r3-rust-retirement-catalogue.md` (159 lines) - Framing: explicit anti-paper-shrink stance citing `feedback_template_relocation_paper_shrink_discriminator` (cycles 4/5/6 reverts at PR #3059) - Format spec for per-entry catalogue: Role / Public surface / Inputs / Calls into / Called by / Existing `.dag` substrate / Retirement target / Replacement plan (R1=substrate, R2=consumer-reads-substrate-not-template, R3=parity invariant — semantic NOT textual) / Anti-paper-shrink check / Phase 1-5 / Substantive retirement risks - 5-phase retirement plan ordered cheapest-first: Phase 1: hand-Rust monotonicity invariant (foreclose growth) Phase 2: test harness layer (122 → 1-3 via .dag TestClaim) Phase 3: lens-as-Rust (7-10 → 0 via data lens_X: Lens<C> + fold_lens) Phase 4: substrate-mirror generation (5-8 → 0 via regen reads substrate.dag) Phase 5: pipeline-stage retirement (12-15 → meta-circular bootstrap) - One worked example entry: src/v3/compiler/src/emit.rs (3,992 lines) with 4 substantive retirement risks flagged - 5 open format questions for operator before scaling to remaining ~176 entries (2) `docs/r3-retirement-modeling-emit-rs.md` (310 lines) - Per-file modeling doc; first instance of a series (one per Rust file) - §1 What emit.rs does (4 internal layers identified) - §2 Reference pattern (tokenize.dag) — the proven `.dag`-drives-retirement example - §3 6-layer identification ordered by tractability (Layer 1 dispatcher = most tractable; Layer 6 = whole-file retirement) - §4 Layer 1 (dispatcher) FULLY MODELED: * 4 new substrate carriers in src/v3/std/emit_model.dag: EmitTarget, EmitMode, EmittedSource, EmitTargetDispatchRow * 1 data value: emit_target_dispatch_table * 3 pure functions: emit_with_mode, emit, emit_module * Codegen driver outline: new regen_emit_dispatcher.rs following regen_tokenize.rs pattern * Parity verification: SEMANTIC (m1_3/m1_4 integration tests pass unchanged) NOT TEXTUAL (no source-clone) - §5 Sketches for Layers 2-N - §6 4 open questions about .dag substrate-language features needed - §7 Substantive retirement risks (paper-shrink discriminators) - §8 What Layer 1 demonstrates (proof-of-pattern for emit translation) Neither doc proposes changing the ratchet now — that's separate operator direction. These are planning artifacts for the substantive retirement work, not enforcement bridges. Tokenize/parse pipeline stages are already fully substrate-driven (the proof-of-concept). Lower/infer/emit have L2.5 design docs (PR #3066, #3077, #3085, #3126 just merged) but no executable `.dag` substrate yet — the modeling doc series identifies the smallest tractable layer per file to begin substantive migration. Co-authored-by: Brian (operator briansrls) — directive 2026-05-15 * docs(r3-catalogue): restructure per claude APPROVE-exploratory PR #3139 — move 5-phase plan above format spec (single authority for Phase enum) claude APPROVE on commit 458b08d (PR #3139, 2026-05-15T02:14:43Z) flagged a non-blocking exploratory note: "the catalogue's Phase enum is defined inside the per-entry format spec block, but the 5-phase plan section at the bottom is the canonical authority — if this doc lives long, consider moving the phase definitions above the format spec so the format references rather than redefines them." Applied — the doc now has the 5-phase plan section FIRST, with full definitions, and the format spec section references Phase numbers without duplicating definitions. Eliminates the dual-authority problem the exploratory note identified. Section order (post-fix): - §"5-phase plan (canonical authority for Phase enum referenced below)" - §"Format spec (per entry — references Phase numbers from §"5-phase plan" above)" - §"Catalogue" (worked example: emit.rs) - §"(Remaining ~176 entries — to be filled per format-ratified spec)" - §"Open questions for operator before format is ratified" The format spec's Phase field now reads: "Phase: one of Phase 1–5 per §"5-phase plan" above. (Definitions are NOT duplicated here — the §"5-phase plan" section is the single authority.)" No content changes beyond structure; doc is 154 lines (down 5 from de-duplication of the Phase definitions). * docs(r3): add Path B tokenize/parse brief set (9 briefs, no workarounds) Per operator directive 2026-05-15 — "could we try to do path B for tokenize/ parse (NO workarounds) now — i'd like to spawn workers under you directly". Planning doc enumerating the 9 briefs needed for true 100% .dag retirement of tokenize + parse including codegen drivers. Workers spawn directly under deep-wolf-155 (PM) per operator; no Director/Mgr layer for this lane. Dispatch graph: - Phase 0 (parallel, no deps): Briefs 1-3 substrate-language gaps - Brief 1: generic methods on FreeMonoid<T> (non-endomorphic map + per-method type params; named gap at dsl/std/algebra.dag:387-393) - Brief 2: format(template, args) + Int/Char/Bool → String primitives - Brief 3: char-class structural completion (finish in-progress scaffold at tokenize.dag:23-58) - Phase 1 (parallel, no deps on Phase 0): Briefs 4-6 host effects + bridge - Brief 4: FileReadEffect + FileWriteEffect (bundle) - Brief 5: ProcessSpawnEffect (for rustfmt) - Brief 6: compile_to_dag FFI bridge — operator decision point (FFI vs self-hosted) - Phase 2 (depends on Phases 0+1): Briefs 7-9 driver authoring - Brief 7: tokenize_codegen.dag (retires regen_tokenize.rs 1,186 lines) - Brief 8: parse_tables_codegen.dag (retires regen_parse_tables_emit.rs 1,284 lines) - Brief 9: parse_codegen.dag (retires regen_parse_emit.rs 124 lines) Cumulative: 6-12 months optimistic, 12-18 realistic. Substrate-language work in Briefs 1-6 unblocks Phase 2/3/5 broader retirement paths beyond tokenize/parse alone. 5 open questions for operator at end of doc: 1. Brief 6 FFI vs self-hosted architectural choice 2. Spawn cadence (parallel vs sequential) 3. Test harness scope (in or out of this brief set) 4. Substrate-language work attribution to Phase 2/3/5 5. Worker parallelism cap (3-4 in flight realistic) Anti-paper-shrink discriminator applies to all 9 briefs: substrate-growth PR-by-PR is the receipt, not file-path shrinkage. * docs(briefs): add Path B Phase 0 worker briefs (1-3) — individual files for dispatched workers Workers witty-moth-725 (Brief 1), sunny-tern-495 (Brief 2), bright-swift-668 (Brief 3) auto-spawned under deep-wolf-155 per operator directive. The work- item titles were truncated and didn't carry full brief content; this commit provides the canonical single-file brief per worker. - docs/briefs/r3-path-b-brief-1-freemonoid-generic-methods.md Worker: witty-moth-725 Gap: dsl/std/algebra.dag:387-393 (FreeMonoid<T>.map endomorphic only) Estimated effort: 2-6 months substrate-language work - docs/briefs/r3-path-b-brief-2-string-templating-conversions.md Worker: sunny-tern-495 Gap: no format(template, args) + verify Int/Char/Bool → String primitives Estimated effort: 1-3 months - docs/briefs/r3-path-b-brief-3-char-class-structural.md Worker: bright-swift-668 Gap: tokenize.dag:23-58 named scaffold (char_in_class NYI for structural execution) Estimated effort: 1-2 months Each brief: - Investigation-first (Phase A) — surface findings to deep-wolf-155 before authoring - Concrete deliverables + acceptance criteria (substrate-fact-at-HEAD) - Anti-paper-shrink discriminator (substrate growth, not file-path manipulation) - Coordination protocol: direct dashboard-message to deep-wolf-155, no Director/Mgr layer - PR title prefix r3-path-b-brief-N for traceability * docs(r3): address codex + briansrls BLOCKING PR #3139 — align catalogue with 0-floor target + dissolve EmitTarget closed enum into LanguageSpec open registry Two valid BLOCKING findings: (1) codex REQUEST_CHANGES (catalogue.md:31, :52, :55) — "irreducible 10-15 file seed" + "Irreducible bootstrap seed (cannot retire)" framings CONTRADICTED `docs/design-pure-bootstrap-zero.md` (LIVE 2026-04-25 cascade promotion) which establishes the in-tree floor as ZERO. Authoritative text: - line 41: "Goal: zero hand-authored files in v3's source tree." - line 95: "the in-tree floor target is 0 regardless of which N=0 resolution lands" - line 191: "If first-time bootstrap (N=0) resolution requires hand-Rust in v3's source tree — STOP. The resolution is supposed to live outside v3's source tree (install script, gunbc-runtime crate, or rustc macro)." (2) briansrls INLINE BLOCKING (modeling-emit-rs.md:125) — proposed `type EmitTarget = Go | Rust | Python` closed sum REINTRODUCED a target roster that the live `src/v3/std/emit_model.dag` header (lines 8-16) explicitly dissolves via LanguageSpec references: "Adding a new shared target is a pure spec-file change — drop a `<target>.dag` with a LanguageSpec data item and reference it from each realization. No compiler enum roster to edit." Fixes: Catalogue (docs/r3-rust-retirement-catalogue.md): - §"5-phase plan" end-state: replaced "irreducible 10-15 file seed" with 0-floor target. Files that look irreducible (bootstrap drivers etc.) retire by MOVING OUT-OF-TREE per design-pure-bootstrap-zero.md N=0 resolution paths (install script / gunbc-runtime crate / rustc macro), NOT by accepting a permanent in-tree residual. - §"Format spec" per-entry "Retirement target" options: replaced "Irreducible bootstrap seed (cannot retire; document why)" with "Moved out-of-tree". Added explicit (N.B.) citing codex BLOCKING + design-pure-bootstrap-zero.md line 191: planning artifact does NOT have authority to introduce permanent in-tree carve-outs against the live 0-floor design. Modeling doc (docs/r3-retirement-modeling-emit-rs.md): - §4.1 substrate carriers: retracted `type EmitTarget = Go | Rust | Python` closed sum. Replaced `EmittedSource.target: EmitTarget` with `EmittedSource.language: DeclarationRef` matching the `TypeRealization.language: DeclarationRef` pattern at emit_model.dag:18. Removed `EmitTargetDispatchRow` separate roster carrier — LanguageSpec registry IS the roster. - §4.2/§4.3: dispatch reads LanguageSpec declarations from src/v3/spec/*.dag directly via declaration-namespace walk; functions now take `language: DeclarationRef` parameter. - §4.4 codegen driver: GENERATED Rust uses open-registry pattern too — no hardcoded `match EmitTarget { Go => ..., Rust => ..., Python => ... }` in emitted code; dispatches via DeclarationId lookup against the live LanguageSpec registry. - §6 open question #2: variant-arm exhaustiveness check replaced with declaration-namespace-walk-by-type-tag (open-registry concern). - §7 substantive retirement risks: paper-shrink discriminator updated (no closed enum reintroduction in generated Rust). Cross-target convenience wrappers collapse to ONE `emit_text(dag, language)` parameterized function. EmitMode = Program | Module stays as a closed sum (intentionally bounded; structurally distinct from target-roster concern). * docs(r3): address briansrls BLOCKING PR #3139 at catalogue.md:21 — expand Phase 1 monotonicity invariant to full hand-Rust surface (include src/v3/compiler/tests/**) briansrls inline BLOCKING at 2026-05-15T02:48:45Z flagged that Phase 1 scoped only src/v3/compiler/src/, leaving Rust tests outside the net-shrink gate even though INVARIANTS.md P5 + T-PB-B explicitly include Rust tests in the hand-Rust surface. Verified at INVARIANTS.md:323 (Dispatch-Discipline Mechanisms (b)): "Hand-Rust includes Rust tests (src/v3/compiler/tests/**) — these are the T-PB-B test subset of the SG-0 census; the gate applies the same way it applies to T-PB-A non-test files." Fix: Phase 1 monotonicity invariant now scopes the FULL hand-Rust surface (src + tests). Eliminates the loophole where gate-closure PRs adding Rust tests would skirt the invariant — which is exactly the growth pattern observed in the SG-0 trajectory data (TEST array went 122 → 130 → 131 across recent gate-closure PRs). * docs(r3): M2 / class-5 deferral debt survey (operator-requested 2026-05-15) Per operator directive: "Can we please find all instances of this happening in this project - i want to attack one of these problems specifically so we can gather some confidence." Survey enumerates the M2-deferred / class-5-blocked work in the project: Quantitative scope: - 119 references to "class-5" across docs/ + src/v3/ + dsl/ - 61 citations naming class-5 as a blocker / dissolution trigger - 161 ArrowBody::Unparsed std fn bodies (58% of 276 total) - 1 dedicated design doc (docs/design-m2-feature-parity.md, status "Design ready for implementer review") sitting unimplemented Enumeration: 1. M2 Feature Parity (DB-9 through DB-13, design doc ready): - DB-9: Mutual recursion lowering (L) - DB-10: data value semantics (S) — RECOMMENDED ATTACK POINT - DB-11: where refinement predicates (M) - DB-12: surface generics (S) - DB-13: Disj dotted-path (S) 2. Class-5 grammar gaps (substrate-language sub-program): - #1: Brace-bodied fn on .dag files (161 Unparsed std fns) - #2: Record literals inside data bodies - #3: Lens-fold prereq - #4: Variant-constructor expressions - #5: Dimension<C> data declarations (blocked on #2) - #6: Name rosters 3. Hand-Rust trampolines that exist BECAUSE class-5 isn't closed 4. Downstream symptoms (R3 retirement stalls, lens trampolines, etc.) Recommendation: DB-10 (data value semantics) as confidence-builder: - Smallest (size S per doc) - Substrate carrier already exists (Declaration.value_body at dag.rs:122) - Gap is downstream consumers, not substrate-shape change - Closes class-5 sub-gap #2 + unblocks dimension framework + cost-lens trampoline retirement - Estimated 1-2 weeks if design is accurate - Demonstrates "we can close M2 deferrals" pattern Alternative: class-5 brace-body parse for .dag files (bigger lever, more invasive; coordinates with Brief 3 worker bright-swift-668). * docs(r3-catalogue): clean up stale 'irreducible bootstrap seed' reference in Open Questions §5 (briansrls BLOCKING PR #3139 follow-through at catalogue.md:163) briansrls BLOCKING at catalogue.md:31 about the "irreducible 10-15 file seed" framing was already addressed in commit 6bafd12 (relay arrived after fix per dashboard typical relay-after-fix pattern). However, a stale reference to "irreducible bootstrap seed" remained at line 163 in the Open Questions section — reframed as "move out-of-tree per design-pure-bootstrap-zero.md N=0 resolution paths" with explicit no-permanent-residual disclaimer. The retraction at lines 31-38 + §"Format spec" (N.B.) at line 64 remains the canonical retraction text per the prior commit. * docs(briefs): add Path B Brief 4 — DB-10 data value semantics (M2/class-5 confidence-builder attack point) Per operator directive 2026-05-15 — "lets attack DB-10 for confidence, give it to one of the existing path B brief members". Brief 4 dispatches DB-10 (data value semantics, M2 feature parity item 3a.2) to witty-moth-725 — they closed Brief 1 cleanly (PR #3142 promoted to ready) and are available for new substrate-language work. Authoritative design at docs/design-m2-feature-parity.md §DB-10 (lines 20-71); doc carries "Design ready for implementer review" status since authoring. This is the FIRST attack against the M2 / class-5 deferral pit per the survey at docs/r3-m2-class-5-deferral-survey.md. Scope: - Phase A: verify design-doc cited locations (dag.rs:122, lower.rs:1404, test_3a2_data_field_access_resolves_statically test ratchet) against HEAD; surface drift findings to deep-wolf-155 - Phase B: land 3 consumers per design — Dag::data_value_at accessor + SurfaceExpr::Var fallback for scalar inlining + lower_field_path_expr walks ValueBody::Structural for static field access - Phase C: test fixture demonstrating data answer = 42 + answer + 1 emits 42 + 1 inline across all 3 target languages Architectural commitment honored (per design + PR #496 2026-04-17): inlining at LOWERING, not emission. Load-bearing per locked test ratchet. Emission-time inlining REJECTED. Coordination: parallel to PR #3142 merge (Brief 1 closure); separate branch; report findings directly to deep-wolf-155 (no Director/Mgr layer). Coordinate with sunny-tern-495 (Brief 2) + bright-swift-668 (Brief 3) only if substrate work overlaps. Anti-paper-shrink discriminator: locked test asserts no FieldProject Transform exists in the lowered DAG for data-resolved field accesses; that ratchet catches trampoline-style workarounds. Estimated effort: 1-2 weeks if design doc is accurate. * docs(r3): retract stale 'M2 not landed' framing — DB-10/12/13 verified LANDED at HEAD 2026-05-15 Per gentle-bat-24 Brief 4 Phase A finding (DB-10 substrate already implemented at HEAD with `Dag::data_value_at` at dag.rs:4310 + lower.rs:8489+/8642+/9125+ + passing test at m2_feature_parity_test.rs:771) + subsequent verification of DB-12/DB-13 status amendments in PR #496 against HEAD test names: DB-10: LANDED DB-12: LANDED (parse_generated.rs:927; m2_feature_parity_test.rs:90-156) DB-13: LANDED (lower.rs:3375; m2_feature_parity_test.rs:163-208) DB-9 + DB-11: HEAD landed-state NOT YET AUDITED; may also be silently landed Sites updated: - docs/r3-m2-class-5-deferral-survey.md: M2 feature parity table reframed with cited HEAD evidence per DB; explicit retraction of "no DB item has landed yet" claim; active deferral pits shrink to DB-9 + DB-11 (pending audit) plus class-5 sub-gaps which remain genuinely deferred per Brief 3 findings - docs/design-m2-feature-parity.md: top-level Status line updated from "Design ready for implementer review" to "3 of 4 LANDED" with per-DB cited HEAD evidence; explicit advisory that workers should audit HEAD state before authoring implementation against this doc Residual M2 work for the 3 LANDED items: emission-test-coverage gap for DB-12 + DB-13 (design §Acceptance promises 3-target render verification; current tests check compile + lower only). Small follow-up scope; not pit-shaped. The "M2 deferral pit" framing was substantially wrong as initially described — much of M2 has been silently landing. The class-5 sub-gaps remain genuinely deferred per Brief 3's bright-swift-668 investigation (brace-body fn parse on .dag files). Per `feedback_corrections_must_grep_verify_source` — this is the canonical lesson: design docs drift; verify against HEAD before authoring against them. * docs(r3): address codex BLOCKING PR #3139 (review #12458) — retract String-typed EmitDispatchError + retract Brief 6 FFI bridge as deliverable path Two findings, both valid: (1) modeling-emit-rs.md:203 — proposed `type EmitDispatchError { language: DeclarationRef, detail: String }` as 🟡 SCAFFOLD. RETRACTED. INVARIANTS P3 + docs/modeling-discipline.md Practice 1 forbid String-typed diagnostic channels at the substrate-API level. SCAFFOLD-with-String at the API level is still a String-API at HEAD; the scaffold marker doesn't excuse the typed-carrier requirement. Fix: defer the EmitDispatchError shape entirely until per-language typed error carriers land (Brief 7+). Dispatcher signature stays Result<EmittedSource, ???> with ??? as forward-reference. Workers attempting Brief 7+ surface back if the error-carrier shape becomes load-bearing before per-language errors exist — substantive substrate-language question, not papered over with String channel. (2) brief-set.md:206 — Brief 6 presented an "FFI bridge" option (a) as a deliverable path. The brief text itself admitted "does not retire the Rust compile_to_dag function itself" — that's a bridge preserving hand-Rust compiler authority, NOT retirement. Operator's NO WORKAROUNDS stance + INVARIANTS P5 forbid FFI as deliverable path. The brief currently muddled this; codex correctly flagged that the wording would send a worker to execute the wrong work. Fix: Brief 6 reframed as SCOPE MARKER ONLY (Phase 5 program, NOT dispatchable within this brief set). Recommendation surfaced to operator: declare Phase 5 / meta-circular bootstrap as separate program from Path B; tokenize/parse codegen-driver retirements (Briefs 7-9) are downstream of Phase 5 and not landable until self-hosted compile_to_dag lands. Honest framing: forcing Briefs 7-9 to land before Phase 5 via FFI bridges produces paper-shrink, not retirement. Sites updated: - modeling-emit-rs.md §4.3 EmitDispatchError block: explicit RETRACTION text; signature now Result<EmittedSource, ???> with forward-reference framing - brief-set.md §"Brief 6 — Meta-circular: compile_to_dag Foreign-Function Bridge" retitled to "self-hosted compile_to_dag (Phase 5 scope expansion)" + scope reframed as SCOPE MARKER ONLY - brief-set.md dispatch graph: Brief 6 marked NOT DISPATCHABLE - brief-set.md §Brief 7 prerequisites: Briefs 1-5 + Phase 5 separately - brief-set.md §Brief 7 scope: cites separately-scoped Phase 5 program - brief-set.md §"Open questions for operator before dispatch" #1: RESOLVED per this codex BLOCKING; no FFI workaround acceptable * WIP: Path B Brief 4 — M2 DB-10 data value semantics (data foo: T = v usable a * docs(r3): finish typed emit error retraction
Summary
Key structural distinctions from PB-4/PB-5/PB-6
Decision 3.B (b) preserves substrate-authority-all-the-way-down: GrammarSpec is
.dagsubstrate compiled to parser dispatch tables at build time (NOT runtime data-driven). Live precedent atsrc/v3/compiler/parse_tables.dag(517 lines; 6 SG-2c table-families).Hard substrate-capability dependency (unique to PB-3): full parser-body
.dagmigration BLOCKED on substrate capability perparse_tables.dag:13-22STOP-AND-ESCALATE: recursive list-body emission overList<Token>with cursor threading (persrc/v3/std/list.dag:13-15+ SELF_HOSTING.md §6 Phase 4a).Step 3 PHASED into 3a/3b:
.dagmigration — waits for substrate-capability§12 Q1–Q6 open questions
feedback_paper_shrink_variants)Authoring discipline applied (cumulative learnings from PR #3066 + #3077 + #3085)
Test plan
🤖 Generated with Claude Code