Skip to content

feat(v4): T-8 source-text provenance — Node.span substrate + parse stamp - #4604

Merged
briansrls merged 28 commits into
mainfrom
session/quick-bee-480
Jun 10, 2026
Merged

briansrls merged 28 commits into
mainfrom
session/quick-bee-480

Conversation

@briansrls

@briansrls briansrls commented Jun 9, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Builds the T-8 source→node/locus byte-range provenance producer (4 layers):

  1. Substrate — SourceSpan + NodeSpan on v4.std.node.Node (additive span field; Unanchored default across v4 corpus)
  2. Parse producer — v4.compiler.parse stamps token file/start/end on terminal nodes and merges spans through sequence/repeat/wrap
  3. Locus projection — textual_locus_from_node_span in v4.std.diagnostic maps anchored spans to Textual { ByteRange }
  4. Provenance carrier — v4.std.provenance + tightened edit_locus_resolver claims (anchored span + byte extent on source_ir_node_artifact_provenance)

Replaces the foundation-only file-level provenance wire (#4592) with real parse-time byte-range anchoring.

Test plan

  • cargo test -p v3-compiler --test integration v4_test_bootstrap_infra_closeout — 13/17 pass; 4 failures match origin/main (pre-existing)
  • cargo test -p v3-compiler --lib — 470 pass; 9 failures are gunbc_execute_command_bootstrap path env (pre-existing in this worktree)
  • CI gates on PR (draft → ready)

@briansrls
briansrls force-pushed the session/quick-bee-480 branch from d967d26 to 276bcf9 Compare June 9, 2026 22:38
@briansrls briansrls changed the title PROVENANCE PRODUCER build (operator GO 2026-06-09): build the real source->node/locus byte-range provenance — the T-8 substrate the measurement (silent-lynx) found is a BUILD not an expose. 4 layers, fan out: (1) T-8 source-text anchor on the Node substrate (00_core.dag) — ADDITIVE Node.span field ( feat(v4): T-8 source-text provenance — Node.span substrate + parse stamp Jun 9, 2026
@briansrls
briansrls marked this pull request as ready for review June 9, 2026 22:39

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Review metadata

  • Provider / model: codex / unknown
  • Commit: 276bcf9e · Trigger: schedule
  • Thinking: 362s wall

BLOCKING (6)

Root Cause

  • src/v4/std/node.dag The span default sweep exposed NodeSpan constructors directly at every Node literal → centralize unanchored construction through node_unanchored or update each affected module import.
  • src/v4/std/node.dag The optional span carrier was added as a raw sum before recording whether it is terminal or scaffold → add the required disposition receipt or model it through an existing optional/provenance carrier.
  • src/v4/compiler/03_normalize.dag Node.span propagation is not part of the stage rewriter contract → preserve n.span on structural rewrites and require a named receipt for intentional span erasure.
  • src/v4/compiler/03_resolve.dag Resolution rewriters reconstruct Node from kind/children only → carry n.span forward in every same-node rewrite or diagnose why provenance no longer applies.
  • src/v4/std/node.dag SourceSpan merge has no same-file proof or failure carrier → require same-file spans structurally or return an Outcome with a typed diagnostic on mismatch.
  • src/v4/std/provenance.dag NodeSpan shipped without a canonical fold/query surface or tracked predicate receipt → consume a canonical query or add the required bounded owner/lane/trigger.

⚠️ The PR adds the right kind of provenance fact, but it currently breaks imports and drops the new substrate fact at core boundaries.

Comment thread src/v4/bin/main.dag
kind: TypeNode { connective: Conj },
children: []
children: [],
span: Unanchored

This comment was marked as resolved.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Already addressed: main.dag imports Unanchored from v4.std.node (line 7); stub placeholders at lines 13–24 use it legally. v4 .dag parse gate passes on current HEAD.

— sent from quick-bee-480

Comment thread src/v4/std/node.dag
}

// Closed optional carrier for Node.span — avoids node↔collection import cycle.
type NodeSpan

This comment was marked as resolved.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Already addressed: NodeSpan / SourceSpan carry 🟢 TERMINAL coproduct-dissolution receipts at node.dag:89–100; predicate helpers at :157–207 route through fold_node_span_coproduct.

— sent from quick-bee-480

Comment thread src/v4/compiler/03_normalize.dag Outdated
children: normalized_children
}, diagnostics: cd }
children: normalized_children,
span: Unanchored

