WAYS OF WORKING · APPLIED NINO CHAVEZ
One heavy job.
At a time.
A model running on your own machine makes scheduling an operational decision. When the machine dies anyway, the panic report tells you what happened in integers you can look up — and the recovery is only cheap if the run was already set up to be interrupted.
the panic string, verbatim
initproc exited -- exit reason namespace 2 subcode 0xb
Both integers are defined in a header the vendor publishes. Neither one means what it is usually assumed to mean.
→ or scroll to advance · ← to go back
02 THE FAILURE
Three heavy jobs, one 36 GB machine
A quantized 12-billion-parameter model was running under Apple's MLX at batch size one. On top of it: a worker test suite where every test spawns subprocess bridges, and profiling runs chasing a timeout. The machine kernel-panicked.
No component misbehaved. The failure was a scheduling decision nobody consciously made — each job was started for a good reason, at a moment when the others happened to still be running.
03 READ THE PANIC
The exit reason is two published integers
Panic reports live in the diagnostics folder. The first few KB carry everything you need. Resist translating the string from memory: look both numbers up.
/Library/Logs/DiagnosticReports/panic-full-*.panic initproc → launchd, process 1. The kernel panics by design when it exits. Nothing is left to supervise. namespace → bsd/sys/reason.h · JETSAM = 1, SIGNAL = 2 subcode → in the signal namespace, the signal number 0xb = 11 · signal.h · SIGSEGV READ launchd took a segmentation fault. NOT launchd was killed to reclaim memory.
Jetsam, the mechanism that kills processes under memory pressure, is namespace 1. It never appears in this string.
04 WHAT THE LOG DOESN'T SAY
Separate what you read from what you inferred
The report carries per-process resident memory, so the workload's footprint is observed. Why the process died is not.
Observed
Launchd exited on signal 11. One process held 29.1 GB resident. The compressor held 844,864 pages at the log's own stated page size of 16,384 bytes.Compressor totals are system-wide — never quote one as a job's footprint.
Inferred
That memory exhaustion caused the segmentation fault. It fits the workload, and the report does not state it. One field points the other way: memory pressure reads false at the instant of the panic.Ship it as a hypothesis, in the note and in the write-up.
05 MAKE THE RUN SURVIVABLE
Recovery is bought before the crash, not after
Two finished runs survived with their result digests. The in-flight run left nothing behind, which is the correct outcome — there was no partial file to talk yourself into trusting.
Write atomically
Emit the result once, at the end, as a single write. A killed run then has exactly two states: finished, or absent.
Pin the inputs
Record a digest for every approved input. After a crash, "is this still trustworthy" becomes one hash and one comparison, not a judgment call.
Predict first
Write down what the run should produce before starting it. Relaunching is then a repeat, not a redesign.Cost after the panic: about 20 minutes.
06 WHERE THE RUN LIVES
The temporary folder is a delete the system may take
Artifacts in a persistent research directory survived the reboot untouched. The one casualty was the launch script and its log, which had been parked in the temporary folder. A reboot clears it, and nothing asks first.
A long run also has to outlive the thing that started it. Terminal windows close, and agent harnesses commonly reap a background job around the ten-minute mark.
cd ~/research/run-2026-08-15 # persistent, not temporary nohup ./run.sh > run.log 2>&1 & # survives the terminal disown # survives the shell exiting # then poll from anywhere — never block a session on it tail -n 20 run.log
07 THE RULE
Inference gets the machine to itself
One sentence, recorded after the panic: model inference runs alone, and test suites and profiling wait for it to finish. Everyone applies this to production hardware and quietly suspends it for a laptop, because a laptop is where you do everything at once.
Deferral has a second edge. A profiling run found a real inefficiency mid-flight — a per-batch step revalidating the whole manifest every call, measured at 0.55 s per batch at 720 candidates. The fix still waits, so that no run straddles a code change and results stay comparable.
08 USE IT
Set this up before the next long run, not after
1 · Schedule
Decide which job owns the machine. Start nothing heavy beside it. Treat a local model run as an exclusive lock on the hardware.
2 · Place
Put the run directory, its launch script, and its log somewhere the operating system will not clear. Detach the process so it outlives its terminal.
3 · Decode
If it panics anyway, read the exit reason against the vendor's header. Label the mechanism you read and the cause you inferred differently.