v0.4.0
sitter v0.4.0 — --heartbeat-file: liveness that does not depend on stdout
Workers that are silent by design (a remote agent turn over ssh, a CLI that prints only at the end) used to be killed by the log-mtime stall detector while healthy (#10, two incidents). This release adds an opt-in, worker-agnostic liveness input.
New
sitter run --heartbeat-file <path>— the stall clock now uses the freshest of the log mtime and the heartbeat file mtime. sitter never executes anything to produce the heartbeat; the wrapper that owns worker knowledgetouches the file while its own cheap check says the worker is alive. ADR-0001 (no--probe) stays in force. Design record:docs/adr/0003-heartbeat-file.md.examples/heartbeat-wrapper.sh— template: exec's the worker, touches only when the worker is alive and a bounded vouch passes, exits with the worker.- README (en/ja/zh/th) "Know what counts as frozen" now has a three-way guide: raise
--stall-after/--stall-after 0 --timeout/--heartbeat-file.
Guarantees
- Flag unset: behavior byte-identical to v0.3.x (ledger schema and
reasonvocabulary unchanged). - Fail-closed: a missing, non-regular, symlinked or unstattable heartbeat contributes nothing (the log stays the stall clock); creation or per-attempt touch failure aborts the attempt.
- Refused at startup (exit 2): empty path, symlink/non-regular path, collision with
--ledger/ its lock /--kill-file/--log,--stall-after 0;ask/watchreject the flag. SITTER_HEARTBEAT_FILEis exported to the wrapped child only — never read as configuration, never passed to--on-fail.
Review
Design: 3 blind seats (GLM 5.3 / Kimi K3 / Grok 4.6), amendments A1–A10. Implementation: 3 seats r1 + delta D1–D9, cumulative GO. Suite 174 PASS / 0 FAIL on Linux and macOS. PR #59, Issue #46.