tickmarkr 2.8.3 → 2.8.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/claude-code.js +6 -2
- package/dist/adapters/codex-commit-check.js +2 -1
- package/dist/adapters/cursor-agent.js +2 -1
- package/dist/adapters/grok.js +2 -1
- package/dist/adapters/kimi.js +41 -10
- package/dist/adapters/opencode.js +2 -1
- package/dist/adapters/pi.js +3 -2
- package/dist/adapters/qwen.js +2 -1
- package/dist/adapters/registry.js +2 -1
- package/dist/adapters/types.d.ts +2 -0
- package/dist/adapters/types.js +18 -3
- package/dist/cli/commands/doctor.d.ts +49 -5
- package/dist/cli/commands/doctor.js +956 -94
- package/dist/cli/commands/fleet.js +11 -3
- package/dist/cli/commands/init.js +2 -2
- package/dist/cli/commands/verify.js +12 -3
- package/dist/compile/index.js +4 -1
- package/dist/config/config.d.ts +15 -0
- package/dist/config/config.js +67 -5
- package/dist/drivers/host-env.d.ts +3 -0
- package/dist/drivers/host-env.js +47 -0
- package/dist/drivers/orca.js +3 -1
- package/dist/drivers/subprocess.d.ts +1 -1
- package/dist/drivers/subprocess.js +4 -3
- package/dist/gates/acceptance.js +130 -12
- package/dist/gates/baseline.d.ts +1 -1
- package/dist/gates/llm.js +11 -6
- package/dist/run/git.js +12 -13
- package/dist/run/journal.js +40 -11
- package/dist/run/lock.d.ts +5 -0
- package/dist/run/lock.js +202 -9
- package/dist/run/protocol.d.ts +1 -1
- package/dist/tui/cockpit/live-store.js +12 -2
- package/package.json +1 -1
- package/skills/tickmarkr-auto/SKILL.md +65 -21
- package/skills/tickmarkr-loop/SKILL.md +65 -21
- package/skills/tickmarkr-overseer/SKILL.md +88 -32
|
@@ -20,18 +20,50 @@ Keep `name: tickmarkr-auto` and the installed links to canonical `skills/` intac
|
|
|
20
20
|
|
|
21
21
|
## Two-tier by default — role check before the loop
|
|
22
22
|
|
|
23
|
-
When working in a multi-agent terminal environment, decide your role before starting:
|
|
23
|
+
When working in a multi-agent terminal environment (herdr or Orca), decide your role before starting:
|
|
24
24
|
|
|
25
25
|
- **Orchestrator:** your session was started to execute the mission. Rename your own tab/pane `ORCH · <version>` (short labels: ≤20 chars, `ROLE · token`) and run the loop below.
|
|
26
26
|
- **Supervisor with a live orchestrator:** do not start a second run. Relay the mission to the existing orchestrator with a [verified handoff](#verified-handoffs-agent-to-agent-messaging), then supervise it as OVERSEER.
|
|
27
27
|
- **Primary session without an orchestrator:** rename your own tab `OVERSEER · <version>` and your agent `overseer`, spawn one child orchestration session with your host's launch form, label its tab `ORCH · <version>` and name its agent, give it the mission and these rules verbatim, then supervise it. Do not drive a duplicate single-tier run yourself. Before spawning, confirm any PREVIOUS orchestrator has stood down (monitors stopped, input box empty — dim ghost-text suggestions are UI, not queued input; ANSI-verify before alarming) and close its tab — the journal, records, and ledger hold the story; scrollback is disposable.
|
|
28
|
-
- **
|
|
29
|
-
|
|
30
|
-
|
|
28
|
+
- **On herdr (`HERDR_ENV=1`)**: **spawning on current herdr is two-step** — the one-shot `agent start --cwd/--tab/--no-focus` form was removed in the herdr CLI redesign and now fails with `unknown option` (OBS-138). First create the pane: `herdr tab create --workspace <ws> --cwd <repo> --label "ORCH · <version>"` (tab create does not steal focus unless `--focus` is passed; parse `result.root_pane.pane_id` from its JSON), then start the agent in it:
|
|
29
|
+
- **Claude Code:** `herdr agent start orchestrator --kind claude --pane <root-pane-id> -- --permission-mode bypassPermissions`
|
|
30
|
+
- **Codex:** `herdr agent start orchestrator --kind codex --pane <root-pane-id> -- --dangerously-bypass-approvals-and-sandbox` — the unsandboxed flag is REQUIRED, not optional: codex's `workspace-write` sandbox keeps `.git` refs read-only, so a sandboxed orchestrator's `tickmarkr run` dies at integration-branch creation (`git worktree add` cannot lock the ref). Do not downgrade this flag; the herdr pane and repo scope are the containment.
|
|
31
|
+
- **Auxiliary seats run as the CLI's interactive TUI in their visible pane — never headless** (`claude -p` / `codex exec`): headless buffers output until exit so the pane renders idle for the entire run, is blind to SessionStart hook errors (a broken and a fixed hook both return green), and gives a stall watcher no midpoint — silent-time equals lifetime. Headless is for exit-code probes only (a quota check that wants `rc`), never for work anyone must watch.
|
|
32
|
+
- **On Orca (`TERM_PROGRAM=Orca` and non-empty `ORCA_TERMINAL_HANDLE`)**: spawn it with `orca terminal create --worktree path:<repo> --title "ORCH · <version>" --command "<agent-cmd>" --json` and parse `result.terminal.handle` from the create receipt. **Auxiliary seats run as the CLI's interactive TUI in their visible terminal — never headless**, for the reasons the herdr branch gives.
|
|
31
33
|
- **Auxiliary agents you spawn (consultants, reviewers, scouts) follow the same forms.** Never launch a claude session in plan mode or default permission mode for autonomous work — both stall on per-command approval prompts nobody is watching; claude is always `--permission-mode bypassPermissions` (tickmarkr's own adapter uses exactly this for workers, judges, and consults). A read-only codex consultant may use `--sandbox read-only`; any codex session that must touch git needs the unsandboxed flag above.
|
|
32
|
-
- **Auxiliary seats run as the CLI's interactive TUI in their visible pane — never headless** (`claude -p` / `codex exec`): headless buffers output until exit so the pane renders idle for the entire run, is blind to SessionStart hook errors (a broken and a fixed hook both return green), and gives a stall watcher no midpoint — silent-time equals lifetime. Headless is for exit-code probes only (a quota check that wants `rc`), never for work anyone must watch.
|
|
33
34
|
|
|
34
|
-
|
|
35
|
+
With neither herdr nor Orca there is no role to decide and no seat to spawn: follow [On a plain host (neither herdr nor Orca)](#on-a-plain-host-neither-herdr-nor-orca) and run the loop directly, single-tier.
|
|
36
|
+
|
|
37
|
+
## On a plain host (neither herdr nor Orca)
|
|
38
|
+
|
|
39
|
+
Neither `HERDR_ENV=1` nor the Orca markers are set: the Claude Desktop Code tab, a plain terminal, any
|
|
40
|
+
agent session that owns no panes (queue row 192; D-2102). The role check above does not apply.
|
|
41
|
+
|
|
42
|
+
- **This session runs SINGLE-TIER as the orchestrator.** There are no seats, no pane briefs, no tab
|
|
43
|
+
canon and no board: run every step of [the per-spec loop](#per-spec-loop) yourself and skip every
|
|
44
|
+
On herdr and On Orca scope.
|
|
45
|
+
- **An empty mission is asked for, never assumed.** With no target named, ask the operator what to run
|
|
46
|
+
end-to-end before compiling anything; there is no other tier to relay it to.
|
|
47
|
+
- **Run and resume launch through the anchor-free lines** of the
|
|
48
|
+
[detached launch](#host-owned-daemon-and-detached-beats): the same `node` detach with no address, one
|
|
49
|
+
line for `tickmarkr run` and one for `tickmarkr resume <runId>`. The daemon places no board, so a
|
|
50
|
+
missing board is never a fault; confirm the launch from the lock pid as that section says.
|
|
51
|
+
- **Run-end and parks are watched through the host's background wait**, never a foreground wait past
|
|
52
|
+
the host's ten-minute tool cap: the cap kills that wait, ends the turn and leaves the run unwatched.
|
|
53
|
+
Start the wait as a background task whose exit wakes this session, on journal lines after a baseline
|
|
54
|
+
taken at arm time and on the lock holder's death:
|
|
55
|
+
`n=$(wc -l < <journal>); until tail -n +$((n + 1)) <journal> | grep -qE '"event":"(run-end|task-human|task-failed|consult-verdict)"' || ! kill -0 <pid>; do sleep 20; done`
|
|
56
|
+
(`<journal>` is `<state-dir>/runs/<runId>/journal.jsonl`, `<pid>` the lock pid). On every wake read
|
|
57
|
+
CURRENT `tickmarkr status <runId>` first, then re-arm.
|
|
58
|
+
- **The operator's view is `tickmarkr status <runId>`**, plus its live `status --watch --plain` form,
|
|
59
|
+
`tickmarkr status <runId> --watch --plain`, in a read-only Terminal tab beside this session.
|
|
60
|
+
- **Reviews and judges run headless.** The subprocess driver runs every worker, judge and review as a
|
|
61
|
+
headless CLI call with no pane to watch: read their verdicts from the journal, the gate evidence and
|
|
62
|
+
`tickmarkr status <runId>`, never from a screen.
|
|
63
|
+
- **Sessions hand off through the host's cross-session message tool**, confirmed by the peer's reply:
|
|
64
|
+
there is no composer to read back, so a message no peer answered is not a handoff.
|
|
65
|
+
- **Keep a permission mode that never stalls per command** for the whole run (for example
|
|
66
|
+
`bypassPermissions`): nobody answers a per-command approval prompt in an unattended session.
|
|
35
67
|
|
|
36
68
|
## Stand-down (mission end and retirement)
|
|
37
69
|
|
|
@@ -79,21 +111,24 @@ concurrently* — so a machine-wide check answers a question nobody asked and bl
|
|
|
79
111
|
|
|
80
112
|
## Verified handoffs (agent-to-agent messaging)
|
|
81
113
|
|
|
82
|
-
|
|
114
|
+
Never report "briefed" or "relayed" without the confirmation your host gives:
|
|
83
115
|
|
|
84
|
-
Use one of:
|
|
116
|
+
- **On herdr (`HERDR_ENV=1`)**: when relaying missions between agents in a multi-agent terminal, **never use bare send-text** (`herdr agent send` / pane send-text) — it writes text without pressing Enter, so handoffs sit unsubmitted (OBS-39). Use one of:
|
|
117
|
+
- `herdr pane run <pane> "<message>"` — text plus Enter in the target shell
|
|
118
|
+
- `herdr notification show "<message>"` — OS-level delivery for the operator
|
|
85
119
|
|
|
86
|
-
|
|
87
|
-
- `
|
|
88
|
-
|
|
89
|
-
After sending, **confirm delivery** by reading the target pane and verifying the message landed (input empty, agent status `working`, or notification acknowledged). Never report "briefed" or "relayed" without read-back confirmation.
|
|
120
|
+
After sending, **confirm delivery** by reading the target pane and verifying the message landed (input empty, agent status `working`, or notification acknowledged). Never report "briefed" or "relayed" without read-back confirmation.
|
|
121
|
+
- **On Orca (`TERM_PROGRAM=Orca` and non-empty `ORCA_TERMINAL_HANDLE`)**: send with `orca terminal send --terminal <handle> --text "<message>" --enter --wait-submit 15 --json` and treat it as delivered only when `result.send.prompt.stages` carries a `turn_started` stage — `accepted: true` proves input acceptance, not a started turn.
|
|
122
|
+
- With neither host, hand off through the host's cross-session message tool, confirmed by the peer's reply ([On a plain host (neither herdr nor Orca)](#on-a-plain-host-neither-herdr-nor-orca)).
|
|
90
123
|
|
|
91
124
|
## Per-spec loop
|
|
92
125
|
|
|
93
126
|
1. **Prepare** — confirm the target list. Run the [binary preflight](#binary-preflight-before-compile-or-run). Check `git status`, confirm no tickmarkr run is active, and work from a non-main branch.
|
|
94
127
|
2. **Compile** — run `tickmarkr compile <spec-or-directory>`. Fix source-spec defects instead of editing the generated graph.
|
|
95
128
|
3. **Plan** — run `tickmarkr plan`. Review routes, capability-floor warnings, and human gates before execution.
|
|
96
|
-
4. **Run** — launch `tickmarkr run` using the [detached launch](#host-owned-daemon-and-detached-beats), and start detached beats with their run-end stop items. A watch ending the seat's turn is no watch: keep a **blocking journal consumer** alive for the run's terminal events
|
|
129
|
+
4. **Run** — launch `tickmarkr run` using the [detached launch](#host-owned-daemon-and-detached-beats), and start detached beats with their run-end stop items. A watch ending the seat's turn is no watch: keep a **blocking journal consumer** alive for the run's terminal events, and never rely on a `Monitor`-only wake. Watch the run journal rather than polling agents: the consumer takes a line baseline at arm time, then wakes ONCE on `run-end`, `task-human`, `task-failed` or `consult-verdict`. A run-end record is history, never green; the debt clause is yours — read CURRENT `tickmarkr status <runId>` (step 5). Re-arm after every wake. ⛔ Never `tail -F | grep -m1` (run-end is the journal's last line, so tail never notices the broken pipe and the watcher hangs forever) and never a pane-level done wait (it fires on every agent turn end, not mission end). ⚠ A bare whole-file `grep -q '"event":"run-end"'` is the trap the watcher exists to avoid: on a resume it matches the PREVIOUS run's run-end and returns instantly, so a re-armed watcher reads as coverage that does not exist. Resolve blocked interactions in the relevant agent session. The consumer is host-specific; with neither host it is the background wait of [On a plain host (neither herdr nor Orca)](#on-a-plain-host-neither-herdr-nor-orca).
|
|
130
|
+
- **On herdr (`HERDR_ENV=1`)**: the consumer is the shipped watcher — `.claude/skills/tickmarkr-overseer/scripts/watch-journal.sh <state-dir>/runs 20 28800`, which grades the run-end summary's execution clauses for you, `EXECUTION COMPLETE` or `NOT GREEN`, never green — or a foreground `until grep` on the run's terminal events; ensure it is re-armed at most every twenty minutes.
|
|
131
|
+
- **On Orca (`TERM_PROGRAM=Orca` and non-empty `ORCA_TERMINAL_HANDLE`)**: the consumer is that same shipped journal watcher or a foreground `until grep` on the run's terminal events; ensure it is re-armed at most every twenty minutes.
|
|
97
132
|
5. **Verify and consolidate** — continue only after a green run. A run is green when the run-end event exists in the journal, the tip verify is not "failed", the summary's `failed`, `human`, `blocked` and `pending` buckets are all empty, and CURRENT `tickmarkr status <runId>` reads its owed checks outstanding empty AND known (`outstanding 0`) — a run with a parked task is partial, not green. Empty execution buckets alone are not green either (D-660): every bucket empty and the tip passed, but an operator waived one review, leaves one accepted-risk review check owed — status reads `outstanding 1 (T7 review)` and `run`/`resume` still exit 0 on execution alone, so the run is execution complete, not green. It turns green only when a `tickmarkr verify --record <runId>` discharge moves CURRENT status to `outstanding 0`, including a discharge landing after run-end — the historical run-end record keeps the old count, so never read debt from it; `outstanding unknown` is never green. Tickmarkr consolidates accepted work on `tickmarkr/<runId>` and never signs off to the main branch. A human controls any later release merge.
|
|
98
133
|
6. **Record** — `tickmarkr report <runId> --md` prints Markdown to stdout; redirect explicitly beside the spec (for example `tickmarkr report <runId> --md > feature.record.md`) and commit the execution record when the repository tracks those records.
|
|
99
134
|
7. **Continue** — move to the next requested target. If a target fails or is parked, stop with the journal evidence rather than silently skipping it.
|
|
@@ -101,12 +136,13 @@ After sending, **confirm delivery** by reading the target pane and verifying the
|
|
|
101
136
|
## Host-owned daemon and detached beats
|
|
102
137
|
|
|
103
138
|
Launch the daemon DETACHED, with no pane of its own: one `tickmarkr run` or `tickmarkr resume <runId>`
|
|
104
|
-
process in its own session, its stdout and stderr appended to `<state-dir>/daemon.log`, and
|
|
105
|
-
ORCH's recorded address as its board anchor, so the daemon self-places its one
|
|
106
|
-
ORCH in the ORCH tab
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
139
|
+
process in its own session, its stdout and stderr appended to `<state-dir>/daemon.log`, and on
|
|
140
|
+
herdr or Orca the ORCH's recorded address as its board anchor, so the daemon self-places its one
|
|
141
|
+
board beside the ORCH in the ORCH tab; with neither host it carries no address and places no board.
|
|
142
|
+
Never launch it in a visible split, pane or tab, as an agent harness background task, or tied to
|
|
143
|
+
an agent session: the launching shell may end, and the daemon keeps running and logging. The
|
|
144
|
+
detach wrapper is `node`, which tickmarkr already requires — no private script, no extra visible
|
|
145
|
+
daemon pane and no CLI log flag:
|
|
110
146
|
|
|
111
147
|
```bash
|
|
112
148
|
# On Orca: <ORCH handle> is the ORCH terminal handle
|
|
@@ -115,19 +151,27 @@ cd <repo> && ORCA_TERMINAL_HANDLE="<ORCH handle>" node -e "require('child_proces
|
|
|
115
151
|
# On herdr: <ORCH pane id> is the ORCH pane id
|
|
116
152
|
cd <repo> && HERDR_PANE_ID="<ORCH pane id>" node -e "require('child_process').spawn(process.argv[1], process.argv.slice(2), { detached: true, stdio: 'inherit' }).unref()" tickmarkr run >> <state-dir>/daemon.log 2>&1 < /dev/null
|
|
117
153
|
cd <repo> && HERDR_PANE_ID="<ORCH pane id>" node -e "require('child_process').spawn(process.argv[1], process.argv.slice(2), { detached: true, stdio: 'inherit' }).unref()" tickmarkr resume <runId> >> <state-dir>/daemon.log 2>&1 < /dev/null
|
|
154
|
+
# On a plain host (neither herdr nor Orca): the same detach with no address
|
|
155
|
+
cd <repo> && node -e "require('child_process').spawn(process.argv[1], process.argv.slice(2), { detached: true, stdio: 'inherit' }).unref()" tickmarkr run >> <state-dir>/daemon.log 2>&1 < /dev/null
|
|
156
|
+
cd <repo> && node -e "require('child_process').spawn(process.argv[1], process.argv.slice(2), { detached: true, stdio: 'inherit' }).unref()" tickmarkr resume <runId> >> <state-dir>/daemon.log 2>&1 < /dev/null
|
|
118
157
|
```
|
|
119
158
|
|
|
120
159
|
- **On Orca (`TERM_PROGRAM=Orca` and non-empty `ORCA_TERMINAL_HANDLE`)**: run the
|
|
121
160
|
`ORCA_TERMINAL_HANDLE` lines; `<ORCH handle>` is the ORCH's own `$ORCA_TERMINAL_HANDLE`.
|
|
122
161
|
- **On herdr (`HERDR_ENV=1`)**: run the `HERDR_PANE_ID` lines; `<ORCH pane id>` is the ORCH's own
|
|
123
162
|
`$HERDR_PANE_ID`.
|
|
163
|
+
- With neither host, run the two lines that carry no address
|
|
164
|
+
([On a plain host (neither herdr nor Orca)](#on-a-plain-host-neither-herdr-nor-orca)).
|
|
124
165
|
|
|
125
|
-
After
|
|
166
|
+
After any launch, read this repository's lock pid from `<state-dir>/graph.lock` and confirm it:
|
|
126
167
|
`kill -0 <pid>` succeeds, `ps -o pgid= -p <pid>` prints that same pid (its own session group;
|
|
127
168
|
ppid 1 is never proof on its own), walk its ppid chain and verify no agent session is an ancestor,
|
|
128
169
|
and read `<state-dir>/daemon.log`. No live holder means the launch failed: read the log, fix the
|
|
129
170
|
cause and run the same line again — never a second daemon beside a live holder, and never a
|
|
130
|
-
visible split to watch it
|
|
171
|
+
visible split to watch it.
|
|
172
|
+
|
|
173
|
+
- **On herdr (`HERDR_ENV=1`)**: the daemon-placed board is the live surface.
|
|
174
|
+
- **On Orca (`TERM_PROGRAM=Orca` and non-empty `ORCA_TERMINAL_HANDLE`)**: the daemon-placed board is the live surface.
|
|
131
175
|
|
|
132
176
|
Detached beats are product-owned, one per (tier, seat), from the repository root, through the
|
|
133
177
|
shipped lifecycle verbs — never a hand-rolled setsid plus nohup wrapper, pidfile or shell loop:
|
|
@@ -9,18 +9,50 @@ Use this for any spec that `tickmarkr compile` accepts. It is SDD-agnostic: use
|
|
|
9
9
|
|
|
10
10
|
## Two-tier by default — role check before the loop
|
|
11
11
|
|
|
12
|
-
When working in a multi-agent terminal environment, decide your role before starting:
|
|
12
|
+
When working in a multi-agent terminal environment (herdr or Orca), decide your role before starting:
|
|
13
13
|
|
|
14
14
|
- **Orchestrator:** your session was started to execute the mission. Rename your own tab/pane `ORCH · <version>` (short labels: ≤20 chars, `ROLE · token`) and run the loop below.
|
|
15
15
|
- **Supervisor with a live orchestrator:** do not start a second run. Relay the mission to the existing orchestrator with a [verified handoff](#verified-handoffs-agent-to-agent-messaging), then supervise it as OVERSEER.
|
|
16
16
|
- **Primary session without an orchestrator:** rename your own tab `OVERSEER · <version>` and your agent `overseer`, spawn one child orchestration session with your host's launch form, label its tab `ORCH · <version>` and name its agent, give it the mission and these rules verbatim, then supervise it. Do not drive a duplicate single-tier run yourself. Before spawning, confirm any PREVIOUS orchestrator has [stood down](#stand-down-mission-end-and-retirement) and close its tab.
|
|
17
|
-
- **
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
- **On herdr (`HERDR_ENV=1`)**: **spawning on current herdr is two-step** — the one-shot `agent start --cwd/--tab/--no-focus` form was removed in the herdr CLI redesign and now fails with `unknown option` (OBS-138). First create the pane: `herdr tab create --workspace <ws> --cwd <repo> --label "ORCH · <version>"` (tab create does not steal focus unless `--focus` is passed; parse `result.root_pane.pane_id` from its JSON), then start the agent in it:
|
|
18
|
+
- **Claude Code:** `herdr agent start orchestrator --kind claude --pane <root-pane-id> -- --permission-mode bypassPermissions`
|
|
19
|
+
- **Codex:** `herdr agent start orchestrator --kind codex --pane <root-pane-id> -- --dangerously-bypass-approvals-and-sandbox` — the unsandboxed flag is REQUIRED, not optional: codex's `workspace-write` sandbox keeps `.git` refs read-only, so a sandboxed orchestrator's `tickmarkr run` dies at integration-branch creation (`git worktree add` cannot lock the ref). Do not downgrade this flag; the herdr pane and repo scope are the containment.
|
|
20
|
+
- **Auxiliary seats run as the CLI's interactive TUI in their visible pane — never headless** (`claude -p` / `codex exec`): headless buffers output until exit so the pane renders idle for the entire run, is blind to SessionStart hook errors (a broken and a fixed hook both return green), and gives a stall watcher no midpoint — silent-time equals lifetime. Headless is for exit-code probes only (a quota check that wants `rc`), never for work anyone must watch.
|
|
21
|
+
- **On Orca (`TERM_PROGRAM=Orca` and non-empty `ORCA_TERMINAL_HANDLE`)**: spawn it with `orca terminal create --worktree path:<repo> --title "ORCH · <version>" --command "<agent-cmd>" --json` and parse `result.terminal.handle` from the create receipt. **Auxiliary seats run as the CLI's interactive TUI in their visible terminal — never headless**, for the reasons the herdr branch gives.
|
|
20
22
|
- **Auxiliary agents you spawn (consultants, reviewers, scouts) follow the same forms.** Never launch a claude session in plan mode or default permission mode for autonomous work — both stall on per-command approval prompts nobody is watching; claude is always `--permission-mode bypassPermissions` (tickmarkr's own adapter uses exactly this for workers, judges, and consults). A read-only codex consultant may use `--sandbox read-only`; any codex session that must touch git needs the unsandboxed flag above.
|
|
21
|
-
- **Auxiliary seats run as the CLI's interactive TUI in their visible pane — never headless** (`claude -p` / `codex exec`): headless buffers output until exit so the pane renders idle for the entire run, is blind to SessionStart hook errors (a broken and a fixed hook both return green), and gives a stall watcher no midpoint — silent-time equals lifetime. Headless is for exit-code probes only (a quota check that wants `rc`), never for work anyone must watch.
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
With neither herdr nor Orca there is no role to decide and no seat to spawn: follow [On a plain host (neither herdr nor Orca)](#on-a-plain-host-neither-herdr-nor-orca) and run the loop directly, single-tier.
|
|
25
|
+
|
|
26
|
+
## On a plain host (neither herdr nor Orca)
|
|
27
|
+
|
|
28
|
+
Neither `HERDR_ENV=1` nor the Orca markers are set: the Claude Desktop Code tab, a plain terminal, any
|
|
29
|
+
agent session that owns no panes (queue row 192; D-2102). The role check above does not apply.
|
|
30
|
+
|
|
31
|
+
- **This session runs SINGLE-TIER as the orchestrator.** There are no seats, no pane briefs, no tab
|
|
32
|
+
canon and no board: run every step of [the loop](#the-loop) yourself and skip every On herdr and On
|
|
33
|
+
Orca scope.
|
|
34
|
+
- **An empty mission is asked for, never assumed.** With no spec named, ask the operator what to run
|
|
35
|
+
end-to-end before compiling anything; there is no other tier to relay it to.
|
|
36
|
+
- **Run and resume launch through the anchor-free lines** of the
|
|
37
|
+
[detached launch](#host-owned-daemon-and-detached-beats): the same `node` detach with no address, one
|
|
38
|
+
line for `tickmarkr run` and one for `tickmarkr resume <runId>`. The daemon places no board, so a
|
|
39
|
+
missing board is never a fault; confirm the launch from the lock pid as that section says.
|
|
40
|
+
- **Run-end and parks are watched through the host's background wait**, never a foreground wait past
|
|
41
|
+
the host's ten-minute tool cap: the cap kills that wait, ends the turn and leaves the run unwatched.
|
|
42
|
+
Start the wait as a background task whose exit wakes this session, on journal lines after a baseline
|
|
43
|
+
taken at arm time and on the lock holder's death:
|
|
44
|
+
`n=$(wc -l < <journal>); until tail -n +$((n + 1)) <journal> | grep -qE '"event":"(run-end|task-human|task-failed|consult-verdict)"' || ! kill -0 <pid>; do sleep 20; done`
|
|
45
|
+
(`<journal>` is `<state-dir>/runs/<runId>/journal.jsonl`, `<pid>` the lock pid). On every wake read
|
|
46
|
+
CURRENT `tickmarkr status <runId>` first, then re-arm.
|
|
47
|
+
- **The operator's view is `tickmarkr status <runId>`**, plus its live `status --watch --plain` form,
|
|
48
|
+
`tickmarkr status <runId> --watch --plain`, in a read-only Terminal tab beside this session.
|
|
49
|
+
- **Reviews and judges run headless.** The subprocess driver runs every worker, judge and review as a
|
|
50
|
+
headless CLI call with no pane to watch: read their verdicts from the journal, the gate evidence and
|
|
51
|
+
`tickmarkr status <runId>`, never from a screen.
|
|
52
|
+
- **Sessions hand off through the host's cross-session message tool**, confirmed by the peer's reply:
|
|
53
|
+
there is no composer to read back, so a message no peer answered is not a handoff.
|
|
54
|
+
- **Keep a permission mode that never stalls per command** for the whole run (for example
|
|
55
|
+
`bypassPermissions`): nobody answers a per-command approval prompt in an unattended session.
|
|
24
56
|
|
|
25
57
|
## Invariants
|
|
26
58
|
|
|
@@ -65,14 +97,15 @@ concurrently* — so a machine-wide check answers a question nobody asked and bl
|
|
|
65
97
|
|
|
66
98
|
## Verified handoffs (agent-to-agent messaging)
|
|
67
99
|
|
|
68
|
-
|
|
100
|
+
Never report "briefed" or "relayed" without the confirmation your host gives:
|
|
69
101
|
|
|
70
|
-
Use one of:
|
|
102
|
+
- **On herdr (`HERDR_ENV=1`)**: when relaying missions between agents in a multi-agent terminal, **never use bare send-text** (`herdr agent send` / pane send-text) — it writes text without pressing Enter, so handoffs sit unsubmitted (OBS-39). Use one of:
|
|
103
|
+
- `herdr pane run <pane> "<message>"` — text plus Enter in the target shell
|
|
104
|
+
- `herdr notification show "<message>"` — OS-level delivery for the operator
|
|
71
105
|
|
|
72
|
-
|
|
73
|
-
- `
|
|
74
|
-
|
|
75
|
-
After sending, **confirm delivery** by reading the target pane and verifying the message landed (input empty, agent status `working`, or notification acknowledged). Never report "briefed" or "relayed" without read-back confirmation.
|
|
106
|
+
After sending, **confirm delivery** by reading the target pane and verifying the message landed (input empty, agent status `working`, or notification acknowledged). Never report "briefed" or "relayed" without read-back confirmation.
|
|
107
|
+
- **On Orca (`TERM_PROGRAM=Orca` and non-empty `ORCA_TERMINAL_HANDLE`)**: send with `orca terminal send --terminal <handle> --text "<message>" --enter --wait-submit 15 --json` and treat it as delivered only when `result.send.prompt.stages` carries a `turn_started` stage — `accepted: true` proves input acceptance, not a started turn.
|
|
108
|
+
- With neither host, hand off through the host's cross-session message tool, confirmed by the peer's reply ([On a plain host (neither herdr nor Orca)](#on-a-plain-host-neither-herdr-nor-orca)).
|
|
76
109
|
|
|
77
110
|
## Dedicated consultant tab rule
|
|
78
111
|
|
|
@@ -88,19 +121,22 @@ When spawning consultants (agents gathering synthesis input for decisions like S
|
|
|
88
121
|
1. **Prepare** — start from the requested spec. Run the [binary preflight](#binary-preflight-before-compile-or-run). Check `git status`, confirm no tickmarkr run is active, and work from a non-main branch.
|
|
89
122
|
2. **Compile** — run `tickmarkr compile <spec>`. Correct compilation errors in the spec, never in the generated graph.
|
|
90
123
|
3. **Plan** — run `tickmarkr plan`. Review the routing table, capability-floor warnings, and every human gate, including work that each gate blocks.
|
|
91
|
-
4. **Run** — launch `tickmarkr run` using the [detached launch](#host-owned-daemon-and-detached-beats), and start detached beats with their run-end stop items. A watch ending the seat's turn is no watch: keep a **blocking journal consumer** alive for the run's terminal events
|
|
124
|
+
4. **Run** — launch `tickmarkr run` using the [detached launch](#host-owned-daemon-and-detached-beats), and start detached beats with their run-end stop items. A watch ending the seat's turn is no watch: keep a **blocking journal consumer** alive for the run's terminal events, and never rely on a `Monitor`-only wake. Watch the run journal rather than polling agents: the consumer takes a line baseline at arm time, then wakes ONCE on `run-end`, `task-human`, `task-failed` or `consult-verdict`. A run-end record is history, never green; the debt clause is yours — read CURRENT `tickmarkr status <runId>` (step 5). Re-arm after every wake. ⛔ Never `tail -F | grep -m1` (run-end is the journal's last line, so tail never notices the broken pipe and the watcher hangs forever) and never a pane-level done wait (it fires on every agent turn end, not mission end). ⚠ A bare whole-file `grep -q '"event":"run-end"'` is the trap the watcher exists to avoid: on a resume it matches the PREVIOUS run's run-end and returns instantly, so a re-armed watcher reads as coverage that does not exist. Resolve blocked interactions in the agent session; do not turn them into proxy questions. The consumer is host-specific; with neither host it is the background wait of [On a plain host (neither herdr nor Orca)](#on-a-plain-host-neither-herdr-nor-orca).
|
|
125
|
+
- **On herdr (`HERDR_ENV=1`)**: the consumer is the shipped watcher — `.claude/skills/tickmarkr-overseer/scripts/watch-journal.sh <state-dir>/runs 20 28800`, which grades the run-end summary's execution clauses for you, `EXECUTION COMPLETE` or `NOT GREEN`, never green — or a foreground `until grep` on the run's terminal events; ensure it is re-armed at most every twenty minutes.
|
|
126
|
+
- **On Orca (`TERM_PROGRAM=Orca` and non-empty `ORCA_TERMINAL_HANDLE`)**: the consumer is that same shipped journal watcher or a foreground `until grep` on the run's terminal events; ensure it is re-armed at most every twenty minutes.
|
|
92
127
|
5. **Verify and consolidate** — accept only a green run. A run is green when the run-end event exists in the journal, the tip verify is not "failed", the summary's `failed`, `human`, `blocked` and `pending` buckets are all empty, and CURRENT `tickmarkr status <runId>` reads its owed checks outstanding empty AND known (`outstanding 0`) — a run with a parked task is partial, not green. Empty execution buckets alone are not green either (D-660): every bucket empty and the tip passed, but an operator waived one review, leaves one accepted-risk review check owed — status reads `outstanding 1 (T7 review)` and `run`/`resume` still exit 0 on execution alone, so the run is execution complete, not green. It turns green only when a `tickmarkr verify --record <runId>` discharge moves CURRENT status to `outstanding 0`, including a discharge landing after run-end — the historical run-end record keeps the old count, so never read debt from it; `outstanding unknown` is never green. Tickmarkr consolidates accepted task work on `tickmarkr/<runId>`; it never signs off to the main branch. A human may later merge that integration branch through the repository's normal release process.
|
|
93
128
|
6. **Record** — `tickmarkr report <runId> --md` prints Markdown to stdout. Redirect it explicitly beside the source spec (for example `tickmarkr report <runId> --md > feature.record.md`) and commit the execution record when the repository tracks those records. Then [stand down](#stand-down-mission-end-and-retirement).
|
|
94
129
|
|
|
95
130
|
## Host-owned daemon and detached beats
|
|
96
131
|
|
|
97
132
|
Launch the daemon DETACHED, with no pane of its own: one `tickmarkr run` or `tickmarkr resume <runId>`
|
|
98
|
-
process in its own session, its stdout and stderr appended to `<state-dir>/daemon.log`, and
|
|
99
|
-
ORCH's recorded address as its board anchor, so the daemon self-places its one
|
|
100
|
-
ORCH in the ORCH tab
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
133
|
+
process in its own session, its stdout and stderr appended to `<state-dir>/daemon.log`, and on
|
|
134
|
+
herdr or Orca the ORCH's recorded address as its board anchor, so the daemon self-places its one
|
|
135
|
+
board beside the ORCH in the ORCH tab; with neither host it carries no address and places no board.
|
|
136
|
+
Never launch it in a visible split, pane or tab, as an agent harness background task, or tied to
|
|
137
|
+
an agent session: the launching shell may end, and the daemon keeps running and logging. The
|
|
138
|
+
detach wrapper is `node`, which tickmarkr already requires — no private script, no extra visible
|
|
139
|
+
daemon pane and no CLI log flag:
|
|
104
140
|
|
|
105
141
|
```bash
|
|
106
142
|
# On Orca: <ORCH handle> is the ORCH terminal handle
|
|
@@ -109,19 +145,27 @@ cd <repo> && ORCA_TERMINAL_HANDLE="<ORCH handle>" node -e "require('child_proces
|
|
|
109
145
|
# On herdr: <ORCH pane id> is the ORCH pane id
|
|
110
146
|
cd <repo> && HERDR_PANE_ID="<ORCH pane id>" node -e "require('child_process').spawn(process.argv[1], process.argv.slice(2), { detached: true, stdio: 'inherit' }).unref()" tickmarkr run >> <state-dir>/daemon.log 2>&1 < /dev/null
|
|
111
147
|
cd <repo> && HERDR_PANE_ID="<ORCH pane id>" node -e "require('child_process').spawn(process.argv[1], process.argv.slice(2), { detached: true, stdio: 'inherit' }).unref()" tickmarkr resume <runId> >> <state-dir>/daemon.log 2>&1 < /dev/null
|
|
148
|
+
# On a plain host (neither herdr nor Orca): the same detach with no address
|
|
149
|
+
cd <repo> && node -e "require('child_process').spawn(process.argv[1], process.argv.slice(2), { detached: true, stdio: 'inherit' }).unref()" tickmarkr run >> <state-dir>/daemon.log 2>&1 < /dev/null
|
|
150
|
+
cd <repo> && node -e "require('child_process').spawn(process.argv[1], process.argv.slice(2), { detached: true, stdio: 'inherit' }).unref()" tickmarkr resume <runId> >> <state-dir>/daemon.log 2>&1 < /dev/null
|
|
112
151
|
```
|
|
113
152
|
|
|
114
153
|
- **On Orca (`TERM_PROGRAM=Orca` and non-empty `ORCA_TERMINAL_HANDLE`)**: run the
|
|
115
154
|
`ORCA_TERMINAL_HANDLE` lines; `<ORCH handle>` is the ORCH's own `$ORCA_TERMINAL_HANDLE`.
|
|
116
155
|
- **On herdr (`HERDR_ENV=1`)**: run the `HERDR_PANE_ID` lines; `<ORCH pane id>` is the ORCH's own
|
|
117
156
|
`$HERDR_PANE_ID`.
|
|
157
|
+
- With neither host, run the two lines that carry no address
|
|
158
|
+
([On a plain host (neither herdr nor Orca)](#on-a-plain-host-neither-herdr-nor-orca)).
|
|
118
159
|
|
|
119
|
-
After
|
|
160
|
+
After any launch, read this repository's lock pid from `<state-dir>/graph.lock` and confirm it:
|
|
120
161
|
`kill -0 <pid>` succeeds, `ps -o pgid= -p <pid>` prints that same pid (its own session group;
|
|
121
162
|
ppid 1 is never proof on its own), walk its ppid chain and verify no agent session is an ancestor,
|
|
122
163
|
and read `<state-dir>/daemon.log`. No live holder means the launch failed: read the log, fix the
|
|
123
164
|
cause and run the same line again — never a second daemon beside a live holder, and never a
|
|
124
|
-
visible split to watch it
|
|
165
|
+
visible split to watch it.
|
|
166
|
+
|
|
167
|
+
- **On herdr (`HERDR_ENV=1`)**: the daemon-placed board is the live surface.
|
|
168
|
+
- **On Orca (`TERM_PROGRAM=Orca` and non-empty `ORCA_TERMINAL_HANDLE`)**: the daemon-placed board is the live surface.
|
|
125
169
|
|
|
126
170
|
Detached beats are product-owned, one per (tier, seat), from the repository root, through the
|
|
127
171
|
shipped lifecycle verbs — never a hand-rolled setsid plus nohup wrapper, pidfile or shell loop:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: tickmarkr-overseer
|
|
3
|
-
description: "Use when the user asks to oversee/supervise/babysit an autonomous tickmarkr run in a Herdr workspace
|
|
3
|
+
description: "Use when the user asks to oversee/supervise/babysit an autonomous tickmarkr run in a Herdr workspace, an Orca session or a plain agent session (e.g. '/tickmarkr-overseer run the milestone', 'supervise this tickmarkr run', 'babysit this pipeline'). Two-tier on herdr (HERDR_ENV=1) or Orca (TERM_PROGRAM=Orca and non-empty ORCA_TERMINAL_HANDLE); single-tier as the orchestrator on a plain host with neither. The skill argument is the mission (what to run end-to-end)."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Overseer (tickmarkr)
|
|
@@ -10,7 +10,7 @@ hierarchy of VISIBLE agents (you → orchestrator → tickmarkr's own worker fle
|
|
|
10
10
|
to the user with evidence.
|
|
11
11
|
|
|
12
12
|
The mission is the skill argument. If empty, ask the user what to run end-to-end before doing anything else.
|
|
13
|
-
Requires a supported host: herdr (`HERDR_ENV=1`) or Orca (`TERM_PROGRAM=Orca` and non-empty `ORCA_TERMINAL_HANDLE`); if neither host is detected,
|
|
13
|
+
Requires a supported host: herdr (`HERDR_ENV=1`) or Orca (`TERM_PROGRAM=Orca` and non-empty `ORCA_TERMINAL_HANDLE`) for that hierarchy; if neither host is detected, do not stop: this is a plain host — follow [On a plain host (neither herdr nor Orca)](#on-a-plain-host-neither-herdr-nor-orca) and run single-tier as the orchestrator.
|
|
14
14
|
|
|
15
15
|
Use the canonical loop skill's [cockpit, parked decisions and printed twins](../tickmarkr-loop/SKILL.md#cockpit-parked-decisions-and-printed-twins)
|
|
16
16
|
when reading or relaying operator evidence. Delivered views are **1 Home, 4 Run, 5 Evidence**;
|
|
@@ -69,6 +69,41 @@ the answer took session-file archaeology). The flip from the engine (P89, journa
|
|
|
69
69
|
GSD legs (P92) had been RULED NOWHERE — no ledger entry decides it — and then propagated for six phases
|
|
70
70
|
through brief lineage. **An executor choice nobody made is still an executor choice, and it compounds.**
|
|
71
71
|
|
|
72
|
+
## On a plain host (neither herdr nor Orca)
|
|
73
|
+
|
|
74
|
+
Neither `HERDR_ENV=1` nor the Orca markers are set: the Claude Desktop Code tab, a plain terminal, any
|
|
75
|
+
agent session that owns no panes (queue row 192; D-2102). There is no hierarchy to build, so this scope
|
|
76
|
+
replaces the two-tier setup.
|
|
77
|
+
|
|
78
|
+
- **This session runs SINGLE-TIER as the orchestrator.** The OVERSEER's rulings and the ORCHESTRATOR's
|
|
79
|
+
loop (`tickmarkr compile` → `plan` → `run` → `report`) are this one session: there are no seats, no
|
|
80
|
+
pane briefs, no tab canon and no board. Skip Setup steps 1–4, the seat-spawn recipes, the watcher
|
|
81
|
+
instruments and every On herdr and On Orca scope; read
|
|
82
|
+
[what the ORCHESTRATOR does](#what-the-orchestrator-does-and-what-you-require-of-it) as your own
|
|
83
|
+
duties and keep every ruling and evidence law.
|
|
84
|
+
- **An empty mission is asked for, never assumed.** With an empty skill argument, ask the operator what
|
|
85
|
+
to run end-to-end before doing anything else; there is no other tier to relay it to.
|
|
86
|
+
- **Run and resume launch through the anchor-free lines** of the
|
|
87
|
+
[detached launch](#host-owned-daemon-and-detached-beats): the same `node` detach with no address, one
|
|
88
|
+
line for `tickmarkr run` and one for `tickmarkr resume <runId>`. The daemon places no board, so a
|
|
89
|
+
missing board is never a fault; confirm the launch from the lock pid as that section says.
|
|
90
|
+
- **Run-end and parks are watched through the host's background wait**, never a foreground wait past
|
|
91
|
+
the host's ten-minute tool cap: the cap kills that wait, ends the turn and leaves the run unwatched.
|
|
92
|
+
Start the wait as a background task whose exit wakes this session, on journal lines after a baseline
|
|
93
|
+
taken at arm time and on the lock holder's death:
|
|
94
|
+
`n=$(wc -l < <journal>); until tail -n +$((n + 1)) <journal> | grep -qE '"event":"(run-end|task-human|task-failed|consult-verdict)"' || ! kill -0 <pid>; do sleep 20; done`
|
|
95
|
+
(`<journal>` is `<state-dir>/runs/<runId>/journal.jsonl`, `<pid>` the lock pid). On every wake read
|
|
96
|
+
CURRENT `tickmarkr status <runId>` first, then re-arm.
|
|
97
|
+
- **The operator's view is `tickmarkr status <runId>`**, plus its live `status --watch --plain` form,
|
|
98
|
+
`tickmarkr status <runId> --watch --plain`, in a read-only Terminal tab beside this session.
|
|
99
|
+
- **Reviews and judges run headless.** The subprocess driver runs every worker, judge and review as a
|
|
100
|
+
headless CLI call with no pane to watch: read their verdicts from the journal, the gate evidence and
|
|
101
|
+
`tickmarkr status <runId>`, never from a screen. No seat transport rule applies: there are no seats.
|
|
102
|
+
- **Sessions hand off through the host's cross-session message tool**, confirmed by the peer's reply:
|
|
103
|
+
there is no composer to read back, so a message no peer answered is not a handoff.
|
|
104
|
+
- **Keep a permission mode that never stalls per command** for the whole run (for example
|
|
105
|
+
`bypassPermissions`): nobody answers a per-command approval prompt in an unattended session.
|
|
106
|
+
|
|
72
107
|
## Setup
|
|
73
108
|
|
|
74
109
|
0. **Adopt before you build.** If this workspace already has a supervision hierarchy — an
|
|
@@ -333,12 +368,13 @@ For Leg-2 (both hosts), a Codex reviewer under `workspace-write` must be briefed
|
|
|
333
368
|
## Host-owned daemon and detached beats
|
|
334
369
|
|
|
335
370
|
Launch the daemon DETACHED, with no pane of its own: one `tickmarkr run` or `tickmarkr resume <runId>`
|
|
336
|
-
process in its own session, its stdout and stderr appended to `<state-dir>/daemon.log`, and
|
|
337
|
-
ORCH's recorded address as its board anchor, so the daemon self-places its one
|
|
338
|
-
ORCH in the ORCH tab
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
371
|
+
process in its own session, its stdout and stderr appended to `<state-dir>/daemon.log`, and on
|
|
372
|
+
herdr or Orca the ORCH's recorded address as its board anchor, so the daemon self-places its one
|
|
373
|
+
board beside the ORCH in the ORCH tab; with neither host it carries no address and places no board.
|
|
374
|
+
Never launch it in a visible split, pane or tab, as an agent harness background task, or tied to
|
|
375
|
+
an agent session: the launching shell may end, and the daemon keeps running and logging. The
|
|
376
|
+
detach wrapper is `node`, which tickmarkr already requires — no private script, no extra visible
|
|
377
|
+
daemon pane and no CLI log flag:
|
|
342
378
|
|
|
343
379
|
```bash
|
|
344
380
|
# On Orca: <ORCH handle> is the ORCH terminal handle
|
|
@@ -347,6 +383,9 @@ cd <repo> && ORCA_TERMINAL_HANDLE="<ORCH handle>" node -e "require('child_proces
|
|
|
347
383
|
# On herdr: <ORCH pane id> is the ORCH pane id
|
|
348
384
|
cd <repo> && HERDR_PANE_ID="<ORCH pane id>" node -e "require('child_process').spawn(process.argv[1], process.argv.slice(2), { detached: true, stdio: 'inherit' }).unref()" tickmarkr run >> <state-dir>/daemon.log 2>&1 < /dev/null
|
|
349
385
|
cd <repo> && HERDR_PANE_ID="<ORCH pane id>" node -e "require('child_process').spawn(process.argv[1], process.argv.slice(2), { detached: true, stdio: 'inherit' }).unref()" tickmarkr resume <runId> >> <state-dir>/daemon.log 2>&1 < /dev/null
|
|
386
|
+
# On a plain host (neither herdr nor Orca): the same detach with no address
|
|
387
|
+
cd <repo> && node -e "require('child_process').spawn(process.argv[1], process.argv.slice(2), { detached: true, stdio: 'inherit' }).unref()" tickmarkr run >> <state-dir>/daemon.log 2>&1 < /dev/null
|
|
388
|
+
cd <repo> && node -e "require('child_process').spawn(process.argv[1], process.argv.slice(2), { detached: true, stdio: 'inherit' }).unref()" tickmarkr resume <runId> >> <state-dir>/daemon.log 2>&1 < /dev/null
|
|
350
389
|
```
|
|
351
390
|
|
|
352
391
|
- **On Orca (`TERM_PROGRAM=Orca` and non-empty `ORCA_TERMINAL_HANDLE`)**: run the
|
|
@@ -357,13 +396,18 @@ cd <repo> && HERDR_PANE_ID="<ORCH pane id>" node -e "require('child_process').sp
|
|
|
357
396
|
- **On herdr (`HERDR_ENV=1`)**: run the `HERDR_PANE_ID` lines; `<ORCH pane id>` is the ORCH's own
|
|
358
397
|
`$HERDR_PANE_ID`. When the OVERSEER launches the fallback, substitute the ORCH pane id recorded
|
|
359
398
|
at seat creation, never the OVERSEER's pane.
|
|
399
|
+
- With neither host, run the two lines that carry no address
|
|
400
|
+
([On a plain host (neither herdr nor Orca)](#on-a-plain-host-neither-herdr-nor-orca)).
|
|
360
401
|
|
|
361
|
-
After
|
|
402
|
+
After any launch, read this repository's lock pid from `<state-dir>/graph.lock` and confirm it:
|
|
362
403
|
`kill -0 <pid>` succeeds, `ps -o pgid= -p <pid>` prints that same pid (its own session group;
|
|
363
404
|
ppid 1 is never proof on its own), walk its ppid chain and verify no agent session is an ancestor,
|
|
364
405
|
and read `<state-dir>/daemon.log`. No live holder means the launch failed: read the log, fix the
|
|
365
406
|
cause and run the same line again — never a second daemon beside a live holder, and never a
|
|
366
|
-
visible split to watch it
|
|
407
|
+
visible split to watch it.
|
|
408
|
+
|
|
409
|
+
- **On herdr (`HERDR_ENV=1`)**: the daemon-placed board is the live surface.
|
|
410
|
+
- **On Orca (`TERM_PROGRAM=Orca` and non-empty `ORCA_TERMINAL_HANDLE`)**: the daemon-placed board is the live surface.
|
|
367
411
|
|
|
368
412
|
Detached beats are product-owned, one per (tier, seat), from the repository root, through the
|
|
369
413
|
shipped lifecycle verbs — never a hand-rolled setsid plus nohup wrapper, pidfile or shell loop:
|
|
@@ -521,26 +565,34 @@ journal tail to decide what happens next, or sweeping orphans — you have taken
|
|
|
521
565
|
|
|
522
566
|
### What the ORCHESTRATOR does, and what you require of it
|
|
523
567
|
|
|
524
|
-
- **The live surface arrives with the run.** `tickmarkr run` is stdout-silent until run-end by design
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
568
|
+
- **The live surface arrives with the run.** `tickmarkr run` is stdout-silent until run-end by design.
|
|
569
|
+
With neither host there is no board: the plain-host scope's status view is the live surface.
|
|
570
|
+
- **On herdr (`HERDR_ENV=1`)**: its daemon self-places one shipped `role: "watch"` board BESIDE the
|
|
571
|
+
supervising seat — the right half of the tab, narration on the left — and pins that board to the
|
|
572
|
+
daemon's run id. **Look for the matching daemon-placed pane.** If it is absent, treat that as a
|
|
573
|
+
daemon/run liveness fault and use the normal recovery path; never hand-place, hand-roll, or launch a
|
|
574
|
+
replacement live surface. A board the daemon could not stack is not silently re-arranged: the split
|
|
575
|
+
is closed and the run continues BOARDLESS, so an absent board means the placement failed, never that
|
|
576
|
+
it landed somewhere else in the tab.
|
|
577
|
+
- **On Orca (`TERM_PROGRAM=Orca` and non-empty `ORCA_TERMINAL_HANDLE`)**: the same board, placed and
|
|
578
|
+
pinned the same way beside the ORCH. **Look for the matching daemon-placed pane.** If it is absent,
|
|
579
|
+
treat that as a daemon/run liveness fault and use the normal recovery path; never hand-place,
|
|
580
|
+
hand-roll, or launch a replacement live surface.
|
|
531
581
|
- **The journal is the source of truth**, not panes. Watchers go on `run-end` / `task-human` /
|
|
532
582
|
`task-failed` / `consult-verdict`; never sleep-poll inside an agent turn. **Never key a watcher on an
|
|
533
583
|
agent's `done`** — that is turn end and fires the moment a seat finishes acknowledging you.
|
|
534
584
|
A watch ending the seat's turn is no watch: keep a **blocking journal consumer** alive for those terminal
|
|
535
|
-
events
|
|
536
|
-
|
|
537
|
-
- **On herdr (`HERDR_ENV=1`)**:
|
|
585
|
+
events, and never rely on a `Monitor`-only wake. The consumer is host-specific; with neither host it is
|
|
586
|
+
the plain-host scope's background wait.
|
|
587
|
+
- **On herdr (`HERDR_ENV=1`)**: the consumer is the shipped watcher below, or a foreground `until grep`
|
|
588
|
+
on the run's terminal events; ensure it is re-armed at most every twenty minutes. Use the shipped
|
|
589
|
+
journal instruments:
|
|
538
590
|
**All four are covered by one shipped instrument** — `scripts/watch-journal.sh <runs-dir> [poll] [cap]
|
|
539
591
|
[events-csv]` — which arms on a line baseline, wakes once, and grades a `run-end`'s execution clauses —
|
|
540
592
|
`EXECUTION COMPLETE` or `NOT GREEN`, never green: green is CURRENT `tickmarkr status <runId>` at
|
|
541
593
|
`outstanding 0`. `scripts/watch-parks.sh` stays the park-specific wake for THIS seat (it counts parks and speaks
|
|
542
594
|
about rulings); the two overlap on `task-human` deliberately, and arming both is coverage, not a bug.
|
|
543
|
-
- **On Orca (`TERM_PROGRAM=Orca` and non-empty `ORCA_TERMINAL_HANDLE`)**: Arm a file/journal consumer for the same terminal events and inspect the seat with `orca terminal read --terminal <handle> --screen --json`; re-arm after every wake.
|
|
595
|
+
- **On Orca (`TERM_PROGRAM=Orca` and non-empty `ORCA_TERMINAL_HANDLE`)**: Arm a file/journal consumer for the same terminal events, or a foreground `until grep` on them, and ensure it is re-armed at most every twenty minutes; inspect the seat with `orca terminal read --terminal <handle> --screen --json`; re-arm after every wake.
|
|
544
596
|
- **Daemon liveness ≠ journal activity.** A dead daemon emits no events, so journal watchers sleep through
|
|
545
597
|
its death. Liveness comes from the lock's OWN pid (`kill -0`), never a command-name grep. Recovery is
|
|
546
598
|
`tickmarkr resume <runId>` — **the orchestrator's command, not yours** — and note that resume REPLAYS the
|
|
@@ -777,10 +829,10 @@ an overseer ran nine hours at 86% unable to read its own number; a context watch
|
|
|
777
829
|
when the run's own status text pushed the percentage off the statusline; and an orchestrator went
|
|
778
830
|
**366k → 970k of 1M between two checks** while its ACT wake sat unread in a detached log.
|
|
779
831
|
|
|
780
|
-
**On Orca (`TERM_PROGRAM=Orca` and non-empty `ORCA_TERMINAL_HANDLE`)**, use the same mutual-clear
|
|
781
|
-
policy through brief/handoff files and `orca terminal send --enter --wait-submit`; identify seats by
|
|
782
|
-
terminal handle, verify submission from the receipt, and read the terminal before continuing. Do not
|
|
783
|
-
run the Herdr pane commands or Herdr context watcher below.
|
|
832
|
+
- **On Orca (`TERM_PROGRAM=Orca` and non-empty `ORCA_TERMINAL_HANDLE`)**, use the same mutual-clear
|
|
833
|
+
policy through brief/handoff files and `orca terminal send --enter --wait-submit`; identify seats by
|
|
834
|
+
terminal handle, verify submission from the receipt, and read the terminal before continuing. Do not
|
|
835
|
+
run the Herdr pane commands or Herdr context watcher below.
|
|
784
836
|
|
|
785
837
|
#### On herdr (`HERDR_ENV=1`) — mutual clear
|
|
786
838
|
|
|
@@ -1020,13 +1072,17 @@ they are left implicit:
|
|
|
1020
1072
|
- **On herdr (`HERDR_ENV=1`)**, subagents run as visible herdr panes in per-task tabs (`herdr agent start …`);
|
|
1021
1073
|
- **On Orca (`TERM_PROGRAM=Orca` and non-empty `ORCA_TERMINAL_HANDLE`)**, they run as visible terminals created with the Orca seat-spawn recipe. A seat report whose work
|
|
1022
1074
|
was produced by invisible subagents is rejected on read.
|
|
1023
|
-
2. **
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1075
|
+
2. **Seat transport is host-specific.** With neither host there are no seats, and the plain-host scope's
|
|
1076
|
+
reviews and judges run headless.
|
|
1077
|
+
- **On herdr (`HERDR_ENV=1`)**: **Seats are interactive TUI, never headless `-p`.** The P92–P96 exec
|
|
1078
|
+
lane — `cat brief | claude -p … ` in a visible pane — satisfied visibility in the letter only:
|
|
1079
|
+
`claude -p` buffers output until exit, so the pane renders idle for the entire run; it is blind to
|
|
1080
|
+
SessionStart hook errors (a broken and a fixed hook both return green); and its silence has no
|
|
1081
|
+
midpoint for a stall watcher to catch — silent-time equals lifetime. Standing operator rule since
|
|
1082
|
+
2026-07-13: consults and one-off LLM calls run as the CLI's real interactive TUI in a visible named
|
|
1083
|
+
pane. Headless is for exit-code probes — a quota check that wants `rc`, never work anyone must watch.
|
|
1084
|
+
- **On Orca (`TERM_PROGRAM=Orca` and non-empty `ORCA_TERMINAL_HANDLE`)**: **Seats are interactive TUI,
|
|
1085
|
+
never headless `-p`**, for every reason the herdr branch gives, in a visible named terminal.
|
|
1030
1086
|
3. **Buy seat diversity through Fleet, at every dispatch and respawn.** Resolve authors with `tickmarkr fleet --pick consult` and independent checkers/verifiers with `tickmarkr fleet --pick review --exclude-vendor <author-vendor>`, adding every applicable vendor exclusion under the Fleet selection contract. Consume the successful JSON adapter/model before using the visible-seat recipes; never select directly from doctor data. When one vendor's model
|
|
1031
1087
|
quota collapses, the reflex is to collapse every seat onto the surviving model and hold the
|
|
1032
1088
|
cross-vendor CLI back for a late probe — P97 ran planner, checker and verifier as one family that
|