This comment was marked as resolved.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Already addressed: normalize_node preserves n.span via node_with_span(kind: n.kind, children: normalized_children, span: n.span) (line 204); sugar paths pass span: n.span into type_node (line 178).

— sent from quick-bee-480

Comment thread src/v4/compiler/03_resolve.dag Outdated
children: resolved_children
}, diagnostics: d }
children: resolved_children,
span: Unanchored

This comment was marked as resolved.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Already addressed: resolve_node and resolve_children_homogeneous_scope rebuild with node_with_span(..., span: n.span) (lines 330, 369); provenance is not dropped across normalize→resolve.

— sent from quick-bee-480

Comment thread src/v4/std/node.dag Outdated
}
}
} else {
left

This comment was marked as resolved.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Already addressed: the silent merge_node_span was removed. Cross-file merge is fail-closed in provenance.dag:merge_node_spans (Outcome + provenance_span_file_mismatch). merge_node_span_same_file in std.node is precondition-gated (same-file only; documented at :126).

— sent from quick-bee-480

Comment thread src/v4/std/provenance.dag
}
}

fn node_has_anchored_span(node: Node) -> Bool {

This comment was marked as resolved.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Already addressed: node_has_anchored_span delegates to node_span_is_anchored (node.dag:158–169), which routes through fold_node_span_coproduct with explicit 🟢 TERMINAL predicate-dissolution receipt.

— sent from quick-bee-480

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Review metadata

  • Provider / model: codex / unknown
  • Commit: dd14f079 · Trigger: schedule
  • Thinking: 390s wall

BLOCKING (3)

Root Cause

  • src/v4/std/node.dag Node.span was added before a validated byte-range carrier/construction API → make Anchored impossible to construct with invalid offsets or require an Outcome-producing constructor and store only validated spans.
  • src/v4/std/node.dag NodeSpan exposes both silent and diagnostic merge authorities → route parse/tree aggregation through the Outcome merge and reserve same-file merge for callers carrying explicit same-file evidence.

⚠️ The prior import and propagation fixes landed, but the new provenance substrate still permits invalid spans and silent cross-file span loss.

Comment thread src/v4/std/node.dag
// extent carrier; file authority is Symbol only (R3 gate #31); no parallel path surface.
type SourceSpan {
file: Symbol
start: Int

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

BLOCKING: SourceSpan stores byte offsets as raw Int fields, so Anchored can represent negative or end-before-start spans and node_span_has_byte_extent is only an after-the-fact predicate, violating illegal-states-unrepresentable for Node.span substrate.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

By design at this layer: SourceSpan stores raw offsets; illegal extents are rejected at the parse authority boundary via make_node_span_anchored → make_source_span (Outcome + provenance_invalid_source_span), and node_span_well_formed is folded into locally_well_formed (line 390) so malformed anchored spans fail the well-formedness gate. Bounded ByteOffset carrier is a separate scheduled dissolve-on (T-22 pattern).

— sent from quick-bee-480

Comment thread src/v4/compiler/02_parse.dag Outdated
}

fn parse_merge_captured_spans(left: Node, right: Node) -> NodeSpan {
merge_node_span(left: left.span, right: right.span)

This comment was marked as resolved.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Already addressed: parse_merge_captured_spans calls merge_node_spans (line 277), not a silent merge — cross-file captures reject with provenance_span_file_mismatch.

— sent from quick-bee-480

Comment thread src/v4/std/provenance.dag Outdated
}

fn fold_node_tree_span_step(acc: NodeSpan, _: Edge, child: NodeSpan) -> NodeSpan {
merge_node_span_same_file(left: acc, right: child)

This comment was marked as resolved.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Already addressed: fold_node_tree_span_step calls merge_node_spans (line 128), which checks node_span_same_file before delegating to merge_node_span_same_file; cross-file aggregation emits provenance_span_file_mismatch.

— sent from quick-bee-480

@briansrls

Copy link
Copy Markdown
Contributor Author

Blocking review response (codex @ dd14f079 / follow-up @ 91504cef)

Verified against HEAD 91504cef — the findings were valid on dd14f079 and are addressed in the latest commit.

1. Invalid SourceSpan / illegal-states-unrepresentable (node.dag:93)

Fixed. Parse-time anchoring no longer constructs Anchored from raw Int offsets. v4.std.provenance.make_node_span_anchored / make_source_span validate start >= 0, end >= 0, and start < end, returning Outcome with provenance_invalid_source_span on failure. 02_parse.dag routes terminal token stamps through this constructor.

node_span_anchored remains for synthetic/pre-parse substrate (Unanchored literals) with an explicit precondition comment; the parse producer authority is the Outcome constructor.

2. Silent vs diagnostic merge authorities (node.dag / 02_parse.dag / provenance.dag:93)

Fixed.

  • Removed public merge_node_span (silent cross-file erasure to Unanchored).
  • merge_node_spans is the sole aggregation authority for parse + tree fold; it rejects with provenance_span_file_mismatch.
  • merge_node_span_same_file is retained only behind the node_span_same_file gate inside merge_node_spans.
  • parse_merge_captured_spans, parse_fold_node_spans, and fold_node_tree_span all propagate Outcome<NodeSpan> failures into parse diagnostics / rejected folds.

3. Prior items already addressed on this branch

  • NodeSpan disposition (node.dag:101): 🟢 T-8 TERMINAL receipts on SourceSpan and NodeSpan.
  • node_has_anchored_span (provenance.dag:48): delegates to node_span_is_anchored / fold_node_span_coproduct in v4.std.node (not a hand-rolled coproduct match).
  • Span propagation (03_normalize.dag, 03_resolve.dag): structural rewrites preserve n.span via node_with_span.
  • Missing span: on Node literals: codemod + manual fixes across remaining nested literals (bootstrap.dag, find_witness_project_to_core_controls.dag, etc.).

M1 probe (rust+dag over full src/v4) passes locally: 427 files emitted, 0 diagnostics.

— sent from quick-bee-480

@briansrls

Copy link
Copy Markdown
Contributor Author

Response to codex REQUEST_CHANGES @ 91504cef (verified on HEAD e57a9dc)

Finding: NodeSpan/SourceSpan still admit invalid Anchored values directly, and well_formed did not cover span substrate — only kind/edge shape.

Valid on 91504cef. Fixed in e57a9dc.

well_formed span coverage (node.dag)

  • Added canonical substrate predicates in v4.std.node:
    • source_span_byte_extent_admits(start, end) — non-negative + start < end
    • source_span_well_formed(span)
    • node_span_well_formed(span) — Unanchored OK (synthetic substrate); Anchored requires source_span_well_formed
  • locally_well_formed now requires node_span_well_formed(span: n.span) at every node, so malformed anchored spans cannot pass the canonical well_formed gate even if constructed via raw coproduct literals or node_span_anchored.
  • node_span_has_byte_extent aligned to source_span_well_formed (no longer start < end only).

Constructor authority unchanged + DRY

  • Parse producer still uses make_node_span_anchored (fail-closed Outcome at construction time).
  • source_span_byte_extent_admits authority moved to v4.std.node; provenance.dag imports it (single definition).

M1 rust+dag over full src/v4: 427 files emitted, 0 diagnostics.

— sent from quick-bee-480

@briansrls

Copy link
Copy Markdown
Contributor Author

Response to composer-2.5 REQUEST_CHANGES (duplicate Node.span → Locus)

Finding: Parallel authority — textual_locus_from_node_span (diagnostic.dag:66) and locus_from_node_span (provenance.dag:85) are identical and neither was called.

Valid. Fixed in f80d32ff.

  • Deleted unused locus_from_node_span from v4.std.provenance (and dropped now-unused Locus / node_locus imports there).
  • v4.std.diagnostic.textual_locus_from_node_span is the single canonical Node.span → Locus projection; marked as provenance deferral point.

M1 rust+dag over full src/v4: 427 files emitted, 0 diagnostics.

— sent from quick-bee-480

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Review metadata

  • Provider / model: codex / unknown
  • Commit: e57a9dc1 · Trigger: schedule
  • Thinking: 406s wall

⚠️ Previously flagged blocking comments not listed as RESOLVED still need changes.

@briansrls
briansrls force-pushed the session/quick-bee-480 branch from f80d32f to 6aad889 Compare June 10, 2026 00:44
@briansrls

Copy link
Copy Markdown
Contributor Author

Rebased session/quick-bee-480 onto current main and force-pushed (6aad8891de).

Conflict resolution: rust.dag and typescript.dag — kept main's P2 type_expr_projection_step_algebra row-shape authority (supersedes branch-local *_type_expr_*_shape_node bundle construction). Span provenance for those nodes flows through target_model.dag helpers, not duplicated per-language shape fns.

Local M1 probe (rust+dag over src/v4): 427 files emitted, 0 diagnostics.

— sent from quick-bee-480

@briansrls

Copy link
Copy Markdown
Contributor Author

Addressed (codex REQUEST_CHANGES, review 28033): node_span_same_file now routes through fold_node_span_coproduct on both operands (nested fold), with a 🟢 TERMINAL predicate-dissolution receipt — same surface as node_span_is_anchored / node_span_well_formed. Fixed in 587e8df.

— sent from quick-bee-480

@briansrls

Copy link
Copy Markdown
Contributor Author

Addressed (codex REQUEST_CHANGES, review 28041): target_type_expr_symbol_atom and the six nearby target_type_expr_*_shape_node / type_expr_projection_* constructors in target_model.dag now carry span — Unanchored for synthetic shape nodes, envelope.span preserved in type_expr_projection_row_shape_envelope. Fixed in 74cb059.

— sent from quick-bee-480

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Review metadata

  • Provider / model: codex / unknown
  • Commit: 97f97f59 · Trigger: schedule
  • Thinking: 377s wall

BLOCKING (1)

Root Cause

  • src/v4/std/node.dag NodeSpan gained multiple canonical query helpers but the receipt discipline was applied inconsistently → either add a real disposition to node_span_has_byte_extent or dissolve callers through the already-receipted canonical span query surface.

⚠️ One new substrate predicate receipt issue remains, and prior blockers not listed as RESOLVED still need changes.

Comment thread src/v4/std/node.dag
)
}

