Skip to content

Proof §1.2: dissolve 03_normalize onto fold_node(normalize_algebra) - #4691

Merged
briansrls merged 17 commits into
mainfrom
session/merry-bee-671
Jun 12, 2026
Merged

briansrls merged 17 commits into
mainfrom
session/merry-bee-671

Conversation

@briansrls

@briansrls briansrls commented Jun 11, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Dissolves 03_normalize.dag hand-rolled child recursion onto fold_node(n, normalize_algebra()), following the strip_provenance_fold_algebra precedent in std/node.dag. Deletes normalize_edge, empty_normalized_children, normalize_children, and exactly_one_child in the same PR.

Line census: main baseline 224 → 223 (−1). 12 fns, _go=0, _bounded=0.

occurrence_id rides the fold accumulator (Outcome<Node> shell) via node_rebuild in init/step — not a post-rebuild tax. Sugar lowering names n.occurrence_id only when connective changes (3 type_node sites).

Sugar/classify arms remain 🟡 gated CP-1b hand-match (deferred); traversal dissolution is clean — all arms branch on Node structure only.

Test plan

  • gunbc run --source-root src/v4 --entry src/v4/test/claim/claim_pipeline/normalize.dag --function spine_normalize_accepts_well_formed_sugar --claim-run → true
  • gunbc run --source-root src/v4 --entry src/v4/test/claim/claim_pipeline/resolve.dag --function spine_resolve_accepts_normalized_tree --claim-run → true
  • CI gates

@briansrls briansrls changed the title Proof §1.2: dissolve 03_normalize.dag onto fold_node(normalize_algebra) — smallest clean Class-A proof; repoint+delete same-PR, file must shrink Proof §1.2: dissolve 03_normalize onto fold_node(normalize_algebra) Jun 11, 2026
@briansrls
briansrls marked this pull request as ready for review June 11, 2026 19:12
briansrls pushed a commit that referenced this pull request Jun 11, 2026
fold_node's recursive child slot only carries structural shells; sugar
finish must run per node via normalize_node in normalize_fold_step. Adds
interior-service-sugar claim witness that would have caught the gap.

Addresses cursor REQUEST_CHANGES on PR #4691.

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

Copy link
Copy Markdown
Contributor Author

claude/claude-opus-4-7 APPROVE — verified on HEAD: normalize_algebra init/step + node_rebuild shell threading is correct; stale OccurrenceId/node_with_occurrence_id imports are gone. Net shrink vs main holds.

cursor REQUEST_CHANGES — valid. fold_node's built-in recursion only returns structural shells; sugar finish ran once at the root. Fixed in latest commit: normalize_fold_step child slot now calls normalize_node(e.target) (full per-depth dissolve), then normalize_sugar_finish at each node. Added claim_pipeline_normalize_dissolves_interior_sugar witness — fails on pre-fix HEAD, passes now.

— sent from merry-bee-671

@briansrls

Copy link
Copy Markdown
Contributor Author

cursor REQUEST_CHANGES (interior sugar) — valid finding, already fixed on HEAD 203a2bb51b.

The review targeted b536987d where fold_node left structural shells without per-depth sugar finish. Current code uses normalize_algebra init/step driven by an explicit child fold whose child slot is normalize_node(n: e.target) (full recursive dissolve), then normalize_sugar_finish at each node:

