plan.md: split row 14 into the MA ladder (14a-14f) — multi-actor is not one deliverable #50
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/050-plan-md-split-row-14-into-the-ma-ladder-14a-14"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
plan.md: split row 14 into the MA ladder (14a-14f) — multi-actor is not one deliverable
Along the way:
Touches 2 files:
decisions-scheduler-model.md,plan.md.Measured. It is a named constant in
decisions-scheduler-model.mdnow, with a line saying how.Comment added on
childinplan.md. It was obvious when I wrote it and it will not be in a month.Updated. The point about
decisions-scheduler-model.mdturned out to be a real bug, so thank you.I do not want to merge while the error path in
decisions-scheduler-model.mdis silent. The rest is fine.@ -70,0 +105,4 @@to actor X". The timer queue is scheduler state; a DUE tick enqueues anORDINARY message (FIFO, the normal mailbox path — no special delivery, sodeterminism and the meta stream are untouched). This is `snake.md`'s tickstone in its real form, and the MMO server's ~20 ticks/s driver.Where does the number beside
stonecome from? It reads as measured rather than chosen, and nothing on the line says which.@ -107,0 +106,4 @@| 14a | **MA1 · the missing primitives — loops + byte width** *(design fully closed: `decisions-scheduler-model.md` — cooperative FIFO, per-state writer, run-to-completion CONFIRMED, mailbox-full = RAISE, loops/tick/park decided)*: (1) **`for` + `while<N>` loops** (LC9's loop half pulled forward; owner 2026-07-02: recursion-only is not enough): `for` over a bounded range/collection, `while<N>` with a declared bound — the iterative twin of `rec<N>`; NO unbounded loop exists (indefinite execution = a scheduled actor, never a spin); front-end + CFG back-edge lowering (LC2 blocks); (2) **recursion EXECUTION** gated (`fib_runs`, pulled from Rung 1 — FS5.2 built parse/check/size; plausibly a gate, not a feature); (3) **`Memory::load/store::<u8>`** — the third machine-op width (FS4 pattern); (4) **`Bytes.ck` in PURE CkLang** (loops over u8 loads/stores) promoted into the live stdlib, then **`Meta.ck`'s `append_str`/`str_len` special forms rewritten as real CkLang over `Bytes.ck`**. After this row the only pass special forms left are the irreducible floor ISA (cells, `dispatch`, `raise_word`) — registered `= intrinsic` leaves, the `Memory::load` tier | `for`/`while<N>` corpus stones (exit-code loops); `fib_runs` executes; `Bytes::copy` round-trips; Meta.ck streams byte-identical after the rewrite (goldens prove it) || 14b | **MA2 · messages can exist — union-ABI copy + `send`/`receive` front-end** (one agent, two checkpoint commits — the LC6/LC7 pattern): first the **union-ABI sliver** — a payload-union value crosses a call boundary **by copy** (the LC5 scope-out; messages ARE payload variants, nothing sends until this lowers); then the **front-end** — receive slots parse fully (snake's `World.ck` E0110/E0105 trap rows ratchet DOWN), sends resolve + typecheck (message type ∈ the actor's declared receive set; synthesis-only, plan §5) | union-copy corpus stone round-trips; type goldens; `snake/trap.md` shrinks; an honest "send does not lower yet" error || 14c | **MA3 · `Mailbox.ck` + `Scheduler.ck` + `Clock.ck` — 100% CkLang** (one agent, checkpoint commits): the bounded FIFO ring in pure CkLang over `Memory`/`Arena`/`Bytes` (full → `Panic::raise`, the locked decision; generic-free bootstrap like `Arena.ck` if LC6's cross-module-template scope-out bites — report); the run loop in pure CkLang (bounded drain via `while<N>`/`for`; FIFO writer queue; per-actor arena-cell swap via `Supervisor::adopt`; handler dispatch via `dispatch`); `send` lowering to enqueue + a self-send driver; **`Clock::tick`** — the timer queue as scheduler state, "every X ms send `Tick` to actor" with a DUE tick enqueuing an ORDINARY message (FIFO, determinism untouched); **the park** — no runnable + timers pending → `nanosleep`(35) until next due (syscall table + `clock_gettime`(228)); no timers + no messages → drain-exit. NOTHING SPINS. `epoll` stays Rung 3's. **Bonus: real meta-event timestamps** (`clock_gettime` wired ⇒ the timestamp-0 residue retires) | driver-level enqueue/dequeue gate (FIFO + bound + full-raise asserted); the `tick` stone (snake.md Rung 2): a `Clock::tick`-driven actor accumulates N ticks → exit = count, CPU parked between ticks (no busy loop — assert wall-clock ≥ N×interval); meta events carry real timestamps || 14d | **MA4 · multi-actor + send-is-serialize → `counter`**: `Supervisor.ck` spawns a child (id allocation, child arena — the ids stop being constants), cross-actor send through the serialize→transmit→deserialize codec in CkLang over `Bytes.ck` (only `imm` + tags/ActorIds cross) | **gate: `tests/corpus/counter` runs** — joined state serialized through ONE mailbox, deterministic count, 2-actor lifecycle on the meta stream |I had to read
childtwice. Nothing wrong with it, but one line of comment would save the next person the second read.Both answered, and
decisions-scheduler-model.mdreads right now. Merging.