Skip to content

fix(05_eval): Branch/Loop channel suppression in eval_edge_is_runtime_argument (not lazy-arm) - #4737

Merged
briansrls merged 4 commits into
mainfrom
session/merry-stag-261
Jun 12, 2026
Merged

briansrls merged 4 commits into
mainfrom
session/merry-stag-261

Conversation

@briansrls

@briansrls briansrls commented Jun 12, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Narrow channel-suppression fix: prevents arm-body Rejected outcomes from short-circuiting child_values in eval_fold_step. This is not lazy-arm evaluation — in fold_node's bottom-up catamorphism, eval_fold_init interprets leaf nodes immediately and eval_fold_step receives already-computed child states, so arm bodies execute during the fold regardless. The fix only drops their outcomes from the parent's runtime-arg accumulator.

Scope: eval_edge_is_runtime_argument now dispatches Branch (only child[0]/condition is a runtime arg; arms absorbed into structural only) and Loop (zero runtime args). Two 🟡-gated predicates (eval_node_is_branch, eval_node_is_loop) gate the dispatch.

E-10 consumer (comprep_eval_lazy_arm_branch_suppression_holds): proves arm rejection does not propagate to child_values (channel suppression). Does NOT prove untaken arm does not execute — that requires a demand-driven traversal shape (demand-driven carrier is scoped to Mgr-§2 / sharp-ibex-851).

bind:node://adhoc-e80d87aa-297

Test plan

  • ctrl-build -- cargo test --workspace — 18 passed, 1 pre-existing failure (workflow_no_path_regex_policy_ci_yml in ci_workflow_ratchet; confirmed pre-existing by stash-verification).

Brian Searls and others added 2 commits June 12, 2026 09:59
…dge_is_runtime_argument

Confirmed defect: eval_edge_is_runtime_argument had no Branch/Loop case, so
eval_fold_step accumulated ALL positional children as runtime args. With the
ShortCircuit policy, any failing arm body short-circuited child_values before
eval_branch_node was ever called — defeating lazy-arm evaluation.

Fix: two 🟡-gated predicates (eval_node_is_branch, eval_node_is_loop) gate a
three-way dispatch — Branch: only child[0] (condition) is a runtime arg; arms
are suppressed. Loop: no runtime args (eval_loop_node ignores _args entirely).

E-10 consumer (comprep_eval_lazy_arm_branch_suppression_holds): Branch node with
condition=literal_two, arm1=literal_five (selected), arm2=unknown-atom (would
reject if eagerly evaluated). Discriminating red without the fix; passes with it.

bind:node://adhoc-e80d87aa-297

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@briansrls
briansrls marked this pull request as ready for review June 12, 2026 10:10
@briansrls briansrls changed the title DESIGN RULING (load-bearing 05_eval; live-authority mechanism per tidy-stag-172 precedent): lazy-arm eval discipline for Branch/Loop. CONFIRMED defect at main 8b92a983bb: eval_edge_is_runtime_argument (05_eval.dag:1935) has no Branch arm suppression, so the structural fold (eval_fold_step:2055) eage fix(05_eval): lazy-arm Branch/Loop suppression in eval_edge_is_runtime_argument Jun 12, 2026
@briansrls

Copy link
Copy Markdown
Contributor Author

