Skip to content

Commit 9b0321b

Browse files
committed
docs(debt+handover): D-557 narrowed (lazy-for double-consumption; shadow/reverse innocent; vec-wrap fixes) + resume contract -> D-557 first
Repro preserved at private/d557_repro (gitignored) with the v3/v5/v7 variant matrix. D-555's remaining pair + nightly-CI cadence wiring queued behind it.
1 parent 40ccdc7 commit 9b0321b

2 files changed

Lines changed: 11 additions & 7 deletions

File tree

‎.dev/debt.yaml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@
2525

2626
active:
2727
- id: "D-557"
28-
status: "open (2026-07-07, found DURING the D-556 verification — a SEPARATE, GC-independent tree_walk bug). The rewritten cw-arcade rush-hour solver (two-list amortized queue: 3-arity self-call chain + loop [front back visited] + (recur (reverse back) () visited) + a let that destructures [state path] (first front) and SHADOWS front with (rest front)) fails on the tree_walk backend with `-nth on Long` at the destructure line — (first front) returns a Long, i.e. a slot/shadow resolution defect. DETERMINISTIC; vm green on the identical code; CLJW_GC_THRESHOLD_MB=100000 (GC off) still fails -> NOT a rooting issue. Direct call fails too (no clojure.test needed). Simple synthetic shadow shapes pass — the trigger needs the real solver's combination (multi-arity self-call + reverse/list queue + same-name shadow + for). REPRO: scratchpad rhmin copy (or cw-arcade apps/rush-hour post-2026-07-07-edit sources), tree_walk build, cljw -cp src run_direct.clj. Fix by minimizing from the real solver; land the distilled case as a diff-oracle case (the F-012 net SHOULD have caught this — its absence is the gap D-555's cadence work addresses)."
28+
status: "NARROWED 2026-07-07 (same session): the SHADOW is innocent (renaming front->front2 still fails); reverse is innocent (dropping it still fails); wrapping the for in `vec` FIXES it -> the defect is in the LAZY `for` seq being held across recur iterations and consumed TWICE ((into back nexts) then (map first nexts)) on the tree_walk backend — (first front) later yields a Long, i.e. a lazy-seq cell or chunk is corrupted/mis-linked. Synthetic twins (int states, plain + map-destructure for-bindings, two-list queue, 3000 iters) do NOT reproduce — the real repro needs the cw-arcade board/puzzles shape (map-of-maps states as HAMT-set keys + legal-moves itself built from a for). GC-independent (fails with collect disabled); vm green. REPRO: scratchpad rhmin (solver.clj = the 2026-07-07 two-list version), tree_walk build, cljw -cp src run_direct.clj -> `-nth on Long` at solver.clj:48. Variants preserved: solver_v3 (shadow renamed, fails), v5 (no reverse, fails), v7 (vec-wrapped for, PASSES). NEXT: diff the tree_walk lazy-seq/chunk realization path for a double-walk-across-recur defect; distill with the real board shape; land as a diff-oracle case. ORIGINAL: found during D-556 verification."
2929
category: "runtime"
30-
barrier: "none — deterministic repro in hand (tree_walk build + the rhmin copy). Minimize -> analyzer slot-allocation fix -> diff case."
30+
barrier: "none — deterministic repro preserved at private/d557_repro (gitignored): tree_walk build + `cljw -cp src run_direct.clj` fails; run_v7.clj (vec-wrapped for) passes. Minimize with the real board shape -> fix the tree_walk lazy-for double-consumption defect -> diff-oracle case."
3131
last_reviewed: "2026-07-07"
3232
- id: "D-556"
3333
status: "ROOT CAUSE FOUND + FIXED 2026-07-07 (the deftest-BFS integer-overflow panic + the D-555 GC family). The swept-string probe showed the FIRST post-bootstrap collect sweeping foundation strings (\"map\", \"clojure.core\", \"*in*\") on the tree_walk backend: fn-body Node literals live in the heap-lifetime analyzer arena, but the ADR-0169 AnalysisFrame bracket DROPPED its roots at form end — correct only for Nodes that die with their form; a (defn f …) body Node survives via Function.body and its literal pool was unrooted from the first collect on (the vm masks the EXECUTING chunk via the A1 pool root; a not-yet-executed fn had the same latent hole). FIX: root_set.endAnalysisPersist — production seams (driver x2, loader, repl, nrepl, evaluator oracle) persist their bracket roots into gc.persisted_analysis_roots (a GcHeap field, walked after permanent_roots; same lifetime the Nodes already have). ALSO landed in the same arc: the conservative C-stack scan (mark_sweep.conservativeStackScan: stack words from the ADR-0157 anchor + a setjmp register spill (Boehm GC_push_regs idiom), validated against a per-collect live-set hash, pinned — sound under non-moving mark-sweep) as the STRUCTURAL backstop for tree_walk's C-stack intermediates, and the 7 explicit A6/A6b brackets. VERIFIED: the original repro (rush-hour solver-test, pre-edit sources preserved in the scratchpad rhmin copy) passes 3/3 at BOTH default and 1MB thresholds on tree_walk; sym-meta GC e2e green; vm untouched. REMAINING out of scope: registered-WORKER-thread stacks are not conservatively scanned (parked at alloc-prologue; agent+tree_walk is the known D-418-adjacent area)."