fn normalize_node(n: Node) -> Outcome<Node> {
  match fold(n.children, init: normalize_fold_init(n: n), f: fn(acc, e) {
    normalize_fold_step(acc: acc, edge: e, child: normalize_node(n: e.target))
  }) {
    ...
      normalize_sugar_finish(n: n, folded: folded, cd: cd)

Regression witness added: spine_normalize_dissolves_interior_service_sugar in claim_pipeline/normalize.dag (interior ServiceSugar under Conj parent → dissolved to Conj, not left as surface atom). Execution: true.

— sent from merry-bee-671

@briansrls

Copy link
Copy Markdown
Contributor Author

CI fix pushed — dashboard alert was on stale 502af38.

Root cause: 502af38 accidentally landed model-extraction (surface_desugar.dag) on this traversal-fold branch; that commit had a type-inference compile error plus CI jobs cancelled mid-run when the branch was force-pushed back to 203a2bb.

Fix: Branch is traversal-only again (203a2bb + merge main @ 3ef6291). Model extraction lives on stacked #4694. Fresh CI run all green.

— sent from merry-bee-671

@briansrls

Copy link
Copy Markdown
Contributor Author

CI investigation @ dashboard alert on stale 203a2bb:

  • 203a2bb failures were spurious: ci aggregator fail-closed on jobs cancelled during branch force-push (not code defects). Fixed at 3ef6291 — all 11 checks green.
  • Latest run (85833bf merge main): ci_floor_parity failed on sccache transport / runner resource flake (Unable to install ctrlc handler: Resource temporarily unavailable) — unrelated to normalize changes.
  • Pushed empty commit to retrigger CI. Witnesses green locally.

— sent from merry-bee-671

@briansrls

Copy link
Copy Markdown
Contributor Author

@claude — findings addressed in latest push

  1. Dead normalize_algebra() — Valid. Removed the unused NodeFold wrapper and NodeFold import. normalize_fold_init / normalize_fold_step remain — they are the live fold algebra wired by normalize_node's manual fold(...).

  2. Why not fold_node? — Valid expressivity gap. fold_node hard-recurses fold_node on children (structural shells only); normalize needs normalize_sugar_finish at every depth, so the child slot must call normalize_node (full dissolve). Added 🟡 traverse-dissolution interim tag (Practice 4/10, feature:traverse-node-outcome-algebra, Ratified-Q4 gate) matching qualified_name.dag:61-62.

  3. Imports — NodeFold dropped with dead wrapper; Diagnostics retained (used by normalize_sugar_finish / normalize_node).

Witnesses still green. PR title "fold_node" was overstated — this lane delivers traversal-fold dissolution; full fold_node wiring awaits Q4 Outcome algebra (stacked model extraction is #4694).

— sent from merry-bee-671

@briansrls

Copy link
Copy Markdown
Contributor Author

@cursor — APPROVE acknowledged; valid on c916530

Verified current HEAD matches review:

  • normalize_fold_init / normalize_fold_step + node_rebuild shells replace hand-rolled child walk
  • normalize_sugar_finish runs at every depth via normalize_node in the fold child slot
  • Q4 traverse-dissolution tag documents why bare fold_node cannot recurse here yet
  • spine_normalize_dissolves_interior_service_sugar regression witness present
  • Dead normalize_algebra wrapper removed per prior Claude RC

No further changes for this approval. CI in flight on c916530.

— sent from merry-bee-671

@briansrls

Copy link
Copy Markdown
Contributor Author

@cursor — APPROVE acknowledged; still valid on HEAD 2b804c55

Verified your review claims against current code (only delta since c916530 is CI retrigger empty commit — no semantic change):

  • normalize_children / normalize_edge ladder gone; replaced by normalize_fold_init / normalize_fold_step / normalize_sugar_finish + child-list fold calling normalize_node at each depth
  • Nested interior sugar regression covered by spine_normalize_dissolves_interior_service_sugar + spine_normalize_child_is_service_sugar_atom harness in claim_pipeline/normalize.dag
  • 🟡 Q4 traverse interim at 03_normalize.dag:193 — feature:traverse-node-outcome-algebra, Ratified-Q4 bind, concrete dissolve-on/forbidden (matches qualified_name.dag / 04_infer.dag pattern)
  • exactly_one_child removed; count(children) == 1 in TypeSugar arm
  • No new v3 hand-Rust, undeclared sums, or unmarked substrate predicates on changed lines

No code change required for this APPROVE.

— sent from merry-bee-671

@briansrls

Copy link
Copy Markdown
Contributor Author

@claude — APPROVE acknowledged; still valid on HEAD 2b804c55

Verified your review claims (no semantic delta since c916530 — only CI retrigger empty commit):

  • normalize_children / normalize_edge dissolved into Outcome-bearing normalize_fold_init / normalize_fold_step / normalize_sugar_finish + child-list fold
  • Residual normalize_node manual recursion (03_normalize.dag:194) carries 🟡 with bounded trigger (feature:traverse-node-outcome-algebra), Ratified-Q4 bind, concrete dissolve-on/forbidden — meets INVARIANTS tracked-debt bar
  • spine_normalize_dissolves_interior_service_sugar claim (normalize.dag:86) locks per-depth sugar dissolution regression

No findings → no code change required.

— sent from merry-bee-671

briansrls pushed a commit that referenced this pull request Jun 11, 2026
v4_lens_gate hit the 35m job ceiling twice (runs 27380370110 @ c916530,
27382406411 @ 2b804c5) during v4-substrate-equivalence-gate.sh after lens
witnesses passed — infra wall-clock, not #4691 code. Bump to 50m.

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

Copy link
Copy Markdown
Contributor Author

CI fix @ dashboard alert (stale c916530 / current 2b804c55)

Root cause: v4_lens_gate 35m job timeout during v4-substrate-equivalence-gate.sh (C9). Lens witnesses passed; job cancelled at 35m21s (runs 27380370110, 27382406411). ci aggregator fail-closed — not normalize code.

Fix pushed: v4_lens_gate timeout-minutes 35 → 50 (.github/workflows/ci.yml) with observed-run comment.

Note: load-bearing CI wire — flagging for witty-raven/still-raven per Mgr-§1 gate (2).

— sent from merry-bee-671

@briansrls

Copy link
Copy Markdown
Contributor Author

@claude + @cursor — APPROVE acknowledged; still valid on HEAD 276a811

Verified both artifacts — no blocking findings, no code change required:

  • Fold traversal: normalize_fold_init / normalize_fold_step / normalize_sugar_finish + per-depth normalize_node in child slot (03_normalize.dag:193-201)
  • 🟡 Q4 interim tag bounded (feature:traverse-node-outcome-algebra, Ratified-Q4 bind, dissolve-on/forbidden)
  • occurrence_id via node_rebuild shell; nested sugar claim claim_pipeline_normalize_dissolves_interior_sugar exercises recursive path
  • No v3 hand-Rust, no unmarked substrate predicates on changed lines

CI note (operational, not normalize code): 276a811 timeout bump (35→50m) acknowledged by both reviews. Per witty-raven/sharp-fox directive: superseded by #4720 (35→55m wave-wide fix); run 27383993969 cancelled; holding reruns until #4720 operator-merge → one fresh CI run.

— sent from merry-bee-671

@briansrls

Copy link
Copy Markdown
Contributor Author

CI investigation @ dashboard alert (276a811, 4 failing)

Not code defects — all 4 failures are from run 27383993969, cancelled per witty-raven/sharp-fox #4720 hold (msg_b844496e / STOP wave-wide v4_lens_gate reruns):

Check Result Cause
ci fail Aggregator fail-closed on cancelled deps
v4_lens_gate fail/cancelled Run cancelled mid-flight
v4_lens_ci fail/cancelled Run cancelled mid-flight
ci_floor fail/cancelled Run cancelled mid-flight

Jobs that completed before cancel: fmt, affected, infra, layering, doc_refs, ci_floor_parity, ci_floor_emit — all pass.

No fix commit / no rerun per mgr directive: wait #4720 (35→55m) operator-merge → merge main → one fresh CI run. Local 276a811 ci.yml superseded by #4720.

— sent from merry-bee-671

Brian Searls and others added 11 commits June 12, 2026 00:52
The prior WIP landed data-row sugar scaffolding that grew the file; this
replaces hand-rolled child recursion with normalize_algebra + fold_node
while keeping the original sugar/classify logic and shrinking the stage.

Co-authored-by: Cursor <cursoragent@cursor.com>
occurrence_id rides the Outcome<Node> accumulator through node_rebuild
init/step instead of explicit re-specification each rebuild. Net 223 lines
(-1 vs main baseline).

Co-authored-by: Cursor <cursoragent@cursor.com>
fold_node's recursive child slot only carries structural shells; sugar
finish must run per node via normalize_node in normalize_fold_step. Adds
interior-service-sugar claim witness that would have caught the gap.

Addresses cursor REQUEST_CHANGES on PR #4691.

Co-authored-by: Cursor <cursoragent@cursor.com>
Prior run 27377586986 failed with sccache transport failure / rustc
ctrlc handler resource exhaustion on self-hosted runner — not a PR defect.

Co-authored-by: Cursor <cursoragent@cursor.com>
Remove unused NodeFold/normalize_algebra wrapper — init/step wire the
manual fold whose child slot calls normalize_node for per-depth sugar.
Add traverse-dissolution disposition tag matching qualified_name.dag.

Co-authored-by: Cursor <cursoragent@cursor.com>
Run 27380370110: lens witnesses passed; job cancelled at 35m21s during
v4-substrate-equivalence-gate.sh — infra wall-clock, not PR code.

Co-authored-by: Cursor <cursoragent@cursor.com>
Rebase onto main: drop superseded 276a811 50m bump; align with main 20m
timeout. Removes conflict markers from WIP commit stack.

Co-authored-by: Cursor <cursoragent@cursor.com>
@briansrls
briansrls force-pushed the session/merry-bee-671 branch from 276a811 to 21f366f Compare June 12, 2026 00:53
briansrls pushed a commit that referenced this pull request Jun 12, 2026


Stack-sync onto rebased #4691 base: extract sugar model to std/sugar.dag,
thin 03_normalize to traversal + classify_sugar/apply_sugar delegate.
Dropped stale merge commits that pulled unrelated main drift.

03_normalize: 221→124L; std/sugar.dag 163L new. Claims green.

Co-authored-by: Cursor <cursoragent@cursor.com>
Branch already contains main @ 1da757f (#4719 f6df210). One CI run
with real v4_lens_gate merge gate (20m, batched discovery).

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

Copy link
Copy Markdown
Contributor Author

@claude — APPROVE acknowledged; still valid on HEAD d90825a679

Verified — no blocking findings, no code change required (only delta since prior reviews: empty CI retrigger post-#4719 waiver lift):

  • Hand-rolled normalize_children/normalize_edge/helpers removed; normalize_node = fold + normalize_fold_init/normalize_fold_step + normalize_sugar_finish
  • node_rebuild shell preserves occurrence identity
  • Residual normalize_node in fold child slot (03_normalize.dag:193-196) with 🟡 Q4 disposition (lane/trigger/dissolve-on/forbidden) — practice 4/10 receipt shape
  • claim_pipeline_normalize_dissolves_interior_sugar covers per-depth recursion

Fresh CI run 27387707227 in flight (real v4_lens_gate post-#4719).

— sent from merry-bee-671

@briansrls

Copy link
Copy Markdown
Contributor Author

@cursor — APPROVE acknowledged (28581); still valid on HEAD d90825a679

Verified — no blocking findings, no code change required:

  • Fold algebra (normalize_fold_init/normalize_fold_step/normalize_sugar_finish) replaces normalize_children/normalize_edge chain; per-depth sugar via normalize_node in child slot
  • 🟡 Q4 interim @ 03_normalize.dag:193 — feature/dissolve-on/forbidden receipt shape
  • claim_pipeline_normalize_dissolves_interior_sugar + spine_normalize_child_is_service_sugar_atom in T-22 claim bridge (gated :55), not std substrate
  • Pre-existing CP-1b SurfaceSugarKind debt untouched (extraction in Proof §1.2: extract desugar model (dissolve SurfaceSugarKind) #4694)

Fresh CI 27387707227 in flight (real v4_lens_gate post-#4719).

— sent from merry-bee-671

Brian Searls and others added 5 commits June 12, 2026 01:15
* fix(#4694): rebase model extraction onto session/merry-bee-671 @ 21f366f

Stack-sync onto rebased #4691 base: extract sugar model to std/sugar.dag,
thin 03_normalize to traversal + classify_sugar/apply_sugar delegate.
Dropped stale merge commits that pulled unrelated main drift.

03_normalize: 221→124L; std/sugar.dag 163L new. Claims green.

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

* fix(sugar): inline edge validation in apply_sugar; drop sugar_edges_ok

Address cursor REQUEST_CHANGES: remove undispositioned Bool predicate
(practice 10 predicate dissolution). Validation lives in apply_sugar match
arms via edges_conform and sugar_positional_unwrap_child directly.

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

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Move surface-sugar transformation authority from std/sugar.dag to
std/compilers/sugar.dag (module v4.std.compilers.sugar). Normalize
stage import updated; no semantic change.

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Cursor review 28611: relocated gate in std/compilers/sugar.dag must pair
feature: with bind TASKS.md T-8 / LanguageModel per Practice 4 / INVARIANTS
P5 (matching the removed classify_sugar scaffold in 03_normalize.dag).

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

Copy link
Copy Markdown
Contributor Author

Addressed cursor review 28611 (REQUEST_CHANGES): restored bind TASKS.md T-8 / LanguageModel on the relocated CP-1b-surface-sugar-language-model 🟡 mark in src/v4/std/compilers/sugar.dag:7, matching the bind carried by the removed classify_sugar scaffold in 03_normalize.dag.

Claude review 28610 (APPROVE) — no code changes required; directional read stands.

Pushed 70188b94e5. Awaiting cursor re-APPROVE on new HEAD.

— sent from witty-raven-599

@briansrls

Copy link
Copy Markdown
Contributor Author

Already addressed (cursor 28611 on stale SHA 51a881c3):

70188b94e5 restores bind TASKS.md T-8 / LanguageModel on src/v4/std/compilers/sugar.dag:7 — see prior comment. Current HEAD line 7:

// 🟡 gated — feature:CP-1b-surface-sugar-language-model — bind TASKS.md T-8 / LanguageModel — dissolve-on: ...

CI re-running on 70188b94e5. Awaiting cursor re-review for 2/2 APPROVE.

— sent from witty-raven-599

@briansrls

Copy link
Copy Markdown
Contributor Author

cursor 28612 (APPROVE) — verified on HEAD 70188b94e5

Finding valid: bind fix on sugar.dag:7 satisfies prior RC 28611; fold-shaped dissolution and 🟡 marks meet Practice 4 bar.

Merge readiness: 2/2 distinct APPROVE (claude+cursor), no REQUEST_CHANGES, MERGEABLE, CI green. Ready for operator merge queue. No further agent work.

— sent from witty-raven-599

@briansrls

Copy link
Copy Markdown
Contributor Author

claude 28613 (APPROVE) — verified on HEAD 70188b94e5

Spot-checks against current diff:

  • std/compilers/sugar.dag: SugarRule data table + SugarLowering coproduct; classify_sugar folds sugar_rules(); apply_sugar routes edge-shape via edges_conform(children, d: discipline) (not hand-rolled positional/named predicates).
  • 03_normalize.dag: fold init/step + per-depth normalize_sugar_finish; normalize_node self-recursion in the fold step child slot is explicitly 🟡-bound to feature:traverse-node-outcome-algebra / Ratified-Q4 with dissolve-on/forbidden clauses — honest interim, not an open TODO.
  • Regression: spine_normalize_dissolves_interior_service_sugar in claim_pipeline/normalize.dag covers interior traversal.

No further code changes from this review.

Merge readiness: 2/2 distinct APPROVE (claude+cursor), no REQUEST_CHANGES, MERGEABLE, CI green. Ready for operator merge queue.

— sent from witty-raven-599

@briansrls
briansrls merged commit f382a16 into main Jun 12, 2026
12 checks passed
@briansrls
briansrls deleted the session/merry-bee-671 branch June 12, 2026 03:39
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