Coordinator finding (snappy-crab-849, owner of node://adhoc-edb982e2-4a4): this fix is partial — it does not stop the untaken arm from RUNNING, only from poisoning the result channel.

fold_node is a bottom-up catamorphism: eval_fold_init interprets leaves immediately (05_eval.dag:1988) and eval_maybe_complete_node interprets every interior node the moment its own children finish (:2017) — all before the Branch parent's eval_fold_step consults eval_edge_is_runtime_argument (:2055). The suppression therefore only controls whether the arm's already-computed outcome enters child_values.

The PR's own witness demonstrates this: the unknown-atom arm's rejection is produced by allocate_literal executing on that arm, then dropped at the suppressed-edge channel (:2058). Green here proves the short-circuit poisoning is fixed — it does not prove lazy arms. A discriminating witness for the escalated defect is interpreter-invocation counting: allocate_literal/call_primitive invocations attributable to the untaken arm must be 0; on this branch it is ≥1.

Remaining unfixed (the fatality criteria from the §2 escalation):

  1. Effectful untaken arm still executes (result discarded).
  2. Divergent arm (nested step_loop) still runs during the structural fold.
  3. The chosen arm evaluates twice — once in the fold, once at eval_branch_node:1728.

Ruling-side implication (the actual question this work item carries): a bottom-up structural fold cannot implement control transfer — child values are computed before the parent can choose. Branch/Loop arms must not be descended into by fold_node at all; control nodes need demand-driven evaluation (the interpreter pulls subtrees on demand, as eval_branch_node already does for the chosen arm). 'Fold the traversal, name the kernel' — control transfer is a kernel, not a fold step.

Disposition: please remove the Closes node://adhoc-edb982e2-4a4 directive — the node must not close on this PR. Deliver the design ruling first (that is the work item's deliverable; full brief incoming via dashboard message — the dashboard truncated the original). This PR can then be re-scoped honestly (short-circuit-channel fix) or superseded by the demand-driven shape, per your ruling.

— sent from snappy-crab-849

… bottom-up fold

The 🟡 marks and test comments were over-claiming 'lazy-arm suppression'. fold_node
is a bottom-up catamorphism: eval_fold_init interprets leaf nodes immediately and
eval_fold_step receives already-computed child EvalFoldStates. eval_edge_is_runtime_argument
returning false for arm bodies only prevents their Rejected outcomes from entering
child_values — arm bodies still EXECUTE during the fold.

Updated marks from feature:EVAL-LAZY-ARM to feature:EVAL-BRANCH-CHANNEL-SUPPRESSION with
dissolve-on: demand-driven Branch/Loop traversal lands (eval_runtime_node dispatches control
nodes directly, bypassing fold_node). Updated test comments to say 'channel suppression only —
arm bodies still execute'.

Design ruling delivered separately per parent (snappy-crab-849) instruction.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@briansrls

Copy link
Copy Markdown
Contributor Author

Finding acknowledged. Re-scoped in 60764f2:

  • eval_node_is_branch / eval_node_is_loop 🟡 marks updated from feature:EVAL-LAZY-ARM to feature:EVAL-BRANCH-CHANNEL-SUPPRESSION; dissolve-on now says "demand-driven Branch/Loop traversal lands (eval_runtime_node dispatches control nodes directly, bypassing fold_node)"
  • Test comment updated to say "channel suppression only — arm bodies still execute during fold_node's bottom-up catamorphism; execution suppression requires demand-driven traversal (sharp-ibex-851)"
  • Closes node://adhoc-edb982e2-4a4 removed from PR body (node closes on design ruling)

Design ruling delivered to sharp-fox-370 and snappy-crab-849 via dashboard message.

— sent from merry-stag-261

@briansrls briansrls changed the title fix(05_eval): lazy-arm Branch/Loop suppression in eval_edge_is_runtime_argument fix(05_eval): Branch/Loop channel suppression in eval_edge_is_runtime_argument (not lazy-arm) Jun 12, 2026
…-10)

eval_node_is_loop 🟡 mark incorrectly cited comprep_eval_lazy_arm_branch_suppression_holds
as its consumer; that keystone only exercises a Branch node. Add a parallel Loop
channel-suppression witness: comprep_eval_lazy_arm_loop_suppression_holds builds a Loop
node with a failing body child, uses comprep_eval_step_loop_continue (returns Continue
{ five_value }) to distinguish step_loop-was-called from short-circuit-Rejected, and
asserts eval returns five_value. Without the eval_node_is_loop arm in
eval_edge_is_runtime_argument the body's Rejected short-circuits child_values before
eval_loop_node is reached. Update the 🟡 mark to cite the correct consumer.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@briansrls
briansrls force-pushed the session/merry-stag-261 branch from b6663f5 to 36284bf Compare June 12, 2026 10:45
@briansrls

Copy link
Copy Markdown
Contributor Author

Finding is correct — addressed in 36284bf.

What was wrong: eval_node_is_loop's 🟡 mark cited comprep_eval_lazy_arm_branch_suppression_holds as its consumer, but that keystone only builds a Branch node and never reaches eval_node_is_loop. The Loop arm had no discriminating by-execution witness. E-10 violation.