‎.dev/handover.md‎

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
66
## Resume contract
77

8-
- **HEAD**: `main` (`git log` = SSOT; tip ≈ `4a51ed2c`). Per-commit = smoke; commit
8+
- **HEAD**: `main` (`git log` = SSOT; tip ≈ `40ccdc77`). Per-commit = smoke; commit
99
**and** push (atomic Step 6). `build.zig.zon` `.zwasm` = tag pin `v2.1.0` (table64-JIT; bumped from v2.0.0).
1010
- **1.0.0 RELEASED (2026-07-01).** cljw `v1.0.0` tagged + pushed (commit a6db5dd6);
1111
release.yml published the GitHub Release (macos-aarch64 + linux-x86_64 binaries +
@@ -14,10 +14,14 @@
1414
(release.yml/CLAUDE.md "loop never tags" is otherwise intact). Demo repos
1515
cw-serverless-demo + cw-playground redeployed to fly.io on v1.0.0 and live-verified
1616
(books+cover-colours / eval+wasm-FFI). ADR-0167 rc.1-readiness campaign CLOSED — 1.0.0 shipped.
17-
- **Track B (parallel, non-blocking for the tag):** the easiest-first `active:`
18-
drain continues — D-522 de-pointer / D-523 doc-audit / D-526 interop / D-527
19-
parity / D-528 real-deps.edn / D-529 / D-305 / D-470 / D-222 / D-460 / D-439 sqrt.
20-
A correctness / clj-parity floor still PREEMPTS.
17+
- **First commit on resume MUST be: D-557** — tree_walk lazy-`for`
18+
double-consumption value corruption (`-nth on Long`); deterministic repro
19+
preserved at `private/d557_repro` (tree_walk build + `cljw -cp src
20+
run_direct.clj`; `run_v7.clj` = vec-wrapped for PASSES — the fix hint).
21+
Then D-555's remaining pair (vm SourceLocation-fallback vs print.zig's
22+
intended caret form + the two e2e expectations) → sweep clean → discharge
23+
+ wire check_vm_parity.sh into the nightly CI leg. Then easiest-first
24+
drain resumes (D-526/D-527/D-528/D-305/D-470/D-554...).
2125
- **Forbidden this session**: bare `zig build test` WITHOUT `-Dwasm`; bare `zig build`
2226
for a probe (use ReleaseSafe). **The FULL gate MUST run `--serial-e2e`** — the `-P8`
2327
parallel default flakes the **D-418/D-258 agent load-race** (`agent_conj` →

0 commit comments

Comments
 (0)