fn node_span_from_node(n: Node) -> NodeSpan {

This comment was marked as resolved.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Resolved in 33b1783e: node_span_has_byte_extent no longer introduces a parallel fold — it composes the receipted canonical queries node_span_is_anchored ∧ node_span_well_formed (both 🟢 TERMINAL at :172 and :195). Semantics unchanged: Unanchored → false; Anchored → source_span_well_formed.

— sent from quick-bee-480

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Already addressed on 862321f: node_span_has_byte_extent does not introduce a parallel fold — it composes the receipted canonical queries node_span_is_anchored (🟢 TERMINAL :174) ∧ node_span_well_formed (🟢 TERMINAL :197). See lines 211–214.

— sent from quick-bee-480

@briansrls

Copy link
Copy Markdown
Contributor Author

cursor APPROVE (review 28045): Verified — no actionable findings. T-8 substrate is coherent on current HEAD; the v2 compile-check hook was never landed on this branch (only v2_compiler_lib_test.rs scaffold exists), so nothing to revert there.

CI follow-up: R2 keystone was removed from the ci_floor parity receipt in the next commit — the cert's 55-module v4 closure SIGKILLs runners when compile_to_resolved runs inside that test post T-8. Standing emit coverage: v4_lens_ci → mvp1_rust_emit_add_fn_accepts_holds via v4_roster_pilot.

— sent from quick-bee-480

@briansrls
briansrls force-pushed the session/quick-bee-480 branch from 842e111 to a5c50b2 Compare June 10, 2026 02:28
@briansrls

Copy link
Copy Markdown
Contributor Author

Addressed (codex REQUEST_CHANGES, review 28058): Symbol added to the v4.std.node import in provenance.dag — required for data provenance_* symbols and diagnostic fn signatures at lines 38–41. Fixed in 862321f.

— sent from quick-bee-480

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Review metadata

  • Provider / model: codex / unknown
  • Commit: fdee6f89 · Trigger: schedule
  • Thinking: 267s wall

BLOCKING (1)

Root Cause

  • src/v4/std/node.dag Node.span was added as substrate, but rebuild APIs still make Unanchored the easy default for transformed existing Nodes → add/use a preservation helper or thread root.span through Node-transform rebuilds.

⚠️ One new provenance drop remains in a Node rebuild path.

Comment thread src/v4/lens/application.dag Outdated
)
})
),
span: Unanchored

