Changelog

edge

13 August 2026

Rolling build of main at 8b3480b47440, 2026-11-12. Not a release; install with HAND_INSTALL_VERSION=edge.

v0.14.0

11 November 2026

Hand v0.14.0

Changes since v0.13.0 (tagged 2026-11-02). Dependency bumps, test-only and internal refactors and the version bump are left out of the sections (listed at the end). Numbers in brackets are merged pull requests.

Breaking changes and migration

Read this before hand update. Four things break: routing profiles, the Tailscale phone path, the database schema, and (from this release on) the fleet's version pin.

Routing profiles are gone (#1207, #1202).

  • routing.json no longer has profiles. A file that still holds the key does not parse: hand doctor fails its routing.json row with "profiles" was removed; delete the key and start workers with --harness, --model and --effort, and the watcher reads nothing from the file until the key is deleted. Until then the watcher falls back to the desktop notifier (the notify command does not run), and autoresume, inbox pruning, worktree retention and stall delays use their defaults or stay off.
  • --profile is gone. hand attempt start, hand supervisor start and hand supervisor switch take --harness, --model and --effort; hand attempt start without --harness is a usage error. Effort levels are low, medium, high, xhigh, max.
  • hand route list is gone: hand models lists models, and the track record is hand attempt track.
  • approve: ask, access: readonly, approve_timeout, hand project grants and the attempt.denied wake are removed (#1202).
  • The Board's profile picker is replaced by a start form per harness. A harness that is not on the Board's PATH disables its button and says why.
  • Migration, in every fleet, in the same sitting: (1) before hand update, carry each profile you want to keep into memory/operator.md as standing rules in flag form, for example "workers run --harness claude --model opus --effort high"; (2) run hand update, then delete only the profiles key from each fleet's routing.json (notify and other keys stay; hand init now writes {}); (3) run hand doctor and rewrite profile mentions in the fleet's memory. docs/update.md has the same steps.

Workers start without MCP servers (#1101, #1196). A Claude worker no longer loads the MCP servers of your Claude config or of a repository's .mcp.json; it starts with --strict-mcp-config and none. Put the servers you need in a file inside the fleet home and start the worker with hand attempt start --mcp FILE (claude only; a path inside the fleet home; hand attempt show prints mcp:; --continue does not inherit it). Measured in #1101 with two idle Playwright MCP servers in the user config: about 540 MB in 3 processes before, about 253 MB in 1 process after.

The Tailscale phone path is removed (#1200). Hand no longer runs tailscale or looks for tailscale serve. The Phone page's tailnet card, the hand doctor phone row and the ts.net address in alerts and hand open --print are gone. The Board still refuses Funnel traffic and drops Tailscale-* headers on peer connections. A phone paired over Tailscale can no longer sign in: revoke it on the Phone page and pair the Hand app over iroh (see Phone and the Hand app). HAND_NOTIFY_URL is now the loopback page only; the new HAND_NOTIFY_APP_URL (handboard://open/<fleet id>/...) opens the item in the Hand app, and hand open --print also prints app. To click through to the app, set the notify command's click target to ${HAND_NOTIFY_APP_URL:-$HAND_NOTIFY_URL}.

Schema 16 to 22 (#1102, #1119, #1143, #1195, #1211, #1203). v0.13.0 wrote schema 16. Each step: 17 adds the kept column for kept worktrees (#1102), 18 an index on events (#1119), 19 a home column on the fleet row, where a move records the fleet's home (#1143), 20 task.parent_id for nested tasks (#1195), 21 an index on attempts by status (#1211), 22 the alert feed table (#1203). hand update backs each fleet's database up and migrates it. An older hand refuses a migrated database (newer than this hand); going back needs a restored backup (docs/update.md, "Restore a backup"). This build also reads hand.db only from schema 16: an older database is refused untouched, with hand 0.13.0 is the last release that migrates it. From a release before 0.13.0, install v0.13.0 first (HAND_INSTALL_VERSION=v0.13.0), run hand orient in each fleet, then update (#1126).

A fleet is pinned to the hand that last opened it (#1226). hand.version in the fleet folder records the version, commit and schema of the hand that last opened or migrated the fleet. From this release, a hand refuses a fleet pinned to a newer schema, or to a newer version when both parse, before it opens hand.db: every fleet command, hand init, the Board (the fleet shows as refused) and hand fleet adopt/move when they write. hand fleet unlock stays open as the escape hatch. hand update and hand update --check read every fleet's pin before any backup or swap and refuse a target older than one, naming every such fleet; a build that is already current is never refused. hand doctor has a hand.version row. A fleet with no pin is not refused and gets one at its next open.

  • Rollback steps: stop the supervisor and the Board; put the older binary back from ~/.secondhand/backups/hand.<stamp>; delete hand.version in the fleet folder; and, only if the older hand refuses the schema, restore a hand.db backup from the fleet's backups/ (docs/update.md step by step). There is no --force. The older hand writes a new pin at its next open.
  • From 0.13.0, hand update with both a watcher and the Board running: the new watcher migrates hand.db first, and 0.13.0 then refuses to open it to start the Board. The update still finishes and exits 1 with could not start board; run hand open to start the Board on the new binary.

Smaller breaks.

  • -h and --help on a command with flags print usage: hand X [flags] and the flag list to stdout and exit 0; before, they exited 2 (#1120).
  • summary in hand report list is clipped to the title budget; report show prints the full body (#1122).
  • Hand 0.7 data is no longer detected or read, and the migrate skill is removed. hand init in a folder that holds 0.7 data and no hand.db refuses with one line and writes nothing (#1125).
  • A hand built from source needs Go 1.27.3 or newer (#1166).
  • The machine registry is now ~/.secondhand/index/<id>, a plain file holding the fleet home; the old fleets hard-link directory is migrated on first read (#1192).
  • A fleet keeps its pinned Luvus copy, its backups and its model lists inside the fleet folder (luvus/<os>-<arch>/, backups/, cache/models/). The first fleet command, hand init and hand update copy the machine-side ones in and print a migrated list. Each fleet now pins its own Luvus copy; the Board's document viewer refuses backups/ and cache/ (#1197).
  • hand attempt start hands each attempt its own scratch folder in the fleet home, scratch/tN-aM, with TMPDIR and the like pointing at it. It is outside reports/ and shots/ (#1142).

Highlights

  • Fleets move. A fleet is a folder you can move, copy to another disk or machine, adopt and import. hand fleet move (#1143), hand fleet adopt (#1209), hand fleet import (#1144), a fleet.home record and per-machine bookmarks (#1192), a fleet's files kept inside it (#1197), a marker for which host has the fleet open (#1221) and the version pin (#1226).
  • Nested tasks. hand task add --parent tN, hand task parent, a task tree in hand task list, and the same on the Board and the API (#1195, #1216).
  • A native window. hand-desktop, a window for the Board's read model and actions on Linux, shipped with the release and fetched by hand update. It sits on a new JSON API v1 (#1182, #1183 and following).
  • Phone and app over iroh. The hand-iroh sidecar ships with the release; the Board starts it, and the Hand app pairs from the Phone page and reads an alert feed (#1132, #1134, #1169, #1203). Tailscale is gone.
  • Routing without profiles. Flags replace profiles (see above); omp joins the harnesses (#1138).
  • A long supervisor session rolls over. A claude or omp supervisor whose context passes supervisor.rollover_tokens (default 300000, 0 off, in routing.json) is replaced by a fresh session on the same harness, model and effort after it writes memory/handoff.md. It happens only when the supervisor is quiet, and never within an hour of the last rollover (#1225).

Fleets, moving and portability

  • hand fleet move [--dry-run|--yes] PATH rewrites every recorded home path in one transaction, checks foreign_key_check and integrity_check, renames the folder and updates the registry. It refuses a live supervisor, attempt, watcher or Board, a destination that is not empty, another filesystem and other unsafe cases. Worktrees keep working after a move (#1143, #1159). It renames the fleet when the recorded name still equals the old folder name (#1164), and a supervisor session from before the move starts fresh on resume (#1161).
  • hand fleet adopt [--from OLD]... [--check] and an automatic version of it: the first store-opening command in a fleet copied or moved to a new path rewrites the old homes in hand.db, appends fleet.adopted and repoints fleet.home and the bookmark. It refuses while two homes hold the same fleet, or while the watcher, supervisor or Board runs. docs/fleets.md has "A fleet on a removable disk" (#1209).
  • hand fleet import SRC INTO DST [--dry-run] gives one fleet the other's task list, memory and history as an archive, without rewriting references or home paths (#1144).
  • fleet.home records each fleet's homes; no os.Link remains on a fleet path, so a fleet works on exFAT; hand doctor gains a modes row for filesystems that do not enforce file modes (#1192).
  • The watcher keeps fleet.host (host, boot id, pid, time) while it runs. A command refuses a fresh marker from another host and takes over a stale one (more than 90 s) or one from an earlier boot of this host with the watcher lock free, recording fleet.took_over and attempt.interrupted. watch.pid and board.pid record start@boot, so hand watch stop, hand board stop and hand update never signal a pid from another boot or host. New: hand fleet unlock, and the doctor rows open on another host and unclean close (#1221).
  • hand update removes systemd watcher units left for a moved or deleted fleet, and hand doctor reports a stale one (#1158). A vanished fleet home is reported as moved (#1201).
  • Worktrees: the watcher removes a finished attempt's worktree retention.worktrees days (default 7) after it ended, only when no terminal is open in it, no process of yours runs in it (Linux), its tree is clean, every commit is on a remote-tracking branch and no ignored file looks like config or secrets; otherwise it keeps it and the Board shows Worktree kept: REASON. hand orient and the Board warn when reports/ and shots/ pass retention.warn_size (20 GB) or hold files older than retention.warn_days (30 days), and hand gc --older-than Nd [--yes] [SCOPE...] lists, then deletes, by task folder. The secondhand-cleanup skill is installed by hand init (#1102).

Tasks, workers and the supervisor

  • Nested tasks: hand task add --parent tN, hand task parent tN (--parent tM | --root), hand task list as a tree (--flat for the old list), parent and children in hand task show; hand task done and abandon on a parent with open children print a warning and still finish it; hand orient orders active and inbox depth first (#1195). hand fleet import carries parent_id (#1195).
  • omp (oh-my-pi) is a worker and supervisor harness: hand models --refresh omp, start with --model provider/id and --effort as the thinking level, resume with --resume ID (#1138). Hand finds a harness installed through mise (#1147), and silences omp's terminal notifications inside a fleet by starting the fleet's Luvus server with PI_NOTIFICATIONS=0 (#1191).
  • hand orient --since CURSOR prints only what changed after an event cursor, under 3000 bytes. The full orient stays the default; the shipped supervisor skill uses the full form at the start of a session and after a resume, and the short one on each wake (#1220).
  • hand project note NAME TEXT appends a dated entry to notes/NAME.md, and hand project notes NAME prints it (#1193).
  • hand skills list | add | update | remove [--user] manages fleet and worker skills, with a skills row in hand doctor (#1194).
  • The shipped supervisor text says the supervisor orchestrates and does not work by hand: code, tests, docs, PRs, reviews and read-only investigations are worker attempts (#1152, #1176).
  • Claude's session transcript path is remembered per session instead of globbed per read: 3.86 ms to 12 µs for a found session on a synthetic 400-folder tree (#1213).
  • Fixes: no attempt.blocked until a second observation holds the status (#1145), and none from an omp status box border (#1171); no quiet wake before an attempt has worked, with a 30 s window (#1168); supervisor closes record who closed them, and a long-lived process checks the Board's generation before it closes or signals a supervisor pane (#1154); hand open reports a Board that exits at once instead of waiting 10 s (#1116); an ended opencode session is exported once (#1210).

Board and API

  • GET /<fleet id>/supervisor shows the supervisor's screen as a live page with a key toolbar and an Ask card for numbered or list options (#1177).
  • JSON API v1 under each fleet's /api/v1: status, timeline, tasks, task, attempt, decision, report; then answers to decisions, report acks, messages and supervisor controls (#1182, #1186, #1187, #1188), the blocked supervisor's question and options (#1219), and an alert feed (#1203).
  • The Board and the API show nested tasks: a child follows its parent, with N sub-tasks and under tM links (#1216).
  • A ?token=...&keep=1 login on a loopback Board keeps the laptop login for 400 days, so a bookmark opens the Board; any other login stays a session cookie (#1128).
  • A relative path in inline code links to the Board's document viewer when it exists in the fleet folder (#1106).
  • A Linux alert's Open action starts the Board page when the notifier supports actions, and validates board.addr first (#1137, #1141).
  • Speed: reads answer 304 when the Board version is unchanged (#1222); lists read attempts without their brief (#1217); the task panel no longer exports the transcript (#1153); attempts are indexed by status (#1211); events are indexed by kind and task (#1119).
  • A peer request whose client half-closes right after the headers is answered instead of getting 403 (#1215).
  • Internal: spacing, size and paint on tokens (#1096), one rule per selector (#1133), one thread head (#1129), one tone attribute (#1156), typed status, timeline, tasks and detail views (#1179, #1181), shared forms (#1184).

Hand desktop window

  • hand-desktop is a window for a running Board, on Linux amd64 and arm64: status, Needs, conversation, tasks and the task, attempt, decision and report screens; answers decisions, marks reports read, sends messages (Ctrl+Enter) and has the supervisor controls (#1183, #1186, #1187, #1188, #1223). It refreshes with the API cursor, every 2 s focused and every 15 s not (#1190, #1206). Text renders as markdown (#1205), delivered links and files open (#1214), and every screen has an Open in browser button that runs hand open (#1212). A blocked supervisor's question shows as buttons (#1219).
  • The release carries hand-desktop-linux-amd64.tar.gz and hand-desktop-linux-arm64.tar.gz, each with a .sha256. hand update fetches it only where it can run, checks it against hand version, and installs a launcher entry and icon (#1189, #1204). hand doctor has a desktop row. Not verified: the launcher entry's StartupWMClass on a live window (#1204).

Phone and the Hand app

  • hand-iroh, a sidecar, ships as a release asset for Linux, macOS and Windows (each with a .sha256). hand board --iroh runs it as the Board's child and shows its state on the Phone page, in hand doctor and in board.iroh. install.sh, install.ps1 and hand update fetch it, checked before anything changes (#1132, #1134). The Board's peer listener counts every request on it as remote and accepts the sidecar's preface (#1131).
  • Pair the Hand app from the Phone page: a one-time code as a handboard://c#... link and QR. Revoke closes the device's live peer connections (#1169). Alerts reach the app through a feed of the last 7 days (#1203), and the open link handboard://open/<fleet id>/<page>[#rN] is specified in docs/companion.md (#1200).
  • Docs: the Android companion contract (#1135), the Board as an app window (#1136), docs/phone.md rewritten around iroh (#1200).

Install and platforms

  • README installation section reshaped (#1149). Go 1.27.3 for source builds (#1166).
  • hand update installs hand-iroh and hand-desktop with hand; an older release's update (0.13.0) installs hand without the sidecar, and the new hand's next update places it (#1134).

CI, tests and project

  • The race detector runs on Linux only; the live Luvus step stays on all three systems (#1118). The release test job has a 30 minute timeout (#1103). The Claude Review action is removed (#1151).
  • Tests made deterministic or cheaper: #1123, #1127, #1130, #1175, #1178, #1180, #1198, #1218, #1224.
  • Left out of the sections above: #1124 (internal: supervisor force recorded under detached, one pin-match table), #1173 (an approve deadline fix whose code #1202 removed) and #1121 (model refresh scope, replaced by #1207).

Known limits

  • hand fleet adopt refuses while the watcher, the supervisor or a Board that serves the fleet runs, and live attempts are not rewritten: their pids, panes and machine paths stay as they were (#1209).
  • Desktop: only Linux runs the window. macOS and Windows build the package.
  • Linux alert actions need notify-send with --action and --wait; otherwise the old plain notification is sent (#1137).
  • hand update from 0.13.0 with a watcher and the Board running exits 1 once with could not start board (see above).

Dependency and version bumps

  • Version bump to 0.14.0 (#1227).
  • golang.org/x/sys 0.49.0 to 0.50.0 (#1208).
  • modernc.org/sqlite 1.61.0 to 1.61.1 (#1117).
  • anthropics/claude-code-action 1.0.263 to 1.0.266 (#1104).
  • Go 1.26.5 to 1.27.3 in go.mod (#1166).
  • Luvus is still 0.14.3. hand-iroh is 0.1.0 on iroh 1.4.1 (#1132).

Pull requests in these notes

#1096, #1101, #1102, #1103, #1104, #1106, #1116, #1117, #1118, #1119, #1120, #1121, #1122, #1123, #1124, #1125, #1126, #1127, #1128, #1129, #1130, #1131, #1132, #1133, #1134, #1135, #1136, #1137, #1138, #1141, #1142, #1143, #1144, #1145, #1147, #1149, #1151, #1152, #1153, #1154, #1156, #1158, #1159, #1161, #1164, #1166, #1168, #1169, #1171, #1173, #1175, #1176, #1177, #1178, #1179, #1180, #1181, #1182, #1183, #1184, #1186, #1187, #1188, #1189, #1190, #1191, #1192, #1193, #1194, #1195, #1196, #1197, #1198, #1200, #1201, #1202, #1203, #1204, #1205, #1206, #1207, #1208, #1209, #1210, #1211, #1212, #1213, #1214, #1215, #1216, #1217, #1218, #1219, #1220, #1221, #1222, #1223, #1224, #1225, #1226, #1227.

v0.13.0

2 November 2026

Hand v0.13.0

Changes since v0.12.0 (tagged 2026-10-24). Dependency bumps and the version bump are left out (listed at the end). Numbers in brackets are merged pull requests.

Highlights

Hand can now start workers on the GitHub Copilot CLI, and opencode becomes a full worker and supervisor harness: pick its model and variant at launch, see what it runs, and switch it between turns with hand attempt switch. Hand reads back the model every harness actually serves, and warns when it differs from the one you asked for.

Two new settings in routing.json let you control what a Claude worker may do. "approve": "ask" makes Claude Code ask before each command, and the Board shows the command with Approve, Approve always and Deny buttons. "access": "readonly" starts a Claude worker that can read but not write, for review and research tasks.

Wakes got quieter: idle turns and work the supervisor has already handled no longer wake it, and a task can wait on an outside party without raising a stall flag.

Workers and models

  • GitHub Copilot is a worker harness: hand attempt start --harness copilot, with hand models copilot, a launch note when Copilot fell back to Auto or is signed out, its transcript on the Board's attempt page, and its session limit shown as a usage limit. Hand also finds the Copilot CLI that gh copilot downloads (#1028, #1029, #1030, #1032, #1034, #1035). Copilot runs workers only; hand supervisor start refuses it.
  • opencode launches on a model and variant you choose (provider/id and the variant as the effort), with a session id Hand picks, so Hand can read it back (#1058, #1060). The model list keeps each model's variants and warns when a variant is none of them (#1091).
  • hand attempt switch aN --model provider/id [--effort VARIANT] switches an idle opencode worker's model without losing its session (#1090). hand supervisor switch and the Board's model menu do the same for an opencode supervisor (#1071).
  • Hand shows the model and effort that is really running, for opencode, Codex, Claude and Copilot, in hand orient, supervisor show, attempt show and the Board (#1039, #1084, #1089, #1051). An opencode worker or supervisor that runs a different model than asked for gets a model_note: Asked for X, running Y. line (#1092). A gateway shows only the alias you picked (#1081).
  • approve: ask for Claude profiles: workers start without --dangerously-skip-permissions. The Board's Needs item shows the exact command and offers Approve, Approve always for the project (only for a short list of commands whose prefix no flag can change) and Deny. hand project grants NAME lists and removes the saved grants. An unanswered prompt is denied after approve_timeout (default 10 minutes) (#1086).
  • access: readonly for Claude profiles: the worker gets only the Bash, Read, Grep and Glob tools in dontAsk mode, can file its report, and ignores the repository's own Claude settings and MCP config. hand route list has an access column. It is a permission mode, not a sandbox (#1094).
  • A Claude worker launches with a session id Hand chooses, so its transcript can be found (#1089).
  • hand attempt clean removes Claude Code's scratch folder for the worktree (--keep-scratch leaves it), and hand attempt gc [--apply] [--older-than DURATION] lists or removes folders whose worktree is gone (#1082).
  • hand attempt stop, settle and clean end processes a worker left running in its worktree on Linux (#1017).
  • The routing track's first_try counts only the first attempt on a task (#1026). Route-by-model guidance in the supervisor skill no longer counts waiting on builds or locks as a reason to pick a stronger model (#1025).
  • hand attempt start warns when 5 or more attempts are already live, and the docs give the memory cost of concurrent workers (#1016).

Wakes, tasks and the supervisor

  • hand wake --while tN --waits --after 3d --note REASON marks a task as waiting on an outside party for up to 30 days: no stall wake, no stalled count, no red item on the Board until it fires (#1006).
  • attempt.idle is no longer a wake kind, and a wake or hand wait leaves out what the supervisor has already handled. No turn signal is recorded for an attempt that has ended (#1077).
  • An opencode turn is held open while one of its subagents runs, so a subagent no longer shows as a finished turn (#1073). A launch no longer shows a false attempt.blocked (#1063).
  • A Codex worker's question is shown in its blocked event (#1087).
  • An API error on a worker's last turn clears from the Board once a later turn works (#1027).
  • hand orient prints the supervisor's model and effort (#1051).
  • Luvus refusing a key for a few milliseconds after a process scan is retried instead of failing a prompt, trust answer or wake (#1003).
  • Transcripts are read line by line instead of whole, so a large session file is no longer held in memory whole (#1015).
  • hand doctor warns instead of failing on a machine with no harness when nothing uses one (#1002).

Board

  • The supervisor's model menu is laid out in labelled blocks (#1040).
  • The log page's day dividers use local time (#1088).
  • Closing the viewer returns keyboard focus to the control that opened it, also when the page URL has a fragment (#1004).
  • A paired phone stays signed in when it opens a Board link from another app, such as a tapped alert (#996).

Install and platforms

  • install.sh ends a failed download, unpack or copy with one install.sh: ... line and exit 1. The documented one-liner is now s=$(curl -fsSL URL) && sh -c "$s", because curl ... | sh exits 0 when curl fails (#1005).
  • On Windows, a Codex installed with npm install -g starts: Hand uses the codex.exe that npm puts beside codex.cmd (#1022).
  • A plain Windows clone with Git's default line endings now builds and tests: .gitattributes keeps LF, and tests bind their sockets in a short folder (#998).

CI, tests and project

  • CI renders the Board's fixture scenes on Linux, macOS and Windows and asserts the layout; pull requests also get a before-and-after picture diff (#1085).
  • Tests: the race in TestNoRequestPathRunsAHarness is fixed (#1000), the transcript memory tests measure growth against a baseline (#1050), test-linux has a 20 minute timeout (#1062), a doctor test pins the missing-Copilot fix line (#1083), and the dogfood Windows guide decodes TOON paths (#995).
  • Docs: opencode route profiles (#1093), contributor sign-off in CONTRIBUTING.md (#999).
  • Left out: dependency bumps (#1007, #1008, #1009, #1010, #1011, #1021, #1041) and the sponsors link (#1079).

Upgrade notes

  • Schema is now 16 (v0.12.0 was 13): 14 adds the wait timer flag (#1006), 15 adds approve on attempts and the project grants table (#1086), 16 adds access on attempts (#1094). hand update backs each fleet's database up first and migrates it; an older binary refuses a migrated database. docs/update.md has the restore.
  • routing.json has new optional keys: approve and access on a profile, and approve_timeout at the top. copilot is a new harness name. v0.12.0 rejects unknown keys, so an older binary refuses a routing.json that uses any of them. Existing files keep working unchanged.
  • approve: ask is for claude only. access: readonly is for claude only and is refused on Windows. The other harnesses reject both with an invalid-value error.
  • The supervisor: line of hand orient now reads <ref> <harness> [model] [effort] <status>. A script that parses it should expect the extra words.
  • A supervisor or worker on opencode started by an older Hand keeps working. An older supervisor with no session id stored does not read its model, and hand supervisor resume refuses it; start a new one. An older worker's model is not read.
  • Luvus is still 0.14.3.
  • A paired phone's cookie is now SameSite=Lax; the laptop's Board cookie stays Strict.

Known limits

  • Copilot: only a session limit is detected as a usage limit. A spent plan allowance or a rate limit has no captured text, so a worker at one does not fall back to another profile. The effort levels per Copilot model are unverified, and the Copilot model line can be missed on a loaded machine.
  • Hand cannot answer a Codex question: Luvus refuses Shift+Left, so the question times out and the worker goes on with its default.
  • hand attempt switch works for opencode only, and only while the worker is idle or done. It restarts the pane, so background shells in the pane and unsent text end. A switch killed midway leaves the attempt running with no pane; the next command ends it exited.
  • approve: ask is friction, not a boundary. Approve always is offered only for a short list of commands. A Claude statusLine setting hides the idle screen from Hand, which then refuses hand attempt keys for that worker.
  • access: readonly does not stop a worker from leaking what it can read, and a Bash rule in your own user Claude settings still applies. The launcher-level enforcement that would also cover the other harnesses is not built.
  • Ending leftover processes on attempt stop works on Linux; macOS does nothing, and Windows already ends the process tree. The scratch folder cleanup is Unix only; the macOS location was not measured.
  • A gateway alias such as OpenRouter auto shows no routed model, so a track row for it mixes models.

Not verified

  • No run on a real Windows or macOS machine yet. CI covers both on GitHub's runners, but not a person's machine. docs/dogfood/ is how to do it. In particular, install.ps1, the Windows codex.exe lookup, the gh copilot lookup on Windows and macOS, and the scratch folder on macOS were only compiled or run on the runners.
  • An update from a real v0.12.0 install to this release. The end-to-end upgrade test starts from v0.11.0.
  • Copilot with a model other than auto (the login used had only auto), and a Copilot worker at its limit started by Hand.
  • A spent Copilot allowance or rate limit.
  • approve: ask and access: readonly were run against Claude Code 2.1.316 with a mock model. The CI tests pin 2.1.309. Other Claude Code versions may word the permission dialog differently, and Hand then shows the screen raw with no Approve.
  • The Board in Firefox and Safari, on a real iPhone, and with a screen reader.

Pull requests in these notes

#995, #996, #998, #999, #1000, #1002, #1003, #1004, #1005, #1006, #1015, #1016, #1017, #1022, #1025, #1026, #1027, #1028, #1029, #1030, #1032, #1034, #1035, #1039, #1040, #1050, #1051, #1058, #1060, #1062, #1063, #1071, #1073, #1077, #1081, #1082, #1083, #1084, #1085, #1087, #1088, #1089, #1090, #1091, #1092, #1093, #1086, #1094. Left out: #1007, #1008, #1009, #1010, #1011, #1021, #1041, #1079.

v0.12.0

24 October 2026

Hand v0.12.0

Changes since v0.11.0 (tagged 2026-10-14). Dependency bumps and the version bump are left out.

Highlights

The Board is much bigger. It opens a fleet's files, tasks, attempts, reports and decisions in a viewer dialog with a Back history and live updates, and you can answer a decision or mark a report read from inside it. A phone pairs with a one-time code or QR code, installs the Board as an app, reaches several fleets with one pairing, and finds its HTTPS address through tailscale serve. Hand detects the models each harness can use and offers them in the Start picker, warns about an unknown model instead of refusing it, and hand doctor says what is missing on a machine. Windows installs with irm | iex, and Codex now works there: Hand starts it in the right folder, scans the pane before sending keys, never launches a .cmd shim and answers its trust screens for its own worktree.

CI now runs end-to-end tests on Linux, macOS and Windows: installers, first run, the Board in a browser, an upgrade from v0.11.0 with its backup and restore, and the real Claude Code and Codex against a mock model server. The release workflow runs the install end-to-end tests first and builds only the commit they tested.

Board

  • feat(board): the Board layout, the conversation, Needs in bands, the rail and the menu sheet, decisions as a choice list (#904, #908, #909, #911, #913)
  • feat(board): bordered bubbles, copy buttons, a scroll to latest button, a chat draft that survives pages, tabs and restarts (#916, #919, #920)
  • feat(board): attach any file, attachment chips, drop anywhere on the chat (#924, #927)
  • feat(board): search every task from the Tasks page, a prettier filter bar (#907, #917)
  • feat(board): open files in place in a viewer dialog; read large text; JSON, CSV, diff, PDF, media, SVG and HTML previews; page folders and step through files; link file paths in replies (#935, #937, #940–#944)
  • feat(board): a Markdown file's source next to its rendered view; table pin and wide toggle (#949, #969)
  • feat(board): open tasks, attempts, reports and decisions in the viewer dialog, with history and live updates (#992)
  • feat(board): answer a decision and mark a report read from the dialog (#993)
  • feat(board): an attempt page with its brief, timeline and report; show a task's project when a fleet has several; pick a model from the detected lists (#979, #978, #983)
  • feat(board): keep the top bar in view; show a lost connection when the stream goes silent (#956, #950)

Phone

  • feat(board): pair a phone with a one-time code, show the pairing link as a QR code (#951, #952)
  • feat(cli): find the phone address through tailscale serve (#954)
  • feat(board): show a paired phone the fleets it can open, pair several fleets with one code, revoke a phone everywhere (#957, #959, #961)
  • feat(board): install the Board as an app and show an offline page (#968)
  • docs: reach the Board from a phone without Tailscale (#955)

Harnesses and models

  • feat(harness): detect the models each harness can use (#981); warn about an unknown model instead of refusing it (#977)
  • feat(cli): hand doctor, and a missing harness shown before Start (#933)
  • fix(harness): start Codex in the fleet home or worktree explicitly (#972); press Codex's trust screens for its own worktree (#976)
  • fix(harness): scan a pane before sending keys, and never launch a .cmd shim (#974)
  • fix(harness): prove a long prompt reaches a Windows harness intact, and refuse early when it cannot (#985)
  • fix(attempt): wait for Claude's trust dialog while the pane is blank (#991)
  • feat(watch): say when a worker's turn ended on an API error (#885)
  • docs: say plainly what Hand's agents can do, and how to run them safer (#960)

Tasks, supervisor and CLI

  • feat(deliverables): replace the PR-only link with deliverables; record them on a task the supervisor finished itself or that is already done (#889, #930, #973)
  • feat(watch): hand wake, durable timers for the supervisor; wake a supervisor that idles with unwatched work (#912, #914)
  • feat(cli): hand board stop and hand watch stop (#967); hand inbox size and prune (#923); hand open --delivered (#936)
  • feat(project): check a project's git settings before running git (#966)
  • fix(update): reap the service a board starts so a stop does not see a zombie (#986)

Install and platforms

  • feat(install): install on Windows with irm | iex; hint a missing PATH (#929, #931)
  • docs: state support for Linux, macOS and Windows, drop experimental (#901); a shorter README for testers (#934)
  • ci(release): attest build provenance for release archives (#932)

CI and tests

  • ci: end-to-end install, first run, Board and upgrade on Linux, macOS and Windows (#988)
  • ci: end-to-end tests with the real Claude Code and Codex against a mock model (#987)
  • test: remove the real-time waits that make tests flaky under load (#948)

Upgrade notes

  • Schema is now 13 (v0.11.0 was 9). hand update backs each fleet's database up first and migrates it; an older binary refuses a migrated database. docs/update.md has the restore.
  • v0.11.0's own hand update installs the new binary but does not restart the Board when a watcher also runs. hand update ends with could not start board and exit 1; run hand open afterwards. Later updates restart both.
  • Luvus is still 0.14.3.
  • Manual releases of tags before v0.12.0 no longer go through the release workflow, because its end-to-end gate needs the scripts this release adds.
  • Phone access needs an HTTPS address: tailscale serve is found automatically; see docs/phone.md.

Not verified

  • No run on a real Windows or macOS machine yet. CI covers both on GitHub's runners, including the real installers and the real Claude Code and Codex against a mock server, but not a person's machine. docs/dogfood/ is how to do it.
  • Desktop notifications on a real Mac (#895).
  • The release job's build attestation, which runs for the first time on this release (the step is best effort and does not hold back the release).
  • The Board in Firefox and Safari, on a real iPhone, and with a screen reader.

v0.11.0

14 October 2026

Hand v0.11.0

Changes since v0.10.0 (tagged 2026-10-07). Dependency bumps and the version bump are left out.

Highlights

Hand no longer needs systemd to keep itself running. The board starts on demand (hand open), keeps each fleet's watcher alive, and hand update stops and restarts them by pid file on Linux, macOS and Windows. There is one autostart per OS. The board can update itself on a timer (--update-every), and Hand can now move a quiet fleet to the pinned Luvus server by itself. hand init downloads the tested Luvus when none is on PATH. The README now says what each OS runs today, and docs/dogfood/ lists the checks for a real Mac or Windows machine.

Processes and autostart

  • feat(open): start the board when none is running (#865)
  • feat(update): stop and restart watchers and the board by pid file on every OS (#866)
  • feat(board): keep each fleet's watcher alive (#867)
  • feat(unit): start unit files with the graphical session (#864)
  • feat(unit): one autostart per OS, remove hand unit watch (#869)
  • feat(board): update on a timer with --update-every (#872)

Luvus

  • feat(init): download the tested Luvus when none is on PATH (#871)
  • feat(luvus): find and stop the server through UHP and server.pid on every OS (#877)
  • feat(luvus): start the server in a systemd scope instead of a named service (#878)
  • feat(update): switch a quiet fleet's Luvus server from the board's timer (#880)
  • document that a worker can reach the Luvus socket (#861)

Windows and macOS

  • feat(windows): neutral report footer, no console windows, long paths, rename retry (#870)
  • fix(cli): stop naming systemd on macOS and Windows (#875)

Board and CLI

  • feat(board): find finished tasks on the board and in hand task list (#862)

Docs and CI

  • docs: simplify the README getting started (#863)
  • docs: say what each OS runs today and what is still unverified (#873)
  • docs(dogfood): add macOS, Windows and Linux dogfood guides (#881)
  • rename ci job test to test-linux (#874)
  • ci: run the live Luvus tests on Linux and macOS (#876)

Upgrade notes

  • hand unit watch is gone. Fleets that installed watch units can keep them or remove them; the board now keeps watchers alive. One autostart is enough: hand unit board on Linux, a documented launchd plist on macOS and a Startup shortcut on Windows, all of which run hand board at login (README, Autostart).
  • The timer is off unless the board runs with --update-every. Without it, hand update is the only way an update starts.
  • Luvus switch: with --update-every, Hand switches a fleet's Luvus server only when the fleet is quiet and settled (no live attempt, an idle supervisor with an unchanged screen for 30 s, no queued input, no other live pane, no fleet event for 15 min). --keep-luvus never switches. hand update leaves a fleet that would switch as pending.
  • On Linux the server now starts in a transient systemd-run --user --scope instead of a named secondhand-luvus-* service. An existing named server keeps running and moves at its next switch or reboot.
  • Schema is still 9. Windows and macOS are verified by CI only, including the live Luvus tests on all three OSes; a run on a real machine has not happened yet. docs/dogfood/ is how to do it.

v0.10.0

7 October 2026

Changes since v0.9.0 (tagged 2026-10-02). Dependency bumps and PRs merged before the tag are left out.

Highlights

Hand now runs natively on Windows (amd64, experimental), with an installer script and a release zip. The supervisor skill picks a worker's effort with a short rubric, and the starter routing profiles differ only in effort. The board was reworked: clearer layout, larger touch targets, honest state and copy, and a start form that offers model and effort. The watcher can run a notify command when a decision is asked, wakes the supervisor when a worker hits a usage limit or stays in one turn for 60 minutes, takes a daily snapshot of hand.db, and keeps the last screen of an attempt it ends. hand attempt start --continue lets a new attempt take over an earlier attempt's branch and PR.

Windows

  • feat(windows): platform primitives (#768)
  • ci: run the tests on windows and fix what they found (#771)
  • feat(windows): fleet pointer file, update swap and PID files (#777)
  • feat(windows): named-pipe transport for the Luvus client (#808)
  • feat(windows): install.ps1, a release zip and docs for native Windows (#817)
  • fix(windows): refuse an http redirect and use a unique temp file in install.ps1 (#823)
  • fix(windows): set a read/write timeout in install.ps1 and smoke it under PowerShell 7 (#825)
  • fix(windows): bound the whole download in install.ps1 and name the shell in smoke failures (#828)
  • fix: retry a luvus pin rename that windows refuses while a handle is open (#842)

Board

  • list the oldest unread reports in Needs (#772)
  • feat(board): offer model and effort choices in the start form (#775)
  • fix(board): lay out the no-supervisor composer in one box (#829)
  • fix(board): say why a read-only board has no composer (#836)
  • fix(board): show Needs affordances and the rail from 1024px (#837)
  • fix(board): make the task title the link and put the meta under it (#840)
  • fix(board): raise touch targets and fit small windows (#843)
  • fix(board): honest state and copy (#844)
  • fix(board): navigation and thread pages (#847)
  • fix(board): give controls a 3:1 border token (#848)
  • fix(board): clock-only times under day dividers, one zone (#849)
  • fix(board): let thread card text fill the card (#853)
  • fix(markdown): keep numbers across interrupted lists and nest indented lines under items (#835)

Watcher and supervisor

  • feat(supervisor): start the watcher with the supervisor (#773)
  • feat(watch): wake attempt.limited when a worker stops on a usage limit (#785)
  • fix(supervisor): hold wakes while the supervisor sits at a usage limit (#795)
  • feat(watch): wake attempt.long once when a worker stays in one turn for 60 minutes (#806)
  • fix(watch): keep the attempt.long clock across a watcher restart (#813)
  • feat(watch): alert on decision.asked and run a configurable notify command (#833)
  • snapshot hand.db daily from the watcher and keep seven (#851)
  • feat: keep the last screen of an attempt the watcher ends (#854)
  • add attempt start --continue and base new worktrees on fetched origin/main (#852)
  • feat(orient): tell a resumed or switched supervisor it is the running one (#814)
  • Wake hygiene, watch.lock probe fix and orient worker signal (#792)
  • Show each profile's track record in route list (#789)
  • feat(route): an effort rubric in the skill and a matching starter (#812)
  • use restore:false, the prompt fence and the exit status from Luvus (#786)
  • fix: delivery survives a watcher stop, stop ends rows whose terminal will not close (#753)
  • fix: orient names the live supervisor, Stop keeps its arm across a redraw (#759)
  • fix(attempt): accept claude's trust screen in its own worktree (#769)
  • fix agy model check timing out while agy models is listing (#770)
  • fix(board): keep starts running after a dropped request and record supervisor launch notes (#790)
  • fix(harness): launch codex with hooks disabled (#807)
  • fix: run no repository hooks under hand's git calls and create worktrees 0700 (#830)
  • fix: harden attempt clean and git output parsing (#783)
  • bound and explain the shell-outs (#788)
  • ask workers to wait in one blocking command (#787)
  • fix: seven fleet papercuts (#855)
  • fix(board): repeated messages keep their own delivery, Needs ids carry their kind (#754)

Update and install

  • feat(update): finish an update that was killed part way (#758)
  • fix(update): hold a Luvus switch while a pane Hand did not start is live (#774)
  • fix(update): bring back a transient watcher after an update (#791)
  • fix(cli): unit files keep the caller's PATH (#751)
  • ci: title release drafts with the tag (#752)

Docs and tests

  • docs(skill): say what the resume message means (#820)
  • docs: a Safe use section for running workers with permission prompts skipped (#831)
  • docs(skill): issues also get area and platform labels (#850)
  • docs: drop the 2x median clause from the capability-failure rule (#856)
  • ci: label PRs by changed paths and state the issue type-label rule (#832)
  • test: replace the shell fakes with a Go fake harness (#779)
  • test wakes held and auto-resume under a pending switch (#776)
  • test(cli): take 30 s off the race run, cover untested critical paths (#793)
  • test: keep the fake watcher's lock and retry it like the real watcher (#809)
  • test(watch): drive the attempt.long restart tests by observed ticks (#816)
  • refactor(watch): read the runner clock in observe and longTurns (#821)
  • fix: stop asserting tight wall-clock limits in the nesting-cap and expired-dial tests (#839)
  • fix(watch): make the unreadable-screen test wait on failed reads (#858)

Issues closed in the same period: #760, #762–765, #767, #781, #782, #797, #799–804, #810, #811, #815, #818, #819, #822, #824, #827, #834, #838, #841, #857. Each is closed by one of the PRs above.

Upgrade notes

  • Schema: the state schema moves from 7 (v0.9.0) to 9: #852 added 8 and #854 added 9. hand update backs up every fleet before it swaps the binary (internal/update/update.go, Backup) and then runs init on each fleet. A fleet migrates when the new binary first opens it. Not verified: a live hand update across a v0.9.0 fleet. A fleet at schema 9 cannot be opened by an older hand.
  • Windows is still experimental: it has not passed an end-to-end run on a real Windows machine, and it has no units and no desktop notifications (README, docs/spec.md).
  • hand attempt start now runs git fetch origin (20 s limit) and bases the worktree on origin/main. If the fetch fails it starts from the existing remote-tracking branch, or the local HEAD, and says so. --base overrides the ref (internal/cli/attempt.go).
  • Routing: the starter routing.json is five claude sonnet profiles (quick, default, high, deep, max), differing only in effort. v0.9.0 had quick on codex gpt-6-luna and deep on opus. The starter is written only when routing.json is missing, so an existing file is not changed (hand init never overwrites it, per docs/vocabulary.md).
  • notify in routing.json: an argv the watcher runs for each alert, with HAND_NOTIFY_KIND, HAND_NOTIFY_REF, HAND_NOTIFY_TEXT and HAND_NOTIFY_URL in its environment. Without it, Hand uses notify-send on Linux or osascript on macOS. hand watch --notify=false turns alerts off.
  • Luvus panes are created with restore:false (#786), so a Luvus server restart no longer relaunches Hand's panes.

v0.9.0

2 October 2026

Hand 0.9.0 ships binaries for Linux and macOS, an edge channel, and hand update, which keeps the binary, every fleet and its Luvus pin current in one step.

Highlights

  • Binaries and an edge channel.
    • Every release carries hand-linux-{amd64,arm64} and hand-darwin-{amd64,arm64} archives, plus checksums.txt.
    • Every green push to main refreshes the rolling edge pre-release.
    • install.sh installs either channel after a checksum check.
  • hand update replaces the manual deploy. It:
    1. downloads the newest build of the channel the running hand came from, and checks it;
    2. backs up every fleet's hand.db and the old binary under ~/.secondhand/backups/;
    3. swaps the binary, restarts the board and watch units, and runs hand init in every fleet.

    It also pins the Luvus version the build was tested with, and never lowers the pin. It switches a fleet's Luvus server only when no worker is live and the supervisor is idle; otherwise it prints the command to run later.

    • hand update --check shows the plan.
    • --channel edge|stable moves between channels.
  • macOS (part A).
    • Hand builds, tests and runs on Apple silicon and Intel Macs.
    • Until launchd support lands, run hand watch and hand board yourself. The Luvus server starts directly.
    • Windows works through WSL2 with the Linux build.
  • hand version prints the version, the channel (source, edge or stable), the commit, the state schema and the tested Luvus.
  • Antigravity (agy) can be the supervisor, as well as a worker.
  • The board attaches images from the composer. Paste, drop or pick a PNG, JPEG, WebP or GIF of up to 10 MiB; the supervisor sees its path, and the chat shows it.
  • Fixes.
    • hand unit writes your PATH into the unit. After a reboot, the board, the watcher and the Luvus server they start can find your harnesses.
    • A supervisor stopped or switched before its first delivery keeps its session.
    • The working line follows the board's clock, and Needs headers hold no links.
    • Unit files keep a custom SECONDHAND_HOME.
    • agy models no longer waits on a child that holds its output.

Install

curl -fsSL https://raw.githubusercontent.com/atqamz/hand/main/install.sh | sh

HAND_INSTALL_VERSION=edge installs edge, and HAND_INSTALL_DIR picks the folder (default ~/.local/bin). The README lists the requirements: git, Luvus 0.14 and at least one logged-in harness.

Upgrading from 0.8.0

0.8.0 has no hand update, so the first upgrade is by hand:

  1. Install 0.9.0 with install.sh, into the folder your units run from.
  2. Run hand unit watch and hand unit board again, then systemctl --user daemon-reload, so the units keep your PATH.
  3. Restart the board and watch units.
  4. Run hand init in each fleet.

After that, hand update does all of this.

Not in this release

  • launchd units and a launchd-supervised Luvus server on macOS (part B).
  • Native Windows.

v0.8.0

1 October 2026

Hand 0.8.0 is a redesign. You talk to one supervisor agent. Hand runs it for you, starts workers in isolated git worktrees, waits for them at zero token cost, and asks you only through decisions.

Highlights

  • A managed supervisor. Hand starts, resumes, switches and stops one supervisor per fleet (sN) on Claude Code, Codex or opencode. Wakes reach it as messages, so it never polls.
  • Workers in their own worktrees on Claude Code, Codex, opencode or Antigravity (agy, which runs workers only). Each attempt gets a branch hand/<fleet id>/tN-aN, and the worker reports back with hand report add.
  • Luvus is the only runtime.
    • Hand speaks UHP 1.x to one Luvus server per fleet, which runs in a systemd user unit.
    • Hand pins its own copy of the Luvus binary (hand luvus pin, hand luvus show), so a system upgrade never changes the Luvus a fleet runs.
  • The board (hand board, hand open) is an on-call desk:
    • Needs lists what waits on you, most severe first: blocked screens with their own keys, failures, decisions and unread reports.
    • Chat holds the conversation with the supervisor, with model, effort and harness switching, Interrupt and Stop.
    • It updates live and works from a phone through a tunnel. Supervisor controls stay on loopback.
  • Routing profiles in routing.json name a harness, model and effort for workers and the supervisor (hand route list).
  • Fleets are folders, each with its own SQLite state (hand.db). One board shows every fleet. Output is TOON, and exit codes are 0–3.

Install

Build from source on Linux, with Go 1.26.5 or newer, git, Luvus 0.14 and at least one logged-in harness:

git clone https://github.com/atqamz/hand
cd hand
go build -o ~/.local/bin/hand .

Upgrading from 0.7

Follow "Upgrading from 0.7" in the README:

  1. Finish or tear down every live 0.7 task.
  2. Keep the old binary as hand-0.7.
  3. Remove the 0.7 wiring.
  4. Run hand init in the fleet, then let its supervisor migrate it with the secondhand-migrate skill.

Hand 0.7 lives on the 0.7 branch.

Not in this release

Prebuilt binaries, Windows and macOS support, and an edge channel are planned for later.

v0.7.2

29 August 2026

0.7.2 (2026-08-29)

Bug Fixes

  • npm: read npm 12's array-shaped npm view document (#512) (b8d22bb), closes #511

v0.7.1

29 August 2026

0.7.1 (2026-08-29)

Bug Fixes

  • npm: retry post-publish verification instead of failing a first-ever publish (#507) (2a9a8e3)

v0.7.0

29 August 2026

0.7.0 (2026-08-29)

Features

  • cmd: record a PR delivered to a sibling repository with hand pr --cross-repo (#467) (e1cb96f)
  • completion: carry project identity on completion records (#400) (c7b3f5f)
  • harness: add worker-only Antigravity support (#351) (b424e89)
  • harness: catalogue codex's usage-limit signature (#450) (1edfc35)
  • herdr: add Fleet-scoped session lifecycle management (#386) (70c75ff)
  • launch: replace shell-assembled worker launches (#349) (e08071b)
  • npm: publish stable releases to npm behind an operator-approval gate (#489) (7af7221)
  • orientation: make supervisor orientation stateless and Fleet-scoped (#350) (ebce096)
  • project: add local Git project adoption and creation (#334) (42883fe)
  • project: add project mode updates and renaming (#383) (1c7d9d5)
  • runtime: add fleet identity and registry isolation (#341) (a3cdd3d)
  • selfupdate: add stable bootstrap adoption flow (#352) (26b243c)
  • store: give projects a durable surrogate identity (#399) (9661902)
  • supervision: autonomously re-enter supported Supervisor Harnesses without operator prompts (#356) (fbbdeed)
  • toolchain: add private pinned core runtime (#342) (749d1cc)

Bug Fixes

  • accept idle rendered composers (#374) (25ed6cd)
  • attention: surface a not-submitted send to the supervisor (#447) (8bb29b3)
  • centralize secondhand infrastructure root (2ee29db)
  • doctor: report a Treehouse lease held by a Fleet absent from the registry (#462) (4af1909)
  • expose exact Fleet Herdr session state (e5880d0)
  • harness: append the report channel to grok's and pi's brief file (#453) (d5968f1)
  • harness: state ship/scout delivery authorization at launch (#449) (9f7f23b)
  • holds: report a blocked hold once its blocker goes terminal (#452) (4d6f74c)
  • home: refuse HAND_HOME and cwd naming different fleet homes (#469) (8e551e0)
  • init: adopt hand's own source tree, and refuse an untagged suite by name (#438) (fc9ee9e)
  • keep help independent of fleet registry (#381) (d837a88)
  • merge: converge on a PR merged outside hand instead of refusing (#461) (d3c5958)
  • name checkout in trust refusal (#493) (3fedb88)
  • orient: corroborate and latch parked before treating it as actionable (#494) (5ecb1f2)
  • paths: render resolved paths pasteably instead of %q (#475) (28cd355)
  • project: preserve unrelated completion records during rename rollback (#396) (d706b7c)
  • promote: refuse to launch a ship attempt against an unrevised brief (#456) (0d039ab)
  • reconcile: guard every teardown release behind one releasing check (#485) (da24388)
  • refresh mechanical plan base before dispatch (#429) (53e59f5)
  • registry: make test isolation unforgettable, add prune, refuse managed-tree homes (#454) (111eef2)
  • registry: reconcile stale same-home Fleet claims (#385) (d9a613d)
  • registry: scope ambiguity classification to affected Fleets (#382) (79a2cf4)
  • runtime: close the worktree release gate on evidence (#457) (37956ca)
  • runtime: diagnose a git bundle with no https helper (#463) (a0067a7)
  • runtime: give the managed git a real, empty template directory (#468) (f1b460a)
  • runtime: use recorded PR after detached HEAD (#390) (44c7189)
  • scope treehouse pools to fleet homes (#404) (175c162)
  • steering: anchor Tab confirmation on the composer's last block (#495) (1686ef1)
  • steering: chunk PaneSendText writes below the measured stall boundary (#480) (c4da6cc)
  • steering: confirm Enter submission by positive composer evidence, not a claim (#476) (fd7e32f)
  • steering: send Tab, not Enter, to a busy codex pane (#466) (1dc67d7)
  • supervision: fail closed on unavailable runtime identity (#384) (4da2106)
  • test: make test pass reliably on a clean checkout under load (#370) (b4304db)
  • watcher: confirm parked workers with live pane activity (#366) (16e0faf)
  • watcher: name the recorded lock holder in a contended refusal (#451) (3334151)
  • watcher: stop failing an arm when a task is torn down mid-probe (#465) (60b98d6)
  • watcher: stop re-firing attention for delivered tasks (#367) (28c51cb)
  • worktree: enforce pool slot integrity (#496) (9585b47)
  • worktree: put the pool outside every fleet home (#444) (8f2881b)

v0.6.0

21 August 2026

0.6.0 (2026-08-20)

Features

  • add checksum-verifying Hand installers (#280) (2d1e876)
  • add cross-platform Secondhand bootstrap (#297) (a3b36dc)
  • add Windows PowerShell bootstrap (#298) (530bb83)
  • cmd: add doctor readiness contract (#296) (758a3af)
  • cmd: add explicit acknowledgement for task status (#281) (f9c743d)
  • doctor: expand hand doctor diagnostic coverage (e038b71)
  • init: make hand init the canonical fleet-reconciler contract (690edde)
  • packaging: add Homebrew, npm, deb, rpm, WinGet, and AUR package surfaces (#277) (be08bd0)
  • skill: bundle first-party secondhand Agent Skill (e7bc210)
  • update: hand update hands off fleet reconciliation to the new binary (8ab2bf5)

Bug Fixes

  • cmd: preserve PR observation provenance (#278) (72dd288)
  • cmd: preserve unknown report observations (#279) (4cfd1f3)
  • runtime: detect PRs by durable branch name across a detached HEAD (#285) (6015e10)
  • runtime: label pane-derived holds as inferred (#282) (cea038d)
  • runtime: observe attempt liveness from Herdr agent_status in reconcile (#275) (110d6af)

v0.5.0

20 August 2026

0.5.0 (2026-08-20)

Features

  • brief: make worker briefs execution-ready (#227) (48fdfe1)
  • cmd: surface deterministic session next action (#238) (d4b8714)
  • doctor: report project gate and routing health (#249) (a563b36)
  • runtime: add deterministic reconciliation (#229) (bc5c219)
  • runtime: give every reconcile repair diagnosis a reachable treatment (#258) (3029818)
  • selfupdate: embed distribution identity in build metadata (#271) (05a81cc)
  • store: split durable tasks from execution attempts (#219) (c9772bd)
  • update: refuse to mutate a package-manager-owned build (#273) (ee3b184)

Bug Fixes

  • gate: distinguish an unobserved gate run from an absent one (#264) (5d63cfa)
  • ghutil: observe pull requests as found, absent, or unknown (#256) (f054c41)
  • project: preserve operator-owned pull request metadata (#260) (0eb6dc2)
  • runtime: clear a resource repair code an attestation already resolved (#272) (b7e4139)
  • runtime: converge terminal attempt lifecycle and gate worktree return on commit safety (#251) (0513224)
  • runtime: reach pull request head evidence when remote-tracking refs cannot prove durability (#257) (d36591c)
  • runtime: recover unobservable worktree ownership (#248) (cb93eb3)
  • selfupdate: reconcile update notice cache (#237) (2e8d493)
  • steering: make terminal sends crash-safe (#230) (af7e118)
  • watcher: harden takeover and cancellation lifecycle (#231) (be189b6)
  • watcher: stop teardown from reporting a torn-down worker's success as a failure (#261) (2486b20)
  • watcher: suppress false stale events for terminal or delivered tasks (#236) (152ab71)
  • watcher: wake on a fleet condition that was already actionable when the watch armed (#262) (8adb5f1)

v0.4.0

13 August 2026

0.4.0 (2026-08-13)

Features

  • add Windows portability (#203) (998b2c3)
  • establish hand project identity (#179) (d689778)
  • project: repoint a registered project at a renamed repo (#209) (b843340)
  • selfupdate: add rolling edge release channel (#212) (911135e)

Bug Fixes

  • notify: resolve POSIX sh on PATH with an actionable missing-sh error (#211) (95c48a5)
  • restore README onboarding guidance (#185) (fe0b70f)

v0.3.0

9 August 2026

0.3.0 (2026-08-09)

Features

  • session: add supervisor session bootstrap (#173) (6b51061)

v0.2.0

5 August 2026

v0.1.4

4 August 2026

0.1.4 (2026-08-04)

Features

  • cmd: detect gate-opened PRs on a project's declared upstream (#142) (63bfe31)
  • cmd: make hand watch a singleton and flag unread terminal reports (#138) (4eb6932)
  • cmd: record delivered-not-landed work and accept a PR on a project's declared upstream (#135) (9bccfb1)
  • cmd: seed operator context, learnings and backlog archive files (#133) (95e22b3)
  • deliver the operator-decision rule to workers and add hand doctor (341b151)
  • store: gate schema changes on PRAGMA user_version (#115) (5c6f237)
  • watcher: notify a supervisory agent when no session is watching (#131) (d135901)

Bug Fixes

  • cmd: create the data directory update seeds into and report every seed failure (#139) (f6f58cc)
  • cmd: print HAND_HOME mismatch warning as an absolute path (#126) (d045762)
  • herdr: close the workspace herdr created when workspace create returns an unusable response (#112) (21fb575)
  • herdr: sanitize inherited harness-identity env on pane creation and document holds in the fleet-home template (#130) (78f94dc)
  • make hand send survive a busy composer and stop herdr lookups matching foreign state (a285913)
  • state: tolerate a report channel rewritten in place (#144) (aaa112f)
  • watcher: anchor parked on durable pane-start and fired-for stamps (#143) (ddb57dc)
  • worktree: key the collision guard on the treehouse lease id (#132) (56c52b3)

v0.1.3

2 August 2026

0.1.3 (2026-08-02)

Features

  • cmd: resolve a fleet home from HAND_HOME or an ancestor walk instead of the working directory (#104) (a4e0369)
  • cmd: write a durable completion record before teardown removes task state (#101) (5cbcd23)
  • state: back machine state with sqlite and index the prose corpus (#107) (8f44164)

v0.1.2

2 August 2026

0.1.2 (2026-08-02)

Features

  • cmd: honor a brief's declared model and effort on spawn and promote (#59) (017fffa)
  • cmd: name what is dirty on teardown refusal and allow already-landed dirt (#93) (bcaee85)
  • cmd: refuse to dispatch into an uninitialized no-mistakes gate (#94) (d4cd130)
  • cmd: surface PR merge state in hand status (6a768aa), closes #51 #58
  • watch: add hand watch --until-event so the watcher can wake its orchestrator (c14bf27)

Bug Fixes

  • cmd: cap report rendering in hand status (#91) (4d2294a)
  • cmd: detect gate-opened PRs by branch head ref (#76) (8fddac4)
  • cmd: reuse a new workspace's root tab instead of orphaning it (#72) (81e6427)
  • ghutil: resolve multi-PR head refs by preference tier instead of an arbitrary pick (4149241)

v0.1.1

27 July 2026

0.1.1 (2026-07-27)

Features

  • cmd: add worker report channel with hand pr and dashboard reconciliation (#38) (7fd9e3e)

Bug Fixes

  • cmd: confirm workers clear first-run dialogs before reporting spawn success (#37) (e3bbcb3)
  • cmd: parse subprocess stdout only and pad CLI table columns with tabwriter (#23) (649fa02)
  • launch workers interactively and stop leaking herdr workspaces (#29) (170dd98)

v0.1.0

26 July 2026

0.1.0 (2026-07-26)

Features

  • bootstrap secondhand CLI scaffold (#1) (598bf73)
  • cmd: add hand update self-update and startup version notice (#11) (832ca37)
  • cmd: add merge, promote, notify, and project sync commands (#10) (8fde5fa)
  • cmd: add task lifecycle commands (#7) (68ebd68)
  • cmd: add watch command and dashboard maintenance (#9) (9c27f45)
  • cmd: add workspace initialization and project management (#2) (0e445d4)
  • cmd: refresh AGENTS.md and report release notes on hand update (#16) (727080f)
  • set initial release version to 0.1.0 (#5) (2bfc925)

Bug Fixes

  • cmd: enforce exit-code contract and split watch diagnostics to stderr (#12) (93a8691)
  • make the nix flake usable for builds and dev shells (#14) (d4c5275)