Resilience

A closed lid is not a crash

An unattended run has to survive the ordinary interruptions of an unattended machine — sleep, a dropped network, a killed process — without losing work or wedging. Zecor treats the git branch and the on-disk queue as the source of truth, never the process's memory, so any of those can happen mid-task and the next run picks up exactly where it left off.

State lives on disk, not in memory

Everything a run knows lives in one of three stores, and none of them can be torn mid-write:

StateLives asWhy an interruption can't corrupt it
Task progress a git branch open_lane checks out a worktree per task and every attempt commits or resets against it — an interrupted run leaves real, inspectable git history, not a half-finished diff in a dead process.
Task queue card files written with a tmp-file-plus-os.replace swap — a reader sees the old card or the new one, never a half-written one.
Quota ledger SQLite, WAL mode crash-safe by construction.

Restart after any interruption and the state that matters was never only in RAM to begin with.

Sleep, lid-close, crash

Every in-flight task holds a lease with an expiry, and a lease past its expiry is normally treated as abandoned and picked up by the next run. What actually happens turns on one question: is the holder still alive?

lease past its expiry
Holder alive — the machine slept ten minutes grace A laptop that suspends mid-task freezes its process without killing it, so on wake the holder is still there — just late. A live holder past expiry gets ten minutes before anything reaps it; a lid closed for a shorter sleep costs nothing.
no live holder
Holder dead — crash or kill reclaimed immediately The queue is idempotent by design: a card that was mid-run when its holder died goes back to ready, not to some special recovery state, so the same dispatch path that picks up a fresh task also picks up an interrupted one.
→ next pass resumes · a worktree left behind by a killed run self-heals rather than requiring a person to notice and clean it up

The remote link

Watching or steering a run from a phone means the connection itself has to survive roaming between towers, backgrounding the app, and walking through a dead zone — the machine running Zecor is almost never the problem, the link to it is. zecor remote setup wires three pieces, each with one job:

Tailscale the path

Gives the phone a stable address to the machine over an encrypted WireGuard link that punches out through carrier NAT on its own — no port forwarding, nothing to configure on a router.

tmux the session

Keeps the console session running on the machine independent of whether anything is attached to it.

mosh the connection

Replaces the fragile SSH-style connection with one that tolerates IP changes, sleep, and dead zones — close the phone, walk out of signal, reopen it later, and the session is still there, not disconnected.

None of that makes the run itself more durable — the state-on-disk model above already does that. It means losing the view into a run costs nothing either.

What this doesn't cover yet

Honestly: two pieces of the resilience story are still hardening rather than finished.

Neither is silent — both fail loud and recoverable, never silently wrong.