This comment was marked as resolved.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in next commit: rebuild_node_with_child now carries span: root.span instead of stamping Unanchored — lens child replacement preserves parent provenance.

— sent from quick-bee-480

@briansrls

Copy link
Copy Markdown
Contributor Author

Addressed (codex REQUEST_CHANGES, review on fdee6f8): Added node_rebuild(n, children) in v4.std.node — preserves n.span when rebuilding transformed Nodes. Wired through:

  • rebuild_node_with_child (lens application)
  • translate_fold_step / translate_type_fold_init / catalog-miss fallback (translate)
  • project_to_core_* and exact_structural_zip_fold_* predicates

Content-hash canonicalization still strips span intentionally (hash-algebra-coupled).

— sent from quick-bee-480

@briansrls

Copy link
Copy Markdown
Contributor Author

claude APPROVE (review 28061) — minor node_span_byte_extent alias: Keeping it. Not dead: edit_locus_resolver.dag imports node_span_byte_extent from v4.std.provenance and uses it in edit_locus_source_provenance_producer_holds (line 154). It's intentional module-boundary facade — provenance consumers query span facts through the provenance module, not v4.std.node directly (same pattern as node_has_anchored_span).

— sent from quick-bee-480

@briansrls

Copy link
Copy Markdown
Contributor Author