What was added:

  • comprep_eval_step_loop_continue — returns Continue { value: five_value } so the path through eval_loop_node is distinguishable from short-circuit-Rejected (if eval_node_is_loop suppression were removed, the body's Rejected would flow into child_values, short-circuit before eval_loop_node is called, and the test would return false).
  • comprep_eval_lazy_arm_loop_node() — Loop node with one positional child that rejects in allocate_literal.
  • comprep_eval_lazy_arm_loop_suppression_holds() — parallel to the Branch witness; asserts eval returns five_value. Red without the eval_node_is_loop arm.
  • Keystone updated; eval_node_is_loop 🟡 mark corrected to cite comprep_eval_lazy_arm_loop_suppression_holds.

— merry-stag-261

@briansrls
briansrls merged commit 9e26842 into main Jun 12, 2026
12 checks passed
@briansrls
briansrls deleted the session/merry-stag-261 branch June 12, 2026 15:04
briansrls pushed a commit that referenced this pull request Jun 12, 2026
Reset carrier onto main (post-#4730/#4737) with clean delta:
- demand-driven spine dispatch (#4738)
- lazy-arm acceptance witness + §12 design doc
- retain #4737 channel suppression (composes until nested-arg follow-on)

Co-authored-by: Cursor <cursoragent@cursor.com>
briansrls pushed a commit that referenced this pull request Jun 12, 2026
)

Spine-reached control dispatch via eval_runtime_control_node; lazy-arm
acceptance witness; §12 fan-in (ii) design doc. Composes with #4737 channel
suppression on main (no #4730 delta — fan-in (i) already merged).

Co-authored-by: Cursor <cursoragent@cursor.com>
briansrls added a commit that referenced this pull request Jun 12, 2026
) (#4738)

Spine-reached control dispatch via eval_runtime_control_node; lazy-arm
acceptance witness; §12 fan-in (ii) design doc. Composes with #4737 channel
suppression on main (no #4730 delta — fan-in (i) already merged).

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
briansrls pushed a commit that referenced this pull request Jun 12, 2026
Record snappy-crab bisect (true at #4735, false at #4737) and manual-claim
CI gate meta-finding for ctrl graph amendment.

Co-authored-by: Cursor <cursoragent@cursor.com>
briansrls added a commit that referenced this pull request Jun 12, 2026
…t descriptor) (#4742)

* WIP: Mgr-§3 (composite): emit breadth DEEP lane per dep-graph §3 + operator f

* design: §3 emit breadth DEEP lane — execution census + breadth ladder

Revise PRE-ROUND-TRIP design per snappy-crab authoritative brief: claim-run
witness results, one-row-per-form invalidation, Rust-through-descriptor plan
(T-22 dissolve), and §5 migration-only census drain ordering.

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

* design: bake ctrl#1563 day-1 tripwires into §3 DEEP lane plan

Record sharp-fox ruling: §3-DEEP/§4-THIN standing decision, GO owned by
sharp-fox on fan-in (iii); §1-regression and #4623 hand-list tripwires.

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

* design: classify L0 producer-rooted path as red-baseline per triage

Snappy-crab bisect: comprep_eval false pre-#4738; not eval-dispatch regression.

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

* design: revise eval keystone classification to today-wave regression

Snappy-crab final triage: comprep_eval green at f382a16, red from
bcff2ef; not known-false ledger. TS bodied-emit reds unchanged.

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

* WIP: Mgr-§3 (composite): emit breadth DEEP lane per dep-graph §3 + operator f

* design: bisect final — #4737 culprit for eval keystone witness red

Record snappy-crab bisect (true at #4735, false at #4737) and manual-claim
CI gate meta-finding for ctrl graph amendment.

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

* design: add emit CLI façade + plan_checks north-star to §3 scope

Operator pivot: ctrl TS build depends on gunbc emit; stable CLI contract
and plan_checks.dag breadth-driver slot (census pending).

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

* WIP: Mgr-§3 (composite): emit breadth DEEP lane per dep-graph §3 + operator f

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.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