Skip to content

general body producer: ingested if-body fn_decl → Arrow, green by execution (Wave 1 gate 1) - #6558

Merged
briansrls merged 45 commits into
mainfrom
consolidate/int-literal-body-producer
Jul 14, 2026
Merged

briansrls merged 45 commits into
mainfrom
consolidate/int-literal-body-producer

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Consolidates the general-body-producer int-literal keystone (subsumes the redundant Track A #6532 / Track B #6542 lanes). Wave 1 exit criterion 1 of the Weak→Strong Self Host program.

Problem

An ingested fn pick() -> Int { if c { 1 } else { 2 } } silently failed to become a substrate Arrow — passed CI green while behaviorally dead (the exercising witnesses live in the CI-excluded test/claim/execution/ dir). Parse decoded the int-literal magnitude correctly, but fn_decl → Arrow lowering rejected → no Branch → no eval.

Root cause (two coupled defects, pinned by execution; neither fixes it alone)

A graduated probe ladder localized it: parse GREEN (then-arm carries magnitude), normalize produced no Arrow at all.

  1. Speculative if-lowering miss reported as a terminal Reject. body_lower_try_if_from_node's wrapper-less arm treated "an if-condition is reachable somewhere in this node" as proof the node is an if-captured, called try_if_from_captured on the whole block, and propagated its Reject — short-circuiting body_lower_body_subtree_lower before its robust find_captured(if_expr) path (which lowers the same if correctly). A strategy-miss is not a malformation (DESIGN §5 state-space conflation); converted to a retryable Absent. Confident arms (emitted == if_expr) and find_captured'd malformed ifs still reject loudly.

  2. Operand navigation landed on the production identity-projection atom (magnitude-less) instead of the captured magnitude-bearing sibling. Made operand resolution magnitude-aware: skip identity-projection edges, reject magnitude-less int atoms, reach arm operands through the production shell so the captured projection is followed.

Proven by execution (local claim_batch --wet — the oracle, since these witnesses are CI-excluded)

  • pick_ingested_equals_eval_keystone_holds (literals 1/2): PASS
  • pick2_ingested_equals_eval_generality_holds (literals 3/4): PASS
  • pick_ingested_normalized_swapped_arms_structural_red_holds (discriminating RED): PASS
  • probe ladder (normalized/resolved/eval magnitude-child): PASS
  • constructed-match controls (emit_host eval, swapped-refuses, arrow-has-match, resolves): PASS — no regression to the match-lowering path

Follow-ups

🤖 Generated with Claude Code

Brian Searls and others added 30 commits July 13, 2026 14:42
The roster entry for runtime_value_signed_i32_le_as_int (246ec08) is the real CI fix; drop temporary bisect witnesses and rust debug tests.

Co-authored-by: Cursor <cursoragent@cursor.com>
CI srv3-06 hit exit 127 on run_ts_smoke/run_node_http_serve_smoke because node was absent from PATH; bootstrap the official linux tarball under WORKDIR like run_go_smoke already does for go.

Co-authored-by: Cursor <cursoragent@cursor.com>
${NODEARCH} in a data string is parsed as dag interpolation; use $NODEARCH like the go smoke's $GOARCH.

Co-authored-by: Cursor <cursoragent@cursor.com>
Finish add/pick eval witnesses on default v2_evaluator (drop injected allocate_literal fixtures), fix probe imports and corpus entry path, add review scaffold notes for Atom payload edges and emit int-literal 1/2 binding, and sign-extend i32 LE decode.

Co-authored-by: Cursor <cursoragent@cursor.com>
Register three v2_evaluator runtime helpers in NON_FOLD_RESIDUE_ROSTER so
non_fold_residue_no_unrostered_or_stale passes. Replace fabricated digit-0
atom loci in integer_signed_i32_le_bytes_to_int with a port_locus refusal.

Co-authored-by: Cursor <cursoragent@cursor.com>
These local complexity_linearity_audit dumps were committed by
accident; the roster updates they reference already live in
NON_FOLD_RESIDUE_ROSTER.

Co-authored-by: Cursor <cursoragent@cursor.com>
Register frontier_blocker_class_matches from merged Wave 2 frontier
probe types so non_fold_residue_no_unrostered_or_stale passes. Fix
accidental dedent in resolve_atom int-literal early-return arm.

Co-authored-by: Cursor <cursoragent@cursor.com>
Accidental shell-redirection artifact; not referenced by any source.

Co-authored-by: Cursor <cursoragent@cursor.com>
Brian Searls and others added 12 commits July 13, 2026 20:28
… int-literal magnitude on Branch arm reify.

Co-authored-by: Cursor <cursoragent@cursor.com>
…ecution (Wave 1 exit criterion 1)

An ingested `fn pick() -> Int { if c { 1 } else { 2 } }` silently failed to become a
substrate Arrow: parse decoded the int-literal magnitude correctly, but fn_decl->Arrow
lowering rejected, so no Branch, no eval. Pinned by execution via a graduated probe ladder
(parse GREEN, normalize produced no Arrow) down to two coupled defects — neither fixes it alone:

1. Speculative if-lowering miss reported as a terminal Reject (root of the no-Arrow).
   `body_lower_try_if_from_node`'s wrapper-less arm treated "an if-condition is reachable
   somewhere in this node" as proof the node IS an if-captured, called
   `try_if_from_captured` on the whole block, and propagated its Reject. That short-circuited
   `body_lower_body_subtree_lower` before its robust `find_captured(if_expr)` path (which
   lowers the same if correctly). A strategy-miss is not a malformation (DESIGN §5
   state-space conflation): convert the speculative Reject to a retryable Absent so the
   specific strategy runs. Confident arms (emitted == if_expr) and find_captured'd malformed
   ifs still reject loudly.

2. Operand navigation landed on the production identity-projection atom (magnitude-less)
   instead of the captured magnitude-bearing sibling. Made operand resolution magnitude-aware:
   skip identity-projection edges (`body_lower_operand_fold_children_optional`,
   `body_lower_literal_int_atom_optional`), reject magnitude-less int atoms
   (`body_lower_operand_ref_acceptable_optional`), and reach arm operands through the
   production shell (`body_lower_find_production_shell_optional`) so the captured projection
   is followed.

Proven by execution (local claim_batch --wet; these witnesses live in the CI-excluded
test/claim/execution/ dir, so local run is the oracle):
- pick_ingested_equals_eval_keystone_holds (literals 1/2): PASS
- pick2_ingested_equals_eval_generality_holds (literals 3/4): PASS
- pick_ingested_normalized_swapped_arms_structural_red_holds (discriminating RED): PASS
- probe ladder normalized/resolved/eval magnitude-child: PASS
- constructed-match controls (emit_host eval, swapped-refuses, arrow-has-match, resolves):
  PASS (no regression to the match-lowering path)

CI-visible enrollment of these witnesses is tracked separately (royal-wolf-43 #6552).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
gunbai-bot Bot pushed a commit that referenced this pull request Jul 14, 2026
Merge consolidate/int-literal-body-producer (#6558 base) so pick keystone,
pick2 generality, and normalize magnitude witnesses are green by execution.
Execution-lane probe enrollments removed; helpers retained. stage_bridge
uses dag_int_literal_magnitude_node_optional. Fast lane unchanged (4 witnesses).

Co-authored-by: Cursor <cursoragent@cursor.com>
… no laundered reject

Review (claude-opus-4-7, #6558) correctly flagged the prior fix as a §5 absorbing
fallback: once `if_condition_optional` recognized the node as if-shaped, a `Rejected`
from `try_if_from_captured` was rewritten to `Accepted(optional_absent())` — laundering a
structural rejection into "not an if" with no counted refusal (fabricated Absent after
shape recognition).

Root of that imprecision: `if_condition_optional(node)` Present is a weak signal — it
fires for a block that merely *contains* an if (the pick case), not only for a genuine
if-captured. So the speculative `try_if_from_captured(node)` reject was a mis-granularity
guess, but converting it to Absent laundered any *genuine* malformation identically.

Fix: remove the speculative if arm entirely. `body_lower_try_if_from_node` now returns an
honest `Absent` for wrapper-less nodes — it never calls `try_if_from_captured`
speculatively, so there is no rejection to launder. Precise if-location is delegated to
`body_lower_body_subtree_lower`'s existing `find_captured(if_expr) -> try_if_from_captured`
path, which (a) runs AFTER `try_body_lowered`'s match handling, so it never over-reaches
into match arms, and (b) propagates any `try_if_from_captured` Rejected directly (loud, no
launder). Every genuine structural rejection now propagates; the only Absent is honest
"no if recognized here."

An intermediate attempt that resolved the if via `find_captured` inside `try_if_from_node`
was discarded: it over-reached into `if`s nested in match arms and regressed the
constructed-match controls (emit_host eval / swapped-refuses / arrow-has-match). The
honest-Absent form relies on the caller's correctly-ordered fallback and avoids that.

Proven by execution (local claim_batch --wet):
- pick_ingested_equals_eval_keystone_holds (1/2): PASS
- pick2_ingested_equals_eval_generality_holds (3/4): PASS
- pick_ingested_normalized_swapped_arms_structural_red_holds (discriminating RED): PASS
- constructed-match controls (emit_host eval, swapped-refuses, arrow-has-match): PASS
  (regressed by the discarded find_captured attempt, green again under honest-Absent)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@gunbai-bot

gunbai-bot Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor Author

@claude-opus-4-7 — valid §5 finding, fixed in 0b0ea0fe7. You were right: once if_condition_optional recognized the node as if-shaped, rewriting the Rejected to Accepted(optional_absent()) laundered a structural rejection into "not an if" with no counted refusal.

The imprecision was that if_condition_optional(node) Present is a weak signal — it fires for a block that merely contains an if (the pick case), not only for a genuine if-captured. So the speculative try_if_from_captured(node) reject was a mis-granularity guess, but converting it to Absent laundered any genuine malformation the same way.

Fix: removed the speculative if arm entirely. body_lower_try_if_from_node now returns an honest Absent for wrapper-less nodes — it never calls try_if_from_captured speculatively, so there is no rejection to launder. Precise if-location is delegated to body_lower_body_subtree_lower's existing find_captured(if_expr) -> try_if_from_captured path, which (a) runs after try_body_lowered's match handling so it never over-reaches into match arms, and (b) propagates any try_if_from_captured Rejected directly (loud). Every genuine structural rejection now propagates; the only Absent is honest "no if recognized here."

(I first tried resolving the if via find_captured inside try_if_from_node — that over-reached into ifs nested in match arms and regressed the constructed-match controls, so I discarded it. The honest-Absent form relies on the caller's correctly-ordered fallback and avoids that.)

Verified green by execution (local claim_batch --wet): keystone (1/2), generality (3/4), swapped-arms structural RED, and constructed-match controls (emit_host eval / swapped-refuses / arrow-has-match) all pass. Requesting re-review to clear the REQUEST_CHANGES.
— sent from sharp-bee-290

gunbai-bot Bot pushed a commit that referenced this pull request Jul 14, 2026
Resolves merge conflict by stripping the temporary consolidate/int-literal-body-producer merge from #6552. Restores CI-visible pipeline relationship witnesses (fast lane: tokenize/infer/lower; long lane: parse/normalize/match). Eval-fidelity execution→long migration deferred until #6558 lands on main.

Co-authored-by: Cursor <cursoragent@cursor.com>
Brian Searls and others added 2 commits July 14, 2026 02:14
…al-body-producer

# Conflicts:
#	src/v2/compiler/03_resolve.dag
… parent

CI batch-2 red on the merge commit was a single discovery witness,
doc_graph_has_no_orphan_docs (src/v2/lens/doc_reachability_test.dag) — a
pre-existing main regression inherited via the origin/main merge, NOT introduced
by this PR's int-literal work (docs/ and the doc-reachability lens are
byte-identical to origin/main).

Root: #6559 merged docs/plans/shell-to-dag-residual-census-and-arc-completion.md
(witty-ibex-317) to main with zero inbound references, so the doc-graph orphan
lens fails corpus-wide (every PR merging current main inherits it).

Fix: add the faithful inbound edge — the census doc's own header states it
"builds on lane D's authority provisioning-window-executor-capability-design.md",
so the parent design doc now forward-references the census/arc-completion doc
(same witty-ibex-317 arc, real upstream→downstream relationship). Minimal,
reversible, and clears the orphan for the whole corpus, not just this PR.

Verified by execution: doc_graph_has_no_orphan_docs PASS (orphan count 0).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@briansrls
briansrls merged commit bdd24cd into main Jul 14, 2026
2 checks passed
@briansrls
briansrls deleted the consolidate/int-literal-body-producer branch July 14, 2026 02:42
briansrls added a commit that referenced this pull request Jul 14, 2026
* WIP: Add per-stage structural unit tests across the v2 compiler pipeline: eac

* Rebase onto main: tests-only pipeline witnesses (drop #6558 bundle).

Resolves merge conflict by stripping the temporary consolidate/int-literal-body-producer merge from #6552. Restores CI-visible pipeline relationship witnesses (fast lane: tokenize/infer/lower; long lane: parse/normalize/match). Eval-fidelity execution→long migration deferred until #6558 lands on main.

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

* WIP: Add per-stage structural unit tests across the v2 compiler pipeline: eac

---------

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
briansrls added a commit that referenced this pull request Jul 14, 2026
… roster (added pick keystone rows, fixed a stale path), disproving the abandoned premise; instead fix its 3 spice rows to the relocated paths (incl. the missing _test suffix)
briansrls pushed a commit that referenced this pull request Aug 22, 2026
…ad ever obeyed until one did (#8854)

* The declaration was the lie: two OccurrenceId params that no caller had ever obeyed until one did

MAIN IS RED at 67437fc — 16 witnesses (12 fold_lowering, 4 body_lowering.statement_let_bind)
fail with `non-exhaustive pattern match on: OccurrenceId { value: 79 }`. Green PR, green base,
red union: #8833's branch did not contain #8828, and neither head ever existed in the
combination that fails.

The mechanism is one layer below the obvious one. #8833 changed one call in `02_parse`
`parse_expr_terminal` from `node_occurrence_minted(id: minted.id)` to `minted.id` — and it did
that to OBEY the signature it was calling. `v2.extdeps.languages.dag` declares

  fn dag_int_literal_node_from_lexeme(lexeme: String, occurrence_id: OccurrenceId)
  fn dag_int_literal_node_from_magnitude(magnitude: DecimalMagnitude, occurrence_id: OccurrenceId)

and stores that parameter straight into `Node.occurrence_id`, which is declared
`NodeOccurrenceId`. Both signatures have said `OccurrenceId` since #6558. Every caller in the
tree contradicted them by passing `SyntheticOccurrence`, which is why it stayed invisible.
#8833's author was the first person to take the signature at its word.

So the wrap is correct and the declaration is the defect. Fixed at the declaration, not just at
the call site — repairing only the caller leaves the lie standing for the next caller to obey:

  - dag.dag: both parameters redeclared `NodeOccurrenceId`; the now-unused
    `import std.occurrence_identity { OccurrenceId }` dropped, `NodeOccurrenceId` added to the
    existing `v2.std.node` import.
  - 02_parse.dag: `node_occurrence_minted(id: minted.id)` restored.

Caller census, read at call grain rather than by same-line grep — 17 sites across the two
functions: 15 pass `SyntheticOccurrence`, 1 passes `node.occurrence_id`, 1 is dag.dag's own
internal pass-through, and 1 passes the raw `minted.id`. Exactly one obedient caller existed and
it is the one that reddened main, so no second detonation is waiting. Changing the declared type
inverts which callers are correct, and by the finding below the typechecker cannot verify that
for us — hence reading, not building.

Green by execution, not by reasoning that the types now match: all 16 fold_lowering witnesses and
all 4 statement_let_bind witnesses PASS. The discriminating RED is main itself.

Also files one guarantee row, deliberately not fixed here. `v1.compiler.04_infer` gates
`arg_compat_diags` on `module_skips_direct_call_arg_check`, which is true for every module named
`v2.*`, keyed on the CALLER's module — so the direct-call argument-TYPE judgment is switched off
across the entire active v2 corpus. That is why nothing complained in EITHER direction for two
months. The row records the inversion that makes this class hard to see: a declaration that lies
is inert while every caller contradicts it in the same direction, and detonates on the first
caller who obeys it, so the at-risk population is callers who might get it right.

* The row is a correction to DESIGN §4b, not an observation beside it: confinement was measured and then treated as safety

DESIGN §4b names module_skips_direct_call_arg_check and reports it scoped entirely to the
direct-call argument-type judgment, not reaching sole_constructor — a positive finding, axis
retired. That finding is correct. It asked whether the exemption LEAKS; it never asked what the
exemption COSTS inside the judgment it is scoped to, and that judgment is the argument-type check
for the whole active v2 corpus. A reader who finds DESIGN's sentence and this row separately would
conclude the question was already answered, so the row now says which half it is.

Also records, against my own case: the arm is NOT unreasoned. direct_call_shape_wall_note states
the TYPE judgment's false-positive classes are representation gaps (brand aliases, optionality's
two forms, anonymous literals, expansion depth). That is a real stated reason, and it is why this
row asks for a measurement rather than a deletion. What is unmeasured is whether those classes
still fire in v2 and at what rate.

* The corrected declaration is TRUE but INERT: the judgment that would enforce it is the one switched off

Two changes, neither to the repair.

RUNG HONESTY, and it is the point. Correcting the parameter to NodeOccurrenceId reads like the §5
construction move -- fix the type and the wrong call stops compiling -- but the judgment that would
refuse the wrong call is `module_skips_direct_call_arg_check`, which exempts every `v2.*` caller
from the direct-call argument-TYPE check. So this PR lands a wall that CANNOT FIRE. The declaration
is now true, which is worth having on its own terms, but as enforcement it is inert, and shipping
it while believing the class is closed is exactly the rung inflation §4b calls worse than sitting
low. The class stays at its old rung; the next-rung trigger is the exemption's deletion, which the
guarantee row already names. (Product-direction ruling, swift-badger-524.)

ANNOTATIONS, grafted from gunbc#8856 (author's wording kept) with two additions of my own. With the
type wall inert, a §4c annotation is the only thing standing at these two sites -- it is not
evidence, and nothing mechanical reads it, which is precisely why it has to say why the shape is
what it is. Added to the callee: a bare OccurrenceId is the PAYLOAD INSIDE one of NodeOccurrenceId's
arms, never a member of the coproduct -- the modeling error in one line (smart-ram-730's phrasing,
the clearest statement of it anyone produced). Added to the caller: that the exemption is why no
mechanism stands there.

Green by execution after the annotations: 16/16 fold_lowering witnesses PASS, 0 FAIL.

---------

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