Skip to content

Releases: caty-ai/sitter

v0.5.5: dedicated ask ledger + run-ledger rotation contract (docs); --production-shape bench (#74)

Choose a tag to compare

@github-actions github-actions released this 09 Sep 05:22
1c8bfcc

v0.5.5 — dedicated ask ledger + run-ledger rotation contract (docs); --production-shape bench

No behaviour change in sitter. This release ships a norm for operators and the evidence behind it.

Docs (the contract)

  • Run the expect family on its own ledger. expect / ack / ask / watch / sweep should use a ledger that no sitter run and no foreign writer appends to. Sharing stays supported, but every sweep or watch pass stages and replays the whole file, so its cost grows with the run supervisor's history rather than with live asks. (docs/reference.mdLedger placement and rotation; docs/reference.ja.md → 台帳の配置とローテーション.)
  • Rotate run ledgers by rename, under the ledger lock, only when nothing in the expect family reads them. Two pre-rotation checks (no reference to the path from any expect-family caller; the "expect_id" row count equals the record kept in <ledger>.expect-count, never re-derived from the file). A missing record on a file that carries expect rows is an unknown state and blocks both rotation and rescue. Never rotate a ledger the family reads — the next pass stages a fresh file and every active ask disappears silently.
  • docs/specs/ledger-separation.md (new): the measured production shape (14,170 rows, 6 of them expect-family), why compaction was rejected at design review, contracts A1–A5 / B1–B5, and three runbooks exercised on macOS during review — one-time placement of live asks (drain every caller, copy and prove the copy byte-for-byte under the lock, repoint, re-prove), rescue of stranded asks (snapshot count, event_id dedupe, id-collision check and append in one lock hold, fail closed), and rotation with the count check and the rename in one critical section.

Bench

  • tests/fixtures/gen-ledger.sh --production-shape <lines> <out>: production-shaped ledger (run-family and foreign rows ≈ 5:3, the same six expect rows last). The two-argument mode is byte-identical to v0.5.4.
  • tests/bench-ledger.sh --production-shape [--repeat N] [--lines N]: shared vs dedicated, median of N.
ledger rows sweep --once watch --once
shared, production shape 13,884 2.627 s 1.412 s
dedicated ask ledger 6 1.212 s 0.076 s

(macOS arm64, median of 3; the discarded rows cost ≈ 1.4 s per pass for either verb.)

Review

PR #83 — 12 rounds with Opus 5 / Qwen 3.8 Max / Gemini 3.8 Flash; every blocking finding was reproduced by the seat and adopted the same round; 3/3 GO at 6bd477a. Non-blocking leftovers are tracked in #84. Operator wiring (the maintainer's sitter-ask wrappers, launchd jobs and dashboard) is tracked outside this repository via #74.

v0.5.4

Choose a tag to compare

@github-actions github-actions released this 08 Sep 15:42
16c1c5f

v0.5.4 — sweep verifies the staged ledger prefix (#76)

sweep --once stages a private copy of the ledger and re-checks only the bytes appended after it. Since v0.5.0 an in-place replacement of the ledger that was equal-or-longer than the stage but no longer contained the staged history (hand compaction, restoring a backup over it, shrink-then-grow) could produce a spurious nudge and --on-fail hook call.

  • sweep now records the SHA-256 of its private stage and, for each due candidate, trusts the staged state only while the live ledger is at least stage_bytes long and its first stage_bytes bytes still hash to the same value; otherwise it falls back to a full replay for that candidate. Hash or I/O failures end the pass with exit 1 instead of trusting the offset.
  • Regression test ledger_sweep_staged_prefix_replacement (equal-length and longer replacements).
  • Docs: the live ledger is append-only. Supported writers only append; replacing a live ledger in place is out of contract.

Cost: one hash of the stage per pass plus one prefix hash per due candidate (8 MB ≈ 0.03 s).

PR: #82 · Issue: #76

v0.5.3: LC_ALL=C scoped to sitter's string handling; hooks and the wrapped command inherit the operator locale (#75)

Choose a tag to compare

@github-actions github-actions released this 08 Sep 08:20
2f9c9fc

v0.5.3 — LC_ALL=C no longer leaks into hooks and the wrapped command (#75)

Seven functions in sitter assigned LC_ALL=C as a bare global. When the operator had LC_ALL exported (containers, CI), those assignments overwrote the exported value mid-run, so --on-fail hooks observed LC_ALL=C instead of the operator's locale.

Fixed

  • json_quote, sanitize_expect_value, truncate_utf8, emit_expect_event, build_ask_event_record: local LC_ALL=C.
  • invoke_hook, emit_event: assignment removed; the 512-byte detail_truncated count moves to a byte_length helper so no LC_ALL=C frame is alive when the hook is spawned (bash locals inherit the export attribute of an exported global).
  • --on-fail hooks and the wrapped command now inherit the operator's LC_ALL/LANG unchanged. Sitter's internal string-handling helpers and the explicitly scoped replay pipelines still run under LC_ALL=C.

Tests

  • hook_sees_operator_locale (run + expect/sweep hook paths, unset control, 513-byte multibyte detail_truncated).
  • ledger_sweep_exported_locale_equivalence (sweep rows bytewise identical under LANG-only / LC_ALL=C.UTF-8 / en_US.UTF-8 / C).

Docs: docs/reference.md, docs/reference.ja.md.

PR: #81 · Issue: #75 · Previous release: v0.5.2

v0.5.2: truncate_utf8 non-iconv fallback now drops invalid UTF-8 anywhere in the text (#77)

Choose a tag to compare

@github-actions github-actions released this 08 Sep 01:49
7c2140d

v0.5.2: truncate_utf8 non-iconv fallback now drops invalid UTF-8 anywhere in the text (#77)

Bug fix. When iconv is unavailable, truncate_utf8 previously trimmed only an
incomplete trailing sequence, so a stray invalid byte inside --text survived
into an emitted ledger row. The fallback is now a forward byte walk that keeps
the longest RFC 3629 well-formed prefix (the same result the iconv branch
computes). Test-only seam SITTER_TEST_NO_ICONV=1; two new tests; docs state
the guarantee per validator (macOS libiconv is lenient on forms above
U+10FFFF and obsolete 5/6-byte sequences).

Evidence: PR #79 (L1-7 record; CI on
8e8e66b green on ubuntu and macOS; seats Opus 5 / Kimi K3 / Qwen 3.8 Max r3 GO x3).
Follow-up: #80

v0.5.1

Choose a tag to compare

@github-actions github-actions released this 07 Sep 17:32
2b94141

v0.5.1 — string fast paths (json_quote / sanitize_expect_value) and operator notes on sweep hook serialisation and child-log rotation

Perf batch #72 (S). Clean values (no '"', '', 0x01-0x1f) skip the per-byte
loop in json_quote and sanitize_expect_value; output is byte-identical to
v0.5.0 (differential test against the frozen tests/fixtures/sitter.baseline).
64 KiB --text: 4.69 s -> 0.075 s. Four remaining perf findings are closed as
measured won't-fix on #72; two of them add operator notes to docs/reference*.md.

Evidence: PR #78 completion record (L1-7), CI on bbb0766 green on ubuntu and
macOS — #78
Issue: #72

v0.5.0 — single-pass sweep, fork-free replay

Choose a tag to compare

@github-actions github-actions released this 07 Sep 15:02
e4f3e5c

Performance release for the expect/sweep/watch subsystem (#71, PR #73).

What changed

  • expect_replay_line parses ledger lines with bash regex instead of 8–11 printf | sed pipelines per line (zero subprocesses per line).
  • sweep --once stages the ledger once, records the staged byte offset under the ledger lock, and per SLA-due candidate scans only the live tail appended since staging. A possible mention of the key, a shorter live file, an unterminated staged row, or any read error falls back to the original full replay.
  • Replay is now bytewise and identical on every platform; previously a ledger line containing invalid UTF-8 was poisoned on macOS (BSD sed) and passed or skipped on Linux depending on locale state. Emitted text is still truncated to valid UTF-8 (when iconv is available — see follow-up).
  • sweep --once is fail-closed: a snapshot copy or live-tail read failure exits nonzero instead of reporting success; temp files are cleaned on every exit path.
  • Ledger format, emitted events, hook and ack rules: unchanged.

Measured (macOS arm64, tests/bench-ledger.sh, single observations, before = v0.4.0)

lines sweep before → after watch before → after
1,000 32.8 s → 3.4 s 14.2 s → 0.3 s
10,000 285.7 s → 21.7 s 134.2 s → 2.5 s
50,000 1215 s → 96.5 s 551 s → 12.3 s

Verification: frozen copy of the v0.4.0 script (tests/fixtures/sitter.baseline) as an oracle; seven new equivalence/race/cleanup cases; 181/181 on macOS (bash 5 and 3.2) and ubuntu. Windows/MSYS unverified on this lane.

Review: writer Codex (GPT-6 Astra); three independent read-only seats (Opus 5, Kimi K3, Gemini 3.8 Flash) over three rounds; blocking findings 0 at merge. Full record in PR #73.

Follow-ups: ledger compaction design; localise the remaining LC_ALL=C assignments + exported-locale test; equal-or-longer external ledger replacement; truncate_utf8 non-iconv fallback.

v0.4.0

Choose a tag to compare

@github-actions github-actions released this 04 Sep 05:02
e11ac73

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 knowledge touches 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 reason vocabulary 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 / watch reject the flag.
  • SITTER_HEARTBEAT_FILE is 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.

repo-state caller v0.12.1: app-authenticated stamp pushes (family-os#140)

Choose a tag to compare

@github-actions github-actions released this 26 Aug 18:56

repo-state caller v0.12.1: app-authenticated stamp pushes (family-os#140)

v0.3.3 — WSL2: install, scheduling, and notification docs stop assuming macOS

Choose a tag to compare

@shojikumaru shojikumaru released this 26 Aug 18:05
85feb6f

Docs-only release (Issue #52, PR #53; parent: family-os#139).

  • Install block (README ×4 languages): the PATH-persist step now ships both rc-file variants inline — ~/.zshrc (macOS default) and ~/.bashrc (Linux/WSL2 default) — so a WSL2 copy-paste reader no longer silently ends up without sitter on PATH.
  • Scheduling: new systemd user units examples/sitter-sweep.service + examples/sitter-sweep.timer next to the launchd plist, with install steps and precise WSL2 caveats (systemd default on current Ubuntu, sudo + PowerShell enablement for other distros, cron autostart rule, loginctl enable-linger for unattended sweeps).
  • Notifications: README example now offers notify-send (Linux/WSL2) and a Windows-toast pointer alongside macOS notification centre.

No behavior change: make test 150 PASS / 0 FAIL. Review: 3-seat heterogeneous panel (GLM 5.3 / Kimi K3 / Grok 4.6) 3/3 GO + delta confirmation GO. Previous release: v0.3.2.

repo-state caller + generation stamp (family-os#127 rollout; closes #50)

Choose a tag to compare

@github-actions github-actions released this 25 Aug 20:09

repo-state caller + generation stamp (family-os#127 rollout; closes #50)