fix(§17.6.2): the value-form sugar binds its result at a binding site — was always null - #815
Merged
Merged
Conversation
… — was always null
bryan, user-voice S395: "seems ok not to have a trailing else". The ruling settled the
no-else direction; verifying it surfaced that the sugar itself never worked in the
bound position at all.
THE DEFECT. SPEC §17.6.2 is normative: "A branch body that is exactly one expression
SHALL be equivalent to { lift <expression> }." That held in the markup-interpolation
path and was never implemented at a binding site. A local
const label = if (@n > 0) { "pos" } else { "neg" }
compiled at exit 0 with zero diagnostics and emitted a FRESH shadowed
`let _scrml_tilde_4 = "pos"` inside each arm, never writing the outer result var —
so `label` was ALWAYS null. Silent-wrong. The explicit-`lift` twin was the control
and was correct.
THE FIX. New `_emitValueFormSugarArm` helper + 3 call sites; `tildeVar` threaded
through `emitIfExprAltChain`. It shares the leaf predicate `_blockTailIsValueExpr`
with the §18.5 match block-arm redirect (same root question: "is this a value?") but
NOT the shape rule — §18.5 is tail-of-many, §17.6.1's grammar is exactly-one
(`'{' expression '}'`). Sharing the shape test would have widened §17.6 to a rule its
grammar does not sanction. The `length === 1` test matches the working interpolation
twin `_soleBareExprValue`.
Two guards are load-bearing and measured, not assumed: `{ @acc += 1 }` arrives as a
bare-expr carrying an `assign` node. Without `_blockTailIsValueExpr` the redirect would
hijack a statement as the arm value AND bypass the §51.11 machine-write interception.
VERIFICATION.
- Bite, both directions, by FILE COPY (never `git stash` — refs/stash is shared across
worktrees): base `let _scrml_tilde_4 = "pos";` -> build `_scrml_tilde_3 = "pos";`.
PA-reproduced independently of the agent.
- Direction is `semantics-changed`, the class the gates are weakest against, so it owes
a MEASURED differential: artifact diffs 2 of 7408, both named, both the new
conformance cases. ZERO pre-existing corpus files change. The agent's first run was
contaminated by a source-set race (1912/1913) and was re-run at 1914/1914.
- The zero is explained, not assumed: PA-verified census finds exactly 5 bound-position
sites in the whole corpus, all in samples/compilation-tests/gauntlet-s19-phase2-
control-flow/, and all 5 write the explicit `lift` form.
- ctrl-023 and ctrl-024 FAIL on base and PASS on head — genuine regression guards, not
dormant fixtures. Whole-suite base-vs-head: 0 new failures.
- S239 adversarial pass run PA-side (the dev agent cannot invoke it in-agent):
3 findings, all LOW, none blocking, two pre-existing and adjacent. Filed, not fixed
here.
NOT WIDENED, deliberately: the derived-cell binding `const <label> = if (…)` still
fails loud with E-CODEGEN-INVALID-LOGIC for BOTH the sugar and the explicit-`lift`
form. §17.6.3 names only `const`/`let` binding sites, so a derived state cell is an
UNSPECIFIED shape currently failing in the safe direction. Making it work is a widening
and is bryan's ruling. (Asymmetry recorded: `const <label> = match @Level { … }` in a
derived cell DOES work and ships as a conformance case.)
The agent's crash-anchor progress.md was relocated from the repo root into
docs/changes/s395-value-form-sugar-bound/ rather than landing as a root stray.
provenance: spec:§17.6.2 — "A branch body that is exactly one expression SHALL be
equivalent to { lift <expression> }" (conformance restoration, not a widening)
Agent branch: worktree-agent-af4227ae4f7a528e9 @ 8202c10c
…g (+2 conformance cases)
bryanmaclee
added a commit
that referenced
this pull request
Sep 2, 2026
…to zero, and a locus that was disjoint from its answer (#816) GAPS. g-value-form-sugar-in-bound-position-emits-null -> RESOLVED via #815 (908a631), PA-verified on MERGED main rather than on the branch. Two corrections to that entry as filed, both from execution: (a) Its `locus=searched:` named emit-html.ts, emit-each.ts and emit-control-flow.ts. The responsible site was in NONE of the three — it is emit-logic.ts, a FOURTH file, reached via the const-decl/let-decl dispatch through `node.ifExpr`. The searched-set was not merely incomplete, it was DISJOINT from the answer. Routed to the nav-maps per base §5: a locus error that recurs across dispatches is a map gap wearing a brief's clothes. (b) Its claim "the explicit-`lift` twin is the control and is correct" holds for the LOCAL binding only. For a derived cell BOTH forms fail — so anyone building against that sentence works from a false control. TWO NEW ENTRIES, same root as the one #815 closed, which is why #815 is correctly scoped as one position of a class and not the class: - g-bare-expr-in-if-arm-rebinds-tilde-context-corrupting-the-result-var (HIGH, PA-reproduced on merged main, SURVIVES #815). Hits the CANONICAL `'{' statement* lift-stmt statement* '}'` production. The corpus misses it on a technicality — phase2-if-as-expr-intermediate-014.scrml uses a `let`-decl, which does not rebind; only a bare EXPRESSION does. RULING OWED. - g-nested-if-as-expression-arm-body-binds-null-silently (MED, RELAYED-VERIFIED-BY- REVIEWER and labelled as such — not PA-re-executed). Filed as a fail-SILENT direction defect, NOT as a missing feature: §17.6.1 makes the shape unspecified, so supporting it is a widening and is bryan's. REVIEW FLOOR: 1 OWED -> 0. Markers for #812, #813, #814, #815. Code-bearing carve-out rate holds at 2/163 (1%); the 59% all-PR figure is the volume statistic the S319 note says not to read as a health signal. REVIEWER-VS-DEV, ADJUDICATED BY EXECUTION. The S239 pass claimed #815 removes a ReferenceError/implicit-global class. It does for a SUGAR else arm and does NOT for an explicit-`lift` else arm — and the explicit-`lift` form is the one §17.6.1's canonical grammar documents. Recorded in the new HIGH rather than accepted as filed. DRIVE-BY, in a file already open: g-each-value-form-if-markup-fn-call-branch-stringifies carried `status=resolved` on its marker (with a bite-proven prov= from S392-peter) while its HEADING still read `open`. A heading-based sweep saw an open entry the field-based probe saw closed. Heading corrected; no status change. This is the exact divergence base §2 warns about — and it cuts against the overlay's own "match on the heading, not on marker adjacency", since S385 measured headings as the LOSSY side. Counts move HIGH 77 (-1 resolved, +1 new) and MED 200->201, which is the proof the new entries are machine-visible rather than prose-only.
bryanmaclee
added a commit
that referenced
this pull request
Sep 3, 2026
…reen while wrong (#824) Ran concurrently with S396-peter throughout. Five rulings given, four code arcs landed, the review floor drained twice to zero, maps refreshed. ONE ARC HELD on a ruling, worktree retained. ⚑ THE SESSION'S REAL OUTPUT IS NOT THE LANDINGS. Nine separate checks read green or authoritative while being wrong, and every one was caught by RUNNING something rather than by remembering. Three were my own claims. TWO WERE CAUGHT BY GATES I DID NOT WRITE. Three were agents' own instruments, found by those agents. RULINGS · the trailing-`else` question — direction stands, and the reported "inverted ruling" was MY OWN mis-description: §17.6.4 has always said a missing `else` is valid. I relayed a hand-off's framing into the boot report without opening the section. · the `~` arm-body question — limb (a) ratified, limb (c) BANKED as dpa-040, not closed. · 2a / 2b / 2c — the runAnchored fix (sequenced), the dev-root auth gate (limb b), and the tracking-job sequence with its first step folded in. · SPLIT the dev-auth arc when its §52.13 half turned out to require a second decider. LANDED #815 the §17.6.2 value-form sugar binds its result at a binding site — it bound null forever. #818 a branch-declared function is ROUTED before it is COLLECTED; closing the client half alone put a `server fn` BODY into client.js. #822 18 conformance assertions read as coverage and checked nothing. ⚑ MY BRIEF WAS WRONG — a naive `continue` deletion would have reddened 62 count:0 ABSENCE assertions — and the agent deviated with a stated reason. Only 2 of the 18 were covered elsewhere; 16 were entirely unguarded. #823 `scrml dev` served a protected document unauthenticated at `/`. The fix is a DELETION: two serving paths become one. #816 #819 #820 continuity + filings; #817 the overdue wrap-6c maps refresh, which corrected three premises in my own concurrently-dispatched brief. ⚑ HELD, NOT LANDED — the `~` build, worktree RETAINED at agent-ac264a1015c0da19d @ c2ad6f49. Four fix rounds, four adversarial passes, 7 SPEC loci reconciled. Blocked on bryan's revert-vs-press-on for the READ half, whose widening PA-verifiably DELETES A DOM LIFT (base emits _scrml_lift/createTextNode, the branch pushes into a dead array, exit 0). Resume the agent; do not re-dispatch. FINDINGS WORTH CARRYING · SUPPRESSING A SIGNAL SUPPRESSES WHATEVER RODE ON IT — three instances, one of them my own instruction. The `tracking` job's routine red concealed a REAL §52.13 assertion failing on Linux (compiler/tests/commands/ runs in NO blocking job on any platform). A knowingly-red assertion placed FIRST in a test turned the four after it into dead code that still read as coverage. And I instructed `test.failing` on that test — which passes when the body fails for ANY reason, so it would have MASKED A LEAK. The agent's formulation is the keeper: a mechanism that makes a red acceptable also makes a red invisible. · A FIX THAT NEEDS A SECOND DECIDER IS THE FORK RULE SAYING NO. Three rounds found three distinct divergences between the dev pre-gate and the resolution loop; the split then CLOSED a dev/prod divergence rather than opening one. · A REVIEW FINDING WAS FALSIFIED RATHER THAN FILED — the first time this session verification prevented a FABRICATED finding instead of catching a missed one. The corpus IS gated; corpus-bridge.test.js reaches it from inside the gated root. · TWO SHARED-DOC CONCURRENCY HAZARDS, both caught by machinery: conflicting @generated gap counts (resolved by regenerating from the merged population — the union, not a pick), and duplicate delta-log sequence numbers with peter (caught by the cloud gate's step 14; a duplicate makes the flogence bridge DROP the second entry from the digest). · BASE-DRIFT nearly reverted landed work FOUR times. · EVERY ONE of the five agent deviations from my instructions this session was correct. WRAP STEPS: hand-off rewritten (S396-peter's rotated to handOffs/hand-off-282.md, his live items carried) · changelog block · delta-log [2040]-[2045], sequence gate PASS · review floor 6 OWED -> 0 · inbox: TWO items deliberately left unarchived because both await bryan (the E-ROUTE-004 fork and the ~11-day-old FSP Initialize deliberation), both summarised in the hand-off · suite 30945 pass / 54 fail — ONE FEWER than base, the §52.13 assertion · worktrees: four landed swept, one retained · maps refreshed to 2d8dd8c, watermark verified via state.ts not by reading the file · @generated + facts gates PASS.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
bryan, user-voice S395: "seems ok not to have a trailing else". The ruling settled the no-else direction; verifying it surfaced that the sugar itself never worked in the bound position at all.
The defect
SPEC §17.6.2 is normative: "A branch body that is exactly one expression SHALL be equivalent to
{ lift <expression> }." That held in the markup-interpolation path and was never implemented at a binding site:compiled at exit 0 with zero diagnostics and emitted a fresh shadowed
let _scrml_tilde_4 = "pos"inside each arm, never writing the outer result var — solabelwas alwaysnull. Silent-wrong. The explicit-lifttwin was the control and was correct.The fix
New
_emitValueFormSugarArm+ 3 call sites;tildeVarthreaded throughemitIfExprAltChain. It shares the leaf predicate_blockTailIsValueExprwith the §18.5 match block-arm redirect (same root question — "is this a value?") but not the shape rule: §18.5 is tail-of-many, §17.6.1's grammar is exactly-one ('{' expression '}'). Sharing the shape test would have widened §17.6 beyond its grammar.Verification
git stash—refs/stashis shared across worktrees): baselet _scrml_tilde_4 = "pos";→ build_scrml_tilde_3 = "pos";. PA-reproduced independently of the agent.semantics-changed— the class the gates are weakest against — so it owes a measured differential: 2 of 7408 artifacts change, both named, both the new conformance cases. Zero pre-existing corpus files change.samples/compilation-tests/gauntlet-s19-phase2-control-flow/, and all 5 write the explicitliftform.ctrl-023/ctrl-024fail on base, pass on head — genuine regression guards, not dormant fixtures. Whole-suite base-vs-head: 0 new failures.Not widened, deliberately
The derived-cell binding
const <label> = if (…)still fails loud withE-CODEGEN-INVALID-LOGIC, for both the sugar and the explicit-liftform. §17.6.3 names onlyconst/letbinding sites, so a derived state cell is an unspecified shape currently failing in the safe direction. Making it work is a widening and is bryan's ruling. (Asymmetry recorded:const <label> = match @level { … }in a derived cell does work and ships as a conformance case.)provenance: spec:§17.6.2— conformance restoration toward an existing normative sentence, not a widening.Agent branch:
worktree-agent-af4227ae4f7a528e9@8202c10c. Itsprogress.mdcrash-anchor was relocated out of the repo root intodocs/changes/s395-value-form-sugar-bound/.🤖 Generated with Claude Code
https://claude.ai/code/session_019eHiNS6uvnGPFz55fzinNJ