# Handoff — 2026-09-19 (written before a full /clear) Read this, then delete it. Style: user wants extreme concision, plain language, no filler, decisions discussed one at a time BEFORE dispatching, agents dispatched one at a time. No commit watermarks. `dune test` stays fast. ## State of the repo - Branch `dev-loop`, tip `73ab213` (merge of the x86 dyn + conditions lane). All green after merge: dune test 287/0, @x86 137 match / 0 differ, @sanitize clean. - dyn now works on the default x86 dev daemon. handler-bind is now a value (body's last form) on both backends. - `sand.flan` is the author's UNCOMMITTED WIP. Never commit it. Stash around merges (`git stash push sand.flan -m wip`, pop after). `game-data.edn` untracked, leave it. - Known open hole (flagged, not fixed): `dune test` exits 0 even when test_acceptance prints failures — nothing surfaces them. ## In flight: M2 item 1 — dyn maps + keywords Agent worktree: `.claude/worktrees/agent-a3009901a950e8daa` (branch `worktree-agent-a3009901a950e8daa`). NOT committed yet — uncommitted changes across lib/{ast,check,emit,load,parse,prelude}.ml, runtime/flan_dyn.{h,c}, test/dune; it was writing checker/parse tests in test/test_flan.ml when it hit the session limit (resets 7:20pm Asia/Bangkok). To finish: spawn an agent IN THAT WORKTREE (don't reset it) with: "Finish the in-progress dyn maps + keywords lane. Read the uncommitted diff first to see what exists. Remaining: tests in test_flan.ml, acceptance rows (LLVM, -O0, --x86; run programs for real output, never guess wording; no double-quotes in OCaml comments), then ONCE at the end: dune test --force, dune build @x86 --force, dune build @sanitize --force. Commit in the repo's prose voice." Then: stash sand.flan, merge, run the three sweeps, pop stash. ## M2 queue (FIX.org "M2 queue" section, line ~408) — dispatch ONE AT A TIME 1. dyn maps + keywords (in flight, above) 2. per-type descriptors — use Opus-class agent (representation change) 3. typed containers into dyn as views (rides on 2) 4. nil↔None at (Option T) 5. typed =/!= grow strings 6. defclass = named dyn map + CLOS/Clojure dispatch (after 1) 7. dyn if truthiness 8. return slot stays mandatory — decision only, no work Model plan agreed with user: session on Opus, Sonnet agents for items 3–8, Opus agents for item 2 and for reviews of merges. ## Not yet recorded in FIX.org (do this early, cheap) Append a section on the syntax-family discussion (2026-09-19): - User wants an F#-ish indentation/ML surface syntax, side by side with s-exprs. Languages that "disappear" for them: Python > Odin > F#. - Agreed architecture if it happens: one AST (the existing forms), second reader; macros stay usable from both; Nim-style quote-block could allow writing macros in ML syntax too. - Middle options discussed: Parinfer (editor-only), wisp/sweet-exprs (indentation-implied parens), simplified in-paren syntax. Rhombus = the maximal reference. - DECISION: deferred, no spike queued. User's current hypothesis: their Clojure friction may be immutability/planning-ahead, not parens — they will write imperative Flan as-is and see if parens still grate. Revisit with that evidence. ## Environment notes - /tmp (7.6G tmpfs) was 100% full; freed ~470M of stale dune test dirs, now ~95%. Remaining bulk: 2.6G Refold-Defold Claude scratch + ~850M numeric JVM/Defold dirs — user hasn't said whether that session is closed; ask before deleting. - Verify agents' worktree bases: every past agent arrived stale. Prompt must demand git log check + reset to dev-loop tip. - Repeated full sweeps are the main time sink — tell agents to verify incrementally, full sweeps once at the end.