io.fork() and io.exit() — a child that inherits the runtime's open stateio runs a child only through spawnFds (fork + exec of another binary) and reaps it with reap. BEE-072 wants a plain fork(): a child that KEEPS the parent's memory — the ODB handle, the open abc.index lanes, the parsed trees, the list of blobs to index — and does a stripe of the work before leaving, the spot --fork N shape (beagle/spot/CAPO.exe.c:806). Two leaves: io.fork() -> pid (0 in the child) and io.exit(code), an _exit that skips every parent-side teardown, since the child's copies of the handles are not its to close. The runtime is single-threaded, so a fork without an exec is safe here on every platform quickjab builds for.
io.c JABCioSpawnFds / JABCioReap: the existing pair, posix_spawn-style, the child dupping the given fds; reap returns { code, signal }.fork(): one runtime, one context, no threads, so the child's interpreter is a consistent copy; the rpmalloc heap is per process after the copy. mmaped runs and blobs are shared copy-on-write; open fds are shared, which is why a child must not seal or close a lane it inherited (BEE-072 rules that on the bee side).atexit/destructor teardown in main.c (the runtime free, the ulog flush) must NOT run in the child — a normal exit there would double-free the parent's world through the copy.io.fork() -> pid: the fork(2) return value as a Number, 0 in the child; a failure throws in plain words with errno's text. Nothing else changes in either process.io.exit(code): _exit(code & 0xff), no atexit, no flush beyond what the caller did; documented as the ONLY way out of a forked child.io.reap(pid) as today reaps a forked child too (it is waitpid; verify it does not assume a spawned one).test/fork.js (or a leg in the io suite): parent forks two children, each writes one file and io.exit(7); the parent reaps both and reads code === 7 and the files; a child that throws and exits 1 reads as code === 1; io.exit in the child leaves the parent's open lane usable (a put and a commit after the reap succeed).INDEX.md / API.md of the io package mention the pair (the docs live in ~/src/jab; say so if they are out of this ticket's reach, as QJAB-013 did).io.c, main.c if the exit path needs a hook, the test; nothing in dog/; no commit.vfork; the child runs arbitrary JS.build-unbundled with ninja; ~/bin/quickjab is not replaced by the agent._exit over exit for the child: the parent's teardown belongs to the parent; the child owns only what it opened after the fork, and BEE-072 closes those before calling io.exit.fork, exit leaves + registration~/src/jab