Created and documented by Nino Chavez.

Applied A10 · 8 chaptersScroll to read · use ← → to step between chaptersSkip to the record

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.

29.1 GBlargest resident process
36 GBmemory installed
3heavy jobs stacked

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.

decode the exit reason
/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.

detach the run, then watch it
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.

one heavy job at a time atomic results, no partial files observed and inferred are labelled apart
Colophon. An Applied technique distilled from a real kernel panic on 2026-08-15, during a local classification run for a meeting-notes app. Machine: a 36 GB Apple silicon laptop on macOS 26.5.2. The exit reason namespace constants are read from Apple's published kernel source, bsd/sys/reason.h, on the current tree rather than the tag matching this build; the signal number is from the command-line-tools SDK. The note originally written about this crash named jetsam, and was corrected against those two files.

The reusable technique

One Heavy Job at a Time

Running a model locally turns a laptop into a machine that has to be scheduled. A kernel panic during an inference run, how to decode the panic's exit reason from the vendor's own header instead of guessing at it, and the habits that made recovery a twenty-minute job instead of a lost morning.

Collection
Applied
Record
A10
Related sessions
0

Working principles

What to carry forward

  1. Give a local model run the machine to itself.
  2. Look the panic's namespace and subcode up in the vendor's header before translating them.
  3. Write results atomically, into a directory the system is not allowed to wipe.

Explicit relationships