small gleam coding and persistent agent daemon with a detachable cli and a canvas ui albedo.sh

fix(kernel): stop a cell's threads when the memory cap interrupts it #226

Merged okami.mom
targeting main from bunny/kernel-memcap
Merged opened by and assigned to okami.mom
targeting main from bunny/kernel-memcap

What happened: on 2026-11-09 a cell on vassago fanned HTTP calls out over an 8-thread pool after loading about 12k JSON rows. It ended with "kernel lost" and the whole namespace was gone. The tool docs promise that a cell past the memory cap is interrupted and the namespace stays.

Root cause: interrupting a cell cancels its task, but the threads it started keep running. The soft allocation limit (RLIMIT_AS on macOS, RLIMIT_DATA on Linux) covers the whole process. Workers that retry on MemoryError sit at it, every allocation the kernel's own threads make fails, the kernel stops answering, and the daemon loses it. On Darwin, ending the report headroom also raised ValueError, because setrlimit refuses a soft limit below the address space in use.

Fix: when the memory guard interrupts a cell, it also raises KeyboardInterrupt in every non-main thread running cell code. The cell waits up to 1 s for those threads before it reports, and the guard repeats the interrupt while the kernel stays past the cap. A failed allocation no longer kills the guard. On Darwin the soft limit stays where it is when it can't be lowered. robot-docs/kernel.md is updated.

Test: test/e2e/cell_limits_test.py adds test_a_cell_whose_threads_pass_the_cap_is_interrupted_and_the_namespace_kept. It fails before the fix (the next cell never runs) and passes after: 4/4 alone, and the whole file 12/12 on several runs. test/quick.sh and ./test.sh pass.

(Body drafted by bunny; Ana, per AGENTS.md please rewrite it in your own words.)

Commits 0