Skip to content

parse-reader: splice multi-line def := continuations (eigentrust pitfall #15)#12

Merged
hierophantos merged 1 commit into
mainfrom
claude/fix-eigentrust-pitfall-15-mldef
Apr 30, 2026
Merged

parse-reader: splice multi-line def := continuations (eigentrust pitfall #15)#12
hierophantos merged 1 commit into
mainfrom
claude/fix-eigentrust-pitfall-15-mldef

Conversation

@kumavis
Copy link
Copy Markdown
Contributor

@kumavis kumavis commented Apr 25, 2026

Fixes pitfall #15 from docs/tracking/2026-04-23_eigentrust_pitfalls.md.

Summary

def c-asym-3 : [List [List Rat]]
  := '['[rz 1/2 1/2] '[rz rz ro] '[ro rz rz]]

silently suppressed evaluation of downstream top-level expressions. The reducer never fired, PHASE-TIMINGS reported reduce_ms = 0, and the computed value was never printed. The same def collapsed to one line worked normally (reduce_ms = 38_855 for a 3-iter benchmark).

Load-bearing for benchmark validity — silent suppression was the worst of both worlds (no error, but no work).

Reproducer (before/after)

def d : [List Rat]
  := '[1/2 1/2 1/2]
d
Form 1 (def) Form 2 (d)
Before Unbound variable: $list-literal Unbound variable: d (reduce_ms=0)
After d : [List Rat] defined '[1/2 1/2 1/2] : [List Rat]

Identical to the one-line form.

Fix

WS reader splices the := BODY continuation into the def's parent token stream. Narrower than the spec splice rule from PR #4: only continuations whose first token is := are spliced. Bare bodies, + 1 2 applications, bracketed groups stay wrapped, preserving today's def c\n + 1 2(def c (+ 1 2)) semantics.

Implementation: added def-form-node?, flatten-with-boundaries/def, continuation-starts-with-assign? to parse-reader.rkt, dispatched in tree-node->stx-elements.

Coexistence note with PR #4 (pitfall #6)

PR #4 (pitfall #6) is not yet merged to main, but uses the same dispatch site in tree-node->stx-elements. This PR introduces the flatten-with-boundaries/spec triple from PR #4's commit 6c42aa9 alongside the new def helpers because both fixes share the dispatch site. Whichever lands second will need a small dedup of flatten-with-boundaries/spec, spec-form-node?, and continuation-starts-with-keyword?.

Test plan

  • New tests/test-def-multiline-ws.rkt — 12 cases: datum-level equivalence between one-line and two-line forms, end-to-end evaluation regression, := on its own line, multi-line BODY
  • Adjacent regression sample (337 tests across 11 files: process-ws-01, parse-reader, let-arrow-syntax, spec*, defmacro, cond-01, bound-args-01, int-patterns-01, first-rest-01, hashable-01) all pass
  • Lib examples re-run cleanly: lattices.prologos, foreign.prologos, 2026-04-02-ppn-track3.prologos
  • CI fix included (benchmarks/micro/info.rkt)

Commits

  1. e7dbc0f — primary fix in parse-reader.rkt + new test file
  2. 2ebdb15 — CI fix (skip stale bench file)

https://claude.ai/code/session_01MbncYJnrvjzhbVWw4xGi5x


Generated by Claude Code

@kumavis kumavis force-pushed the claude/fix-eigentrust-pitfall-15-mldef branch from 2ebdb15 to 5331e70 Compare April 26, 2026 01:03
kumavis added a commit that referenced this pull request Apr 26, 2026
Adds pvec-nth-int / pvec-length-int / pvec-take-int / pvec-drop-int to
prologos::core::pvec, mirroring the existing nth-int / length-int /
take-int / drop-int quartet on List. These let an algorithm that already
carries Int counters (e.g. for an int-le budget termination check)
index into a PVec without maintaining a parallel Nat counter.

Implementation routes through pvec-to-list and the existing List Int
helpers (and back via pvec-from-list for take/drop), avoiding a
freshly-introduced Int->Nat conversion primitive. An earlier draft
defined a private int-to-nat-clamp helper and called pvec-slice
directly, but pvec-slice's whnf rule needs nat-value to succeed on its
lo/hi args — and a defn-defined int-to-nat-clamp does not reduce far
enough inside the slice's whnf to satisfy nat-value, leaving the slice
stuck. Routing through List sidesteps this entirely and matches the
List versions' semantics exactly: negative indices are out-of-range,
out-of-bounds nth returns none, take/drop clamp to [0, length].

Cost: O(n) for nth-int/take-int/drop-int (matching the List
counterparts). pvec-length-int is O(log32 n).

Did NOT add a top-level Int -> Nat helper. The pitfall noted that
from-int : Int -> Nat does not exist, but `from-int` is already a
parser keyword (Int -> Rat), and the List helpers themselves avoid the
conversion via pure recursion — so a public Int -> Nat would just be a
foot-gun that doesn't unblock anything the new helpers don't already
address.

Tests: tests/test-pvec-int-helpers.rkt covers length on empty/1/2,
nth at 0/1/last/negative/out-of-bounds/empty, take and drop at
1/0/negative/larger-than-length, and a take+drop length round-trip.
A standalone smoke test (run separately) exercises all 16 cases via
process-string + pvec-to-list/pvec-length-int and confirms PASS on
both Racket 8.10 (with current-parallel-executor #f) and Racket 9.1.
The test file uses the standard test-support.rkt + rackunit pattern;
the pre-existing (thread #:pool 'own) blocker on Racket 8.10 prevents
running it via `raco test` here, but it is ready for the standard
test runner.

https: //claude.ai/code/session_01MbncYJnrvjzhbVWw4xGi5x
Co-authored-by: kumavis <1474978+kumavis@users.noreply.github.com>
@kumavis kumavis force-pushed the claude/fix-eigentrust-pitfall-15-mldef branch from 5331e70 to 1f67a47 Compare April 26, 2026 03:06
kumavis added a commit that referenced this pull request Apr 26, 2026
Adds pvec-nth-int / pvec-length-int / pvec-take-int / pvec-drop-int to
prologos::core::pvec, mirroring the existing nth-int / length-int /
take-int / drop-int quartet on List. These let an algorithm that already
carries Int counters (e.g. for an int-le budget termination check)
index into a PVec without maintaining a parallel Nat counter.

Implementation routes through pvec-to-list and the existing List Int
helpers (and back via pvec-from-list for take/drop), avoiding a
freshly-introduced Int->Nat conversion primitive. An earlier draft
defined a private int-to-nat-clamp helper and called pvec-slice
directly, but pvec-slice's whnf rule needs nat-value to succeed on its
lo/hi args — and a defn-defined int-to-nat-clamp does not reduce far
enough inside the slice's whnf to satisfy nat-value, leaving the slice
stuck. Routing through List sidesteps this entirely and matches the
List versions' semantics exactly: negative indices are out-of-range,
out-of-bounds nth returns none, take/drop clamp to [0, length].

Cost: O(n) for nth-int/take-int/drop-int (matching the List
counterparts). pvec-length-int is O(log32 n).

Did NOT add a top-level Int -> Nat helper. The pitfall noted that
from-int : Int -> Nat does not exist, but `from-int` is already a
parser keyword (Int -> Rat), and the List helpers themselves avoid the
conversion via pure recursion — so a public Int -> Nat would just be a
foot-gun that doesn't unblock anything the new helpers don't already
address.

Tests: tests/test-pvec-int-helpers.rkt covers length on empty/1/2,
nth at 0/1/last/negative/out-of-bounds/empty, take and drop at
1/0/negative/larger-than-length, and a take+drop length round-trip.
A standalone smoke test (run separately) exercises all 16 cases via
process-string + pvec-to-list/pvec-length-int and confirms PASS on
both Racket 8.10 (with current-parallel-executor #f) and Racket 9.1.
The test file uses the standard test-support.rkt + rackunit pattern;
the pre-existing (thread #:pool 'own) blocker on Racket 8.10 prevents
running it via `raco test` here, but it is ready for the standard
test runner.

https: //claude.ai/code/session_01MbncYJnrvjzhbVWw4xGi5x
Co-authored-by: kumavis <1474978+kumavis@users.noreply.github.com>
kumavis added a commit that referenced this pull request Apr 26, 2026
Adds pvec-nth-int / pvec-length-int / pvec-take-int / pvec-drop-int to
prologos::core::pvec, mirroring the existing nth-int / length-int /
take-int / drop-int quartet on List. These let an algorithm that already
carries Int counters (e.g. for an int-le budget termination check)
index into a PVec without maintaining a parallel Nat counter.

Implementation routes through pvec-to-list and the existing List Int
helpers (and back via pvec-from-list for take/drop), avoiding a
freshly-introduced Int->Nat conversion primitive. An earlier draft
defined a private int-to-nat-clamp helper and called pvec-slice
directly, but pvec-slice's whnf rule needs nat-value to succeed on its
lo/hi args — and a defn-defined int-to-nat-clamp does not reduce far
enough inside the slice's whnf to satisfy nat-value, leaving the slice
stuck. Routing through List sidesteps this entirely and matches the
List versions' semantics exactly: negative indices are out-of-range,
out-of-bounds nth returns none, take/drop clamp to [0, length].

Cost: O(n) for nth-int/take-int/drop-int (matching the List
counterparts). pvec-length-int is O(log32 n).

Did NOT add a top-level Int -> Nat helper. The pitfall noted that
from-int : Int -> Nat does not exist, but `from-int` is already a
parser keyword (Int -> Rat), and the List helpers themselves avoid the
conversion via pure recursion — so a public Int -> Nat would just be a
foot-gun that doesn't unblock anything the new helpers don't already
address.

Tests: tests/test-pvec-int-helpers.rkt covers length on empty/1/2,
nth at 0/1/last/negative/out-of-bounds/empty, take and drop at
1/0/negative/larger-than-length, and a take+drop length round-trip.
A standalone smoke test (run separately) exercises all 16 cases via
process-string + pvec-to-list/pvec-length-int and confirms PASS on
both Racket 8.10 (with current-parallel-executor #f) and Racket 9.1.
The test file uses the standard test-support.rkt + rackunit pattern;
the pre-existing (thread #:pool 'own) blocker on Racket 8.10 prevents
running it via `raco test` here, but it is ready for the standard
test runner.

https: //claude.ai/code/session_01MbncYJnrvjzhbVWw4xGi5x
Co-authored-by: kumavis <1474978+kumavis@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

@hierophantos hierophantos left a comment

Choose a reason for hiding this comment

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

LGTM. Surgical scope mirrors #4 (preparser splice based on first-token check), with a deliberately narrower rule: only :=-headed continuations splice; bare bodies stay wrapped — preserving def c\n + 1 2(def c (+ 1 2)) semantics for the existing bare-body idiom. End-to-end test coverage (using run-ns-ws-last) pins the silent-suppression case, which is the worst-quality bug shape (no error, just no work — was reporting reduce_ms = 0 in benchmarks).

Audit-passed against our codebase: 354 single-line def := body exist, all unaffected; zero multi-line def usage today, so the change is purely additive.

Now that #4 has landed (3d7ccb19), this PR is showing CONFLICTING — per your own note in the PR body, needs a rebase to drop the duplicate spec-form-node? / flatten-with-boundaries/spec / continuation-starts-with-keyword? (now on main) and add the def-form-node? branch on top of the existing spec-form-node? cond clause.

Approving — ready to merge once the rebase lands.

@kumavis kumavis force-pushed the claude/fix-eigentrust-pitfall-15-mldef branch from 1f67a47 to b51900d Compare April 27, 2026 06:32
@kumavis kumavis force-pushed the claude/fix-eigentrust-pitfall-15-mldef branch from b51900d to d1c92a5 Compare April 27, 2026 08:06
kumavis pushed a commit that referenced this pull request Apr 27, 2026
Wires the OCapN port to a real Racket toolchain and fixes the issues
the test run surfaced.

Library fixes
  - vat.prologos: rename `spawn` -> `vat-spawn` (collision with the
    reserved surface form recognised in macros.rkt:`'spawn`),
    `spawn-actor` -> `vat-spawn-actor`. Same in core.prologos and the
    acceptance file.
  - vat.prologos: drop the `Sigma Vat Nat` return shape for spawn /
    fresh-promise / send. Replace with a named `Allocated` struct +
    `alloc-vat` / `alloc-id` accessors. The Sigma form ran into
    "could not infer" elaborator errors when the body destructured
    via `match | pair a b -> ...` and then re-constructed a Sigma;
    `[fst p]` / `[snd p]` reused on the same `p` tripped QTT
    multiplicity. The named struct sidesteps both.
  - vat.prologos: reorder `resolve-promise` / `break-promise` BEFORE
    `apply-effect` (forward-reference rule — module elaboration is
    single-pass top-to-bottom). Also reorder `step-after-act` before
    `deliver-msg` and `list-length-helper` before `queue-length`.
  - vat.prologos: drop the queued-pipeline-flush in resolve-promise /
    break-promise. PromiseState's queue is `List SyrupValue` (wire
    repr); the vat queue is `List VatMsg` (decoded); flushing across
    the boundary would need re-encoding. Phase 1.

Test-fixture fix (load-bearing)
  - All 8 OCapN test files were updated to capture and restore
    `current-ctor-registry` and `current-type-meta` across the setup-
    -> run boundary. The standard fixture pattern from
    `test-hashable-01.rkt` does NOT preserve these — fine for tests
    that only declare traits, but breaks once a preamble's imports
    declare new `data` types (every `data` in our 8 modules). Without
    it, the reducer sees a stale ctor-registry and refuses to fire
    pattern arms over user constructors; results print as un-reduced
    `[reduce ... | vat x y z a -> x] : Nat` strings.
    Documented as goblin-pitfall #12; the canonical fixture in
    test-support.rkt should grow this for every future test.

Compat fence
  - driver.rkt: guard
    `(current-parallel-executor (make-parallel-thread-fire-all))` with
    a feature-detection try/catch on `thread #:pool 'own`. Racket 9
    ships parallel threads; Racket 8 does not. Fence preserves the
    Racket-9 fast path and falls back to sequential firing on 8.

Acceptance
  - examples/2026-04-27-ocapn-acceptance.prologos updated to match
    the new vat-spawn/Allocated API and verified to run clean via
    process-file.

Pitfalls catalogue (docs/tracking/2026-04-27_GOBLIN_PITFALLS.md)
  - #0 (sandbox/no-Racket): closed.
  - +#11 — Racket-8 vs Racket-9 `thread #:pool` compat
  - +#12 — test fixture loses ctor-registry/type-meta across calls
           [highest-impact; canonical fixture pattern needs update]
  - +#13 — `spawn` is a reserved surface keyword; collides silently
  - +#14 — `match | pair a b ->` on Sigma + Sigma reconstruction =>
           "could not infer"
  - +#15 — QTT multiplicity on `[fst p]`/`[snd p]` reused thrice
  - +#16 — single-pass module elaboration: forward references error
  - +#17 — promise-queue (Syrup) vs vat-queue (VatMsg) type clash
           on flush — design pitfall, scope cut

Test results
  refr      6/6   syrup    22/22  promise   16/16  message  19/19
  behavior 13/13  vat     21/21   pipeline   5/5   captp     7/7
  e2e       8/8                                  total  117/117 PASS
kumavis pushed a commit that referenced this pull request Apr 27, 2026
Per user direction:
- Replace the body of every DELETED entry with a single-sentence
  explanation. Numbers reserved per prior instruction.
- Delete #15 (QTT multiplicity on fst/snd thrice). I re-tested
  with a real Racket — `pair [snd p] [fst p]` then a third use of
  `fst p` works fine; no multiplicity error. The failure I had
  conflated this with was actually #14's "match-and-reconstruct
  Sigma" issue.

Result: pitfalls doc shrinks from 765 to 534 lines. Remaining
real claims: #1, #4, #5, #11, #12, #13, #14, #16, #17, #18, #19,
#20 (the user has reviewed only #0-10 so far; #11-20 still
pending their review).
…alls #15)

A two-line def with type annotation —

    def c : [List Int]
      := '[1 2 3]

— silently suppressed evaluation: PHASE-TIMINGS reported reduce_ms=0
and the bound name elaborated but never reduced. The same def collapsed
to one line worked normally. The silent-no-work shape was particularly
bad for benchmarks (reported zero reduce time regardless of workload).

Add a def-form-node? branch to tree-node->stx-elements and a
flatten-with-boundaries/def variant that splices ONLY continuations
whose first token is :=. All other continuations (bare body, bracketed
application chain, etc.) stay wrapped, preserving today's

    def c
      + 1 2

→ (def c (+ 1 2)) semantics for the bare-body idiom.

Narrower than the spec splice rule (#4 / #6) on purpose: spec needs to
expose -> from anywhere in a multi-line type signature, def only needs
to expose := which is always the head of a natural line break.

Test coverage in test-def-multiline-ws.rkt covers:
  - Datum equivalence between one-line and two-line shapes (12 cases).
  - Bare-body wrapping is preserved.
  - End-to-end via run-ns-ws-last (silent-suppression regression pin).
  - Multi-line BODY after :=, := alone on a line, and definitions
    spanning lines as bracketed groups.

Three-level WS validation:
  - Level 1 (sexp): the test file uses run-ns-last where applicable.
  - Level 2 (WS string): ws-read / run-ns-ws-last cover the dispatch
    and elaboration paths.
  - Level 3 (WS file): process-file on a .prologos with the two-line
    form reports reduce_ms=5 / reduce_steps=39, matching the one-line
    shape exactly (was reduce_ms=0 / reduce_steps=0 before).

https://claude.ai/code/session_01MbncYJnrvjzhbVWw4xGi5x

Co-authored-by: kumavis <1474978+kumavis@users.noreply.github.com>
@kumavis kumavis force-pushed the claude/fix-eigentrust-pitfall-15-mldef branch from d1c92a5 to 274cd2a Compare April 28, 2026 21:19
@kumavis kumavis requested a review from hierophantos April 30, 2026 20:04
kumavis added a commit that referenced this pull request Apr 30, 2026
Adds pvec-nth-int / pvec-length-int / pvec-take-int / pvec-drop-int to
prologos::core::pvec, mirroring the existing nth-int / length-int /
take-int / drop-int quartet on List. These let an algorithm that already
carries Int counters (e.g. for an int-le budget termination check)
index into a PVec without maintaining a parallel Nat counter.

Implementation routes through pvec-to-list and the existing List Int
helpers (and back via pvec-from-list for take/drop), avoiding a
freshly-introduced Int->Nat conversion primitive. An earlier draft
defined a private int-to-nat-clamp helper and called pvec-slice
directly, but pvec-slice's whnf rule needs nat-value to succeed on its
lo/hi args — and a defn-defined int-to-nat-clamp does not reduce far
enough inside the slice's whnf to satisfy nat-value, leaving the slice
stuck. Routing through List sidesteps this entirely and matches the
List versions' semantics exactly: negative indices are out-of-range,
out-of-bounds nth returns none, take/drop clamp to [0, length].

Cost: O(n) for nth-int/take-int/drop-int (matching the List
counterparts). pvec-length-int is O(log32 n).

Did NOT add a top-level Int -> Nat helper. The pitfall noted that
from-int : Int -> Nat does not exist, but `from-int` is already a
parser keyword (Int -> Rat), and the List helpers themselves avoid the
conversion via pure recursion — so a public Int -> Nat would just be a
foot-gun that doesn't unblock anything the new helpers don't already
address.

Tests: tests/test-pvec-int-helpers.rkt covers length on empty/1/2,
nth at 0/1/last/negative/out-of-bounds/empty, take and drop at
1/0/negative/larger-than-length, and a take+drop length round-trip.
A standalone smoke test (run separately) exercises all 16 cases via
process-string + pvec-to-list/pvec-length-int and confirms PASS on
both Racket 8.10 (with current-parallel-executor #f) and Racket 9.1.
The test file uses the standard test-support.rkt + rackunit pattern;
the pre-existing (thread #:pool 'own) blocker on Racket 8.10 prevents
running it via `raco test` here, but it is ready for the standard
test runner.

https: //claude.ai/code/session_01MbncYJnrvjzhbVWw4xGi5x
Co-authored-by: kumavis <1474978+kumavis@users.noreply.github.com>
@hierophantos hierophantos merged commit a443b64 into main Apr 30, 2026
1 check passed
@hierophantos hierophantos deleted the claude/fix-eigentrust-pitfall-15-mldef branch April 30, 2026 21:42
kumavis pushed a commit that referenced this pull request May 4, 2026
Wires the OCapN port to a real Racket toolchain and fixes the issues
the test run surfaced.

Library fixes
  - vat.prologos: rename `spawn` -> `vat-spawn` (collision with the
    reserved surface form recognised in macros.rkt:`'spawn`),
    `spawn-actor` -> `vat-spawn-actor`. Same in core.prologos and the
    acceptance file.
  - vat.prologos: drop the `Sigma Vat Nat` return shape for spawn /
    fresh-promise / send. Replace with a named `Allocated` struct +
    `alloc-vat` / `alloc-id` accessors. The Sigma form ran into
    "could not infer" elaborator errors when the body destructured
    via `match | pair a b -> ...` and then re-constructed a Sigma;
    `[fst p]` / `[snd p]` reused on the same `p` tripped QTT
    multiplicity. The named struct sidesteps both.
  - vat.prologos: reorder `resolve-promise` / `break-promise` BEFORE
    `apply-effect` (forward-reference rule — module elaboration is
    single-pass top-to-bottom). Also reorder `step-after-act` before
    `deliver-msg` and `list-length-helper` before `queue-length`.
  - vat.prologos: drop the queued-pipeline-flush in resolve-promise /
    break-promise. PromiseState's queue is `List SyrupValue` (wire
    repr); the vat queue is `List VatMsg` (decoded); flushing across
    the boundary would need re-encoding. Phase 1.

Test-fixture fix (load-bearing)
  - All 8 OCapN test files were updated to capture and restore
    `current-ctor-registry` and `current-type-meta` across the setup-
    -> run boundary. The standard fixture pattern from
    `test-hashable-01.rkt` does NOT preserve these — fine for tests
    that only declare traits, but breaks once a preamble's imports
    declare new `data` types (every `data` in our 8 modules). Without
    it, the reducer sees a stale ctor-registry and refuses to fire
    pattern arms over user constructors; results print as un-reduced
    `[reduce ... | vat x y z a -> x] : Nat` strings.
    Documented as goblin-pitfall #12; the canonical fixture in
    test-support.rkt should grow this for every future test.

Compat fence
  - driver.rkt: guard
    `(current-parallel-executor (make-parallel-thread-fire-all))` with
    a feature-detection try/catch on `thread #:pool 'own`. Racket 9
    ships parallel threads; Racket 8 does not. Fence preserves the
    Racket-9 fast path and falls back to sequential firing on 8.

Acceptance
  - examples/2026-04-27-ocapn-acceptance.prologos updated to match
    the new vat-spawn/Allocated API and verified to run clean via
    process-file.

Pitfalls catalogue (docs/tracking/2026-04-27_GOBLIN_PITFALLS.md)
  - #0 (sandbox/no-Racket): closed.
  - +#11 — Racket-8 vs Racket-9 `thread #:pool` compat
  - +#12 — test fixture loses ctor-registry/type-meta across calls
           [highest-impact; canonical fixture pattern needs update]
  - +#13 — `spawn` is a reserved surface keyword; collides silently
  - +#14 — `match | pair a b ->` on Sigma + Sigma reconstruction =>
           "could not infer"
  - +#15 — QTT multiplicity on `[fst p]`/`[snd p]` reused thrice
  - +#16 — single-pass module elaboration: forward references error
  - +#17 — promise-queue (Syrup) vs vat-queue (VatMsg) type clash
           on flush — design pitfall, scope cut

Test results
  refr      6/6   syrup    22/22  promise   16/16  message  19/19
  behavior 13/13  vat     21/21   pipeline   5/5   captp     7/7
  e2e       8/8                                  total  117/117 PASS
kumavis pushed a commit that referenced this pull request May 4, 2026
Per user direction:
- Replace the body of every DELETED entry with a single-sentence
  explanation. Numbers reserved per prior instruction.
- Delete #15 (QTT multiplicity on fst/snd thrice). I re-tested
  with a real Racket — `pair [snd p] [fst p]` then a third use of
  `fst p` works fine; no multiplicity error. The failure I had
  conflated this with was actually #14's "match-and-reconstruct
  Sigma" issue.

Result: pitfalls doc shrinks from 765 to 534 lines. Remaining
real claims: #1, #4, #5, #11, #12, #13, #14, #16, #17, #18, #19,
#20 (the user has reviewed only #0-10 so far; #11-20 still
pending their review).
hierophantos added a commit that referenced this pull request May 5, 2026
…2-pv12

pvec: add Int-indexed helpers (eigentrust pitfall #12)
@hierophantos
Copy link
Copy Markdown
Contributor

Post-rebase verified clean: dispatch in tree-node->stx-elements extended from spec-only if to 3-way cond (spec/def/else); duplicate spec helpers correctly absent (delegated to #4 which already landed them); flatten-with-boundaries/def only splices := continuations preserving the bare-body wrap semantics. Same scope as original approval. Merging.

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.

3 participants