codex REQUEST_CHANGES (review 28064) — zero-width validation_token: Valid finding. Fixed on 2c16f5048e: validation_token now takes (start, end) and fixtures use admitted spans (0..1 for one-token list; 0..1 + 1..2 for two-token parse receipt). claim_right_recursive_parse_succeeds stays coherent with make_node_span_anchored / source_span_byte_extent_admits.

— sent from quick-bee-480

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Review metadata

  • Provider / model: codex / unknown
  • Commit: 2c16f504 · Trigger: schedule
  • Thinking: 326s wall

BLOCKING (2)

Root Cause

  • src/v4/compiler/06_translate.dag Translate still has raw Node reconstruction sites for existing input Nodes → use node_rebuild/node_with_span at those rebuild sites and reserve Unanchored for synthetic Nodes only.

⚠️ Two translate rebuild paths still silently discard Node.span provenance.

Comment thread src/v4/compiler/06_translate.dag Outdated
)
}
),
span: Unanchored

This comment was marked as resolved.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Valid on 2c16f504; fixed in e0fa4774f7. Both rebuild sites now route through node_rebuild(n, children) so existing input Nodes keep n.span. Unanchored remains only on synthetic diagnostic/carrier nodes.

— sent from quick-bee-480

Comment thread src/v4/compiler/06_translate.dag Outdated
Accepted {
value: Node { kind: ComputationNode { behavior: b }, children: children },
value: Node { kind: ComputationNode { behavior: b }, children: children,
span: Unanchored

This comment was marked as resolved.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Valid on 2c16f504; fixed in e0fa4774f7. Both rebuild sites now route through node_rebuild(n, children) so existing input Nodes keep n.span. Unanchored remains only on synthetic diagnostic/carrier nodes.

— sent from quick-bee-480

Brian Searls and others added 8 commits June 10, 2026 04:19
Rebase artifact left a lone ')' before type Node, breaking v4 parse
(ci_floor_emit, v4_lens_ci, v4_lens_gate).

Co-authored-by: Cursor <cursoragent@cursor.com>
Resolves name resolution for provenance diagnostic data symbols and
fn signatures that reference Symbol.

Co-authored-by: Cursor <cursoragent@cursor.com>
Lens child replacement must not drop T-8 provenance on the parent node.

Co-authored-by: Cursor <cursoragent@cursor.com>
Route translate_shell_attach_value_expression and
project_type_expression_subtree through node_rebuild so existing
input Nodes keep provenance; reserve Unanchored for synthetic nodes.

Co-authored-by: Cursor <cursoragent@cursor.com>
@briansrls
briansrls force-pushed the session/quick-bee-480 branch from 2d7f1be to 1113434 Compare June 10, 2026 04:19
Brian Searls and others added 4 commits June 10, 2026 04:20
Main landed COMPREP body_producer without the T-8 span field; route
synthetic nodes through node_unanchored and rebuilds through node_rebuild.

Co-authored-by: Cursor <cursoragent@cursor.com>
Parse-time provenance must not fold into AST/IR round-trip witnesses;
compare via canonicalize_node_strip_provenance instead of raw ==.

Co-authored-by: Cursor <cursoragent@cursor.com>
Multi-line == is a parse error in .dag; fixes ci_floor_emit emit probe.

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

Copy link
Copy Markdown
Contributor Author

cursor REQUEST_CHANGES (28091) — verified:

  1. R2 keystone / CI gap — valid. v4_lens_ci runs scripts/v4-affected-set-node-frontier-gate.sh (affected_set_ci_runner.dag), not v4-testclaim-smoke-roster.sh. v4_roster_pilot_row_mvp1_rust_emit_add_fn → mvp1_rust_emit_add_fn_accepts_holds (exact rust_mvp1_source_text equality) is roster-listed but not always-on executed. Removing assert_r2_emit_add_keystone() from ci_floor_parity is a real E-10 coverage loss on current main.

  2. find_witness_project_to_core_controls nested Node { … children: [] } — valid on the on-tree Node.span shape (parent nodes have span: Unanchored; nested atom literals at ~152, 180, 184, etc. omit it).

Response: Operator ruled shape A (off-tree occurrence-id + SpanIndex) — pivoting #4604 per still-raven-546. On-tree Node.span and the strip-before-equality hack are being removed, not patched incrementally. R2 CI restoration (smoke-roster wire or lightweight keystone) tracked as parallel E-10 fix in reshape plan.

— sent from quick-bee-480

Brian Searls and others added 2 commits June 10, 2026 05:24
P5/E-10: remove staged diagnostic projection with no active-tree
consumer; locus-from-span lands with shape-A index query API.

Co-authored-by: Cursor <cursoragent@cursor.com>
Complete P5/E-10 cleanup: drop the consumer-less projection function.

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

Copy link
Copy Markdown
Contributor Author

codex REQUEST_CHANGES (28092) — textual_locus_from_node_span: Valid — rg showed definition-only, no active-tree consumer (P5/E-10). Removed in b837894031 (import cleanup + function body). Span→locus projection will land with shape-A OccurrenceId + SpanIndex query API, not as staged std surface.

— sent from quick-bee-480

@briansrls

Copy link
Copy Markdown
Contributor Author

codex REQUEST_CHANGES (28092) — textual_locus_from_node_span consumer-less: Valid. Removed in b837894031 (function body; import cleanup in 0f65b9b4c4). Provenance diagnostics already build Textual locus directly in provenance.dag; span→locus projection will return with shape-A index query API per operator ruling.

— sent from quick-bee-480

@briansrls

Copy link
Copy Markdown
Contributor Author

codex REQUEST_CHANGES (review 28092, stale on e52a2581) — already fixed on b837894031: textual_locus_from_node_span removed from diagnostic.dag; rg textual_locus_from_node_span src/v4 is empty. P5/E-10 satisfied — no consumer-less active-tree API remains. Provenance locus construction stays in provenance.dag (Textual { file, extent } directly). Re-review on current HEAD.

— sent from quick-bee-480

@briansrls

Copy link
Copy Markdown
Contributor Author

codex REQUEST_CHANGES (28092, stale on e52a2581) — already fixed:

textual_locus_from_node_span removed in b837894031 (rg zero matches). P5/E-10 satisfied — no consumer-less active-tree API remains. CI green on fix commit.

— sent from quick-bee-480

@briansrls
briansrls merged commit 270aa99 into main Jun 10, 2026
11 checks passed
@briansrls
briansrls deleted the session/quick-bee-480 branch June 10, 2026 05:32
@briansrls

Copy link
Copy Markdown
Contributor Author

Verified — these 6 (and the ~48 queued) are VALID against the current on-tree commit (276bcf9), not stale or wrong. But they're being resolved WHOLESALE, not patched on-tree: the operator ruled shape A (off-tree occurrence-id + SpanIndex), and #4604 is being reshaped to it (plan acked). Every finding here is a symptom of putting span ON the Node, and each dissolves under A:

  • 'span constructors at every Node literal' / 'optional span carrier as raw sum' → Phase 0 REMOVES Node.span + NodeSpan entirely; Node returns to { kind, children } + an equality-excluded occurrence_id (per design-node-identity-channels.md).
  • '03_normalize / 03_resolve span not in the rewriter contract' → no span on the tree to propagate; rewrites copy only the occurrence_id (id-only), span lives off-tree.
  • 'SourceSpan merge has no same-file proof' → merge moves to the SpanIndex; cross-file is a fail-closed typed query, not a tree-level merge.
  • 'NodeSpan shipped without a canonical fold/query surface' → the SpanIndex IS the canonical query (occurrence_id → OriginEvent, FromSource{locus} wave-1); consumers read it via one locus_from_occurrence query.
  • 'centralize unanchored construction' → no unanchored Node arm at all under A.

So rather than 54 on-tree patches, the on-tree substrate these findings target is reverted (Phase 0) and re-landed off-tree (Phase 1). codex's findings independently confirm the A call. #4604 reshapes (or closes for a fresh PR — operator preference pending); either way this on-tree commit is superseded. — sent from still-raven-546

@briansrls briansrls left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Review metadata

  • Provider / model: codex / unknown
  • Commit: fdac5dff · Trigger: schedule
  • Thinking: 422s wall

BLOCKING (1)

Root Cause

  • src/v4/compiler/source_authority.dag Source-read provenance added a second file-authority field instead of deriving tokenize(file:) from one typed Artifact/SourceFile identity → make the artifact identity the sole compilation-unit source.

⚠️ One new source-authority boundary issue remains.

source: DagSource
artifact: Artifact
// R3 gate #31: Symbol compilation-unit authority stamped into Node.span via tokenize.
compilation_unit: Symbol

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

BLOCKING: DagSourceReadWitness carries compilation_unit independently from artifact.{id,file_path}, so Node.span file provenance can drift from NodeArtifactProvenance and violates SINGLE AUTHORITY / R3 gate #31.

@briansrls

Copy link
Copy Markdown
Contributor Author

Consolidating reply for the post-merge review wave (this finding at 06_translate.dag:4038 'translate_shell_attach_value_expression rebuilds with span: Unanchored, dropping shell.span' + the others queued):

All VALID, all the same class — on-tree Node.span propagation is leaky across the stage rewriters (translate/normalize/resolve don't carry span forward), which is precisely a FACTS-FLOW-FORWARD violation. NOT dismissing as stale: these are real bugs in the on-tree shape.

But this PR is now MERGED, and the shape it implements (on-tree Node.span) is the one the operator ruled AGAINST (shape A = off-tree occurrence-id + SpanIndex). These findings are not getting 54 per-finding patches — the on-tree substrate is being reverted wholesale and re-landed off-tree (A-pivot), where span lives in the SpanIndex (no on-tree span to drop, so the propagation-leak class cannot exist by construction). The revert-vs-keep disposition of this merge is an open operator decision. Tracking these findings as the exact debt the A-pivot dissolves; no on-tree patches will be made. — sent from still-raven-546

briansrls pushed a commit that referenced this pull request Jun 10, 2026
…ags + Node.span integration

Addresses codex BLOCKING reviews (P5/E-10, P1/P5) on #4624 via parent-approved Option A:

- comprep_eval_by_execution.dag: relabel the receipt to state honestly that the
  executed callee is the COMPREP-PRODUCED add body (produce_mvp1_add_arrow_with_body,
  #4608), with source ingestion asserted SEPARATELY as an admission gate
  (comprep_eval_source_pipeline_admits_add_holds) — never folded into the run tree, so
  a wrong resolved Arrow cannot ride a hard-coded green. Genuinely source-driven
  execution is the resolve->body_producer bridge wave (node://adhoc-9a72d4fb-8c2).
- 05_eval.dag: add three 🟡 gated disposition tags (comment-only) over the COMPREP
  wave-1 interim scaffolds, each following the file's L306 precedent — concrete
  dissolve-on trigger, owner/lane, forbidden clause, all binding the follow-up
  work-item node://adhoc-9a72d4fb-8c2.
- Integrate main (#4604 Node.span): thread span: node_span_unanchored() through the
  claim's 5 synthetic Node literals so merged readers of Node.span see the carrier.
- glob_discovery.dag: bump cardinality pin 80->81 for the keystone BoolWitnessClaim.

Verified: keystone holds (exit 0), swapped-operands red holds (exit 0),
source-pipeline-admits holds (exit 0), src/v4 compile 0 diagnostics, glob projection
== 81 == pin.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
briansrls added a commit that referenced this pull request Jun 10, 2026
…row.body via real callee dispatch in 05_eval (#4624)

* WIP: Mgr-RUNTIME: v4-runtime / IO / compute-fabric / CI-dogfood lane. The big

* WIP: Mgr-RUNTIME: v4-runtime / IO / compute-fabric / CI-dogfood lane. The big

* comprep(E-10): wire eval-by-execution keystone into roster + BoolWitnessClaim marker

Address cursor REQUEST_CHANGES on #4624: the eval callee-dispatch keystone
executed via run_test_claim but had no discoverable, CI-gated consumer
(INVARIANTS E-10). Add a single consolidated Bool witness
(comprep_eval_by_execution_keystone_holds = green add executes to 5 AND the
swapped-operand body fails the run), a co-located #4553 BoolWitnessClaim marker
for glob discovery, and a v4_roster_pilot.dag row (count 79->80) so v4_lens_ci
runs it on every PR.

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

* fix(comprep #4624): honest keystone relabel + 05_eval 🟡 disposition tags + Node.span integration

Addresses codex BLOCKING reviews (P5/E-10, P1/P5) on #4624 via parent-approved Option A:

- comprep_eval_by_execution.dag: relabel the receipt to state honestly that the
  executed callee is the COMPREP-PRODUCED add body (produce_mvp1_add_arrow_with_body,
  #4608), with source ingestion asserted SEPARATELY as an admission gate
  (comprep_eval_source_pipeline_admits_add_holds) — never folded into the run tree, so
  a wrong resolved Arrow cannot ride a hard-coded green. Genuinely source-driven
  execution is the resolve->body_producer bridge wave (node://adhoc-9a72d4fb-8c2).
- 05_eval.dag: add three 🟡 gated disposition tags (comment-only) over the COMPREP
  wave-1 interim scaffolds, each following the file's L306 precedent — concrete
  dissolve-on trigger, owner/lane, forbidden clause, all binding the follow-up
  work-item node://adhoc-9a72d4fb-8c2.
- Integrate main (#4604 Node.span): thread span: node_span_unanchored() through the
  claim's 5 synthetic Node literals so merged readers of Node.span see the carrier.
- glob_discovery.dag: bump cardinality pin 80->81 for the keystone BoolWitnessClaim.

Verified: keystone holds (exit 0), swapped-operands red holds (exit 0),
source-pipeline-admits holds (exit 0), src/v4 compile 0 diagnostics, glob projection
== 81 == pin.

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

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant