talking-stick 0.2.0 → 0.4.0

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.
@@ -0,0 +1,71 @@
1
+ # Talking Stick 0.4.0
2
+
3
+ Date: 2026-05-10
4
+
5
+ This release adds editable collaboration instructions for harness roles and
6
+ phase preferences while keeping the bundled Talking Stick skill as the
7
+ coordination safety floor.
8
+
9
+ ## Added
10
+
11
+ ### Editable collaboration instructions
12
+
13
+ New CLI surface:
14
+
15
+ ```bash
16
+ tt instructions show
17
+ tt instructions edit
18
+ tt instructions reset
19
+ ```
20
+
21
+ `show` returns the effective Markdown prompt for the detected harness. Effective
22
+ instructions are layered as bundled defaults, user defaults, and project
23
+ overrides. User instructions live under the Talking Stick data directory
24
+ (`instructions.md`); project instructions live at
25
+ `.talking-stick/instructions.md` in the workspace root.
26
+
27
+ `edit` lazily materializes the default Markdown on first use and opens
28
+ `$VISUAL`, `$EDITOR`, or a platform editor fallback. `reset` deletes the chosen
29
+ user or project file so lower layers apply again.
30
+
31
+ ### Bundled defaults
32
+
33
+ The shipped defaults describe the shared phase vocabulary:
34
+
35
+ - draft
36
+ - adversarial review
37
+ - convergence
38
+ - implementation
39
+ - implementation review
40
+ - test review
41
+ - release
42
+
43
+ They also include advisory harness fits for Claude, Codex, Gemini, and
44
+ OpenCode. These defaults are prompt guidance only; Talking Stick does not track
45
+ phase state or auto-route turns.
46
+
47
+ ### Skill loading
48
+
49
+ The bundled `talking-stick` skill now tells agents to run
50
+ `tt instructions show --json` after joining a room. If the command fails, agents
51
+ continue with the bundled skill. Editable instructions can add local
52
+ preferences, but they cannot override the core safety rules around joining,
53
+ waiting, guardian checks, handoffs, event wakes, or takeover.
54
+
55
+ ## Changed
56
+
57
+ - `tt install` prints a short customization hint after a successful skill
58
+ install: `Customize collaboration instructions with: tt instructions edit`.
59
+ - The skill's re-entry guidance now says to prefer continued action until the
60
+ task is complete or the operator explicitly redirects or stops the room.
61
+
62
+ ## Verification
63
+
64
+ ```bash
65
+ npm run typecheck
66
+ npm run build
67
+ npm test
68
+ git diff --check
69
+ node dist/cli.js instructions show --harness codex --scope bundled --json
70
+ npm pack --dry-run
71
+ ```
@@ -742,8 +742,9 @@ Recommended defaults (product scale, sized for real agent work rather than chat
742
742
  owner_lease_ttl_ms = 45 * 60 * 1000; // 45 minutes
743
743
  heartbeat_interval_ms = 5 * 60 * 1000; // 5 minutes
744
744
  claim_ttl_ms = 20 * 60 * 1000; // 20 minutes
745
- wait_for_turn_max_wait_ms = 30 * 1000; // 30 seconds
745
+ wait_for_turn_max_wait_ms = 110 * 1000; // 110 seconds
746
746
  wait_for_turn_poll_ms = 250; // transport polling cadence
747
+ wait_for_events_max_wait_ms = 110 * 1000; // 110 seconds
747
748
  presence_ttl_ms = 4 * 60 * 60 * 1000; // 4 hours
748
749
  waiter_grace_ms = 10 * 1000; // 10 seconds
749
750
  ```
@@ -1158,5 +1159,5 @@ presence TTL: 4 hours
1158
1159
  close semantics: no `close_room` tool in the MVP implementation;
1159
1160
  rooms remain resumable and can become dormant
1160
1161
  when nobody is live
1161
- wait_for_turn max wait: 30 seconds, polled at 250 ms
1162
+ wait_for_turn max wait: 110 seconds, polled at 250 ms
1162
1163
  ```
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "talking-stick",
3
- "version": "0.2.0",
4
- "description": "MCP coordination server for path-scoped agent handoffs.",
3
+ "version": "0.4.0",
4
+ "description": "CLI coordination tool for path-scoped agent handoffs.",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "tt": "dist/cli.js"
@@ -11,18 +11,19 @@
11
11
  },
12
12
  "files": [
13
13
  "dist",
14
+ "scripts",
14
15
  "skills",
15
16
  "docs",
16
17
  "README.md"
17
18
  ],
18
19
  "scripts": {
19
20
  "build": "tsc -p tsconfig.build.json && chmod +x dist/cli.js",
21
+ "postinstall": "node scripts/postinstall-mcp-cleanup.cjs",
20
22
  "prepare": "tsc -p tsconfig.build.json && chmod +x dist/cli.js",
21
23
  "test": "vitest run",
22
24
  "typecheck": "tsc -p tsconfig.json --noEmit"
23
25
  },
24
26
  "dependencies": {
25
- "@modelcontextprotocol/sdk": "^1.29.0",
26
27
  "better-sqlite3": "^12.9.0",
27
28
  "zod": "^3.25.76"
28
29
  },
@@ -0,0 +1,25 @@
1
+ #!/usr/bin/env node
2
+ const { spawnSync } = require("node:child_process");
3
+ const fs = require("node:fs");
4
+ const path = require("node:path");
5
+
6
+ const cliPath = path.resolve(__dirname, "..", "dist", "cli.js");
7
+ const packageRoot = path.resolve(__dirname, "..").replace(/\\/g, "/");
8
+
9
+ if (
10
+ process.env.TALKING_STICK_DISABLE_MCP_MIGRATION ||
11
+ !packageRoot.includes("/node_modules/talking-stick") ||
12
+ !fs.existsSync(cliPath)
13
+ ) {
14
+ process.exit(0);
15
+ }
16
+
17
+ spawnSync(process.execPath, [cliPath, "migrate-mcp", "--reason", "update", "--quiet"], {
18
+ stdio: "ignore",
19
+ env: {
20
+ ...process.env,
21
+ TALKING_STICK_SKIP_STARTUP_MAINTENANCE: "1"
22
+ }
23
+ });
24
+
25
+ process.exit(0);
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: talking-stick
3
- description: Use when working in a repo that coordinates multiple agent harnesses with Talking Stick (`tt` / `talking-stick`), or when the user asks you to avoid parallel work, wait your turn, pass structured handoffs, or coordinate with Claude, Codex, Gemini, or OpenCode in the same workspace. Also use when a workspace contains a `.talking-stick/` marker or when the MCP tools `list_rooms`, `join_path`, `leave_room`, `kick_member`, `wait_for_turn`, `heartbeat`, `release_stick`, `pass_stick`, `takeover_stick`, `get_room_state`, `get_room_events`, `send_message`, `wait_for_events`, `add_note`, or `list_notes` are available.
3
+ description: Use when working in a repo that coordinates multiple agent harnesses with Talking Stick (`tt` / `talking-stick`), or when the user asks you to avoid parallel work, wait your turn, pass structured handoffs, or coordinate with Claude, Codex, Gemini, or OpenCode in the same workspace. Also use when a workspace contains a `.talking-stick/` marker.
4
4
  ---
5
5
 
6
6
  This skill teaches a harness how to behave in a Talking Stick workspace.
@@ -18,48 +18,75 @@ Use this skill when any of these are true:
18
18
  - the user mentions `talking-stick`, `tt`, handoffs, turn-taking, or avoiding parallel work
19
19
  - the repo is known to use Talking Stick coordination
20
20
  - a `.talking-stick/` marker exists
21
- - the Talking Stick MCP tools are available in the current harness
22
21
 
23
22
  Do not use this skill for ordinary single-agent work in repos that are not using Talking Stick.
24
23
 
25
24
  ## Workflow
26
25
 
27
- ### 1. Check that Talking Stick is actually available
26
+ ### 1. Use The CLI
28
27
 
29
- Prefer the Talking Stick MCP tools when they are available. If they are not available but the `tt` CLI is on `PATH`, use the CLI instead (`tt list`, `tt join`, `tt leave`, `tt kick`, `tt wait`, `tt state`, `tt release`, `tt pass`, `tt assign`, `tt take`, `tt msg`). Do not treat missing MCP tools alone as proof that coordination is unavailable.
28
+ Use the `tt` CLI for all Talking Stick coordination. Do not use old Talking Stick MCP tools for repo coordination, even if an older install exposes them; the CLI is the source of truth. Current updates should remove stale Talking Stick MCP registrations automatically.
30
29
 
31
- Some workspaces may also have sibling receive processes running `tt msg recv --wait` or `tt msg recv --follow`; leave them alone unless the operator explicitly asks you to stop or restart them.
30
+ Useful commands:
32
31
 
33
- If coordination is required and neither the MCP tools nor the `tt` CLI are available, say so briefly and ask the user whether they want to install or enable Talking Stick first. Do not pretend coordination is active.
32
+ - `tt whoami --json`
33
+ - `tt join --json`
34
+ - `tt wait --json`
35
+ - `tt try --json`
36
+ - `tt state --json`
37
+ - `tt events --after N --target any --json`
38
+ - `tt notes add "..." --json`
39
+ - `tt notes list --json`
40
+ - `tt events --follow --json`
41
+ - `tt msg send <recipient|room> "..." --json`
42
+ - `tt msg recv --follow --json` (messages-only fallback when an event-stream consumer is too broad)
43
+ - `tt release --stdin`
44
+ - `tt assign <agent_id|next> --stdin`
45
+ - `tt take --reason "..." --json`
46
+
47
+ Some workspaces may also have sibling receive processes running `tt events --follow`, `tt msg recv --wait`, or `tt msg recv --follow`; leave them alone unless the operator explicitly asks you to stop or restart them.
48
+
49
+ If coordination is required and `tt` is unavailable, say so briefly and ask the user whether they want to install or enable Talking Stick first. Do not pretend coordination is active.
34
50
 
35
51
  Human CLI runs silently keep already-installed Claude Code, Codex, and OpenCode skill copies/symlinks aligned with the bundled Talking Stick skill. This is best effort and only updates existing installs; Gemini skills are registry-managed and should be refreshed with `tt install gemini` when needed.
36
52
 
37
- ### 2. Join the workspace room once
53
+ ### 2. Join The Workspace Room Once
38
54
 
39
- On the first substantial task in a Talking Stick workspace:
55
+ On the first substantial task in a Talking Stick workspace, run:
40
56
 
41
- 1. call `join_path` with the current workspace path
42
- 2. keep the returned `room_id`
43
- 3. note the returned policy, especially `heartbeatIntervalMs`
57
+ ```sh
58
+ tt join --json
59
+ ```
44
60
 
45
- If the workspace is nested, accept the resolved canonical path the server returns.
61
+ Keep the returned room id and canonical path in mind. The current working directory is the implicit path for normal commands; pass an explicit path only when coordinating a different directory or intentionally selecting a nested room.
46
62
 
47
- ### 3. Wait before doing shared work
63
+ After joining, load editable collaboration instructions once:
48
64
 
49
- Before making shared edits or running owner-style actions, call `wait_for_turn`.
65
+ ```sh
66
+ tt instructions show --json
67
+ ```
50
68
 
51
- Use the `room_id` returned by `join_path`. Do not pass the original filesystem path to `wait_for_turn`; path resolution belongs to `join_path`, and waiting must target the exact resolved room. This avoids ambiguity when a nested workspace resolves to an ancestor room or when multiple rooms could exist under the same tree.
69
+ If that command fails, continue with this bundled skill. Editable instructions can add local preferences, but they do not override the safety rules in this skill.
52
70
 
53
- Keep the wait input minimal:
71
+ Right after joining, start a background ambient receiver so direct messages and turn passes/reservations surface as soon as they happen instead of waiting for the next time you poll:
54
72
 
55
- ```json
56
- {
57
- "room_id": "<room_id from join_path>",
58
- "max_wait_ms": 110000
59
- }
73
+ ```sh
74
+ tt events --follow --json
75
+ ```
76
+
77
+ For `tt events --wait` and `tt events --follow`, the default target is `self`; add `--target any` only for audit/debug views. If your harness can stream a child process's stdout into the model's context (Claude Code's Monitor, Codex `attach`-style), this is enough — each line becomes an event you see mid-task. If your harness can only notice that a backgrounded command exits, use the polling fallback in §4.5. Without an ambient receiver, neither messages nor turn handoffs reach you between deliberate `tt wait` / `tt events` calls.
78
+
79
+ The ambient receiver is not a turn claimant. It never grants the stick and never starts the lease guardian. Keep using `tt wait --json` for ownership.
80
+
81
+ ### 3. Wait Before Shared Work
82
+
83
+ Before making shared edits or running owner-style actions, run:
84
+
85
+ ```sh
86
+ tt wait --json
60
87
  ```
61
88
 
62
- `max_wait_ms` is optional. Use the longest client-safe wait you can support: 110000 ms is a good MCP default when the harness can tolerate it; 180000 ms is fine only when the tool/client timeout is known to exceed that. If the call times out at the harness layer, fall back to a shorter value and call again. Do not send `cursor`, even if an old tool schema still exposes it; `wait_for_turn` is cursor-free, and resumable event replay belongs to `get_room_events`.
89
+ The default wait timeout is `110s`, which is the normal active-coordination setting. If your harness has a shorter tool timeout, override with the longest safe value and immediately wait again when it returns without granting the turn. Do not busy-loop with short waits.
63
90
 
64
91
  Possible outcomes:
65
92
 
@@ -68,151 +95,152 @@ Possible outcomes:
68
95
  - `takeover_available`: surface the reason and make takeover explicit
69
96
  - `closed`: stop and explain that the room is closed
70
97
 
71
- ### 4. While waiting
98
+ A successful `tt wait` or `tt take` starts an internal `tt guard` lease guardian and returns `guardian_pid` in JSON. Verify the field is present and the pid is alive before you start a long edit; the guardian is what keeps your lease from expiring after the foreground `tt wait` process exits. If `guardian_pid` is missing or the pid is gone, stop, run `tt wait` again to repair the guardian (it will detect the existing ownership and respawn the guardian), and only then continue. Do not kill that guardian.
72
99
 
73
- **Prefer to run the wait in the background.** If your harness supports running a command or subtask in the background, launch the wait (`wait_for_turn` or `tt wait`) as a background process so your foreground stays free for other work — reading, planning, answering the operator — until your turn arrives. Blocking the whole harness on the wait defeats the point.
100
+ ### 4. While Waiting
74
101
 
75
- **Prefer wait cycles over scheduled wakeups.** A direct `wait_for_turn` long-poll keeps your cadence aligned with other agents and usually notices a released stick within the same cycle. Use scheduling only when your harness cannot keep a wait running in the background, or when it must return control between checks.
102
+ Prefer to run `tt wait` in the background if your harness supports background commands. That keeps the foreground free for reading, planning, answering the operator, and watching OOB messages until your turn arrives.
76
103
 
77
- Wakeup pattern:
104
+ Prefer wait cycles over scheduled wakeups. A direct long-poll stays aligned with other agents and usually notices a released stick within the same cycle. Use scheduled wakeups only when your harness cannot keep a wait running in the background.
78
105
 
79
- 1. Probe `wait_for_turn` with `max_wait_ms: 0`.
80
- 2. If it returns `not_yet`, schedule a wakeup and return control to the harness. Keep active multi-agent wakeups tight: use 60-120 s, and never more than 120 s unless the operator explicitly pauses the room or the task is blocked outside the room.
81
- 3. On wakeup, repeat from step 1.
82
-
83
- Scheduled wakeups are a fallback, not a reason to check in more slowly than agents using `wait_for_turn` directly. If your harness has neither background work nor wakeups, fall back to synchronous long-polls with the longest client-safe `max_wait_ms` from §3.
84
-
85
- Whether the wait runs in the foreground or the background, call it **once** with the client-safe `max_wait_ms` budget from above and let the server long-poll. When it returns without `your_turn`, call it again. Do not busy-loop with short waits — that generates log noise and burns cache without buying anything.
86
-
87
- Coordination is meant to be lightweight. `wait_for_turn` is the only long-running call you should make. Room-inspection RPCs (`get_room_state`, `get_room_events`) exist to answer specific questions ("who holds the stick right now?", "what was in my predecessor's handoff?") — do not call them on a timer or repeatedly just to check on another agent's progress. If you find yourself inspecting the room more than a few times per turn, stop; long-poll on `wait_for_turn` instead and trust the protocol.
106
+ Do not replace `tt wait` with an event receiver. `tt events --wait` is only a wake channel for messages and handoff/reservation events. If it exits with a pass, release, assignment, or message, process the event, then run or continue `tt wait --json`; do not touch shared files unless that wait returns `your_turn` and a live `guardian_pid`.
88
107
 
89
108
  If you do not have the stick:
90
109
 
91
110
  - do not make shared repo changes
92
111
  - do not silently race another harness
93
- - it is fine to read, plan, review, or help the user think — or any other work that does not mutate shared state
112
+ - it is fine to read, plan, review, or help the user think
94
113
  - tell the user who currently holds or is reserved the turn when that is useful
95
114
 
96
- The wait is for *active* non-mutating work, not idle sleep. Re-read the holder's last handoff, follow up on its `artifacts[]`, investigate the area they are touching, and rethink the plan from your own angle. If you find something the holder should know — a missed invariant, a related bug, a sharper plan — leave a note with `add_note` rather than sitting on it until your next turn. Notes do not grant permission to edit shared files; they are observations and pointers, not coordination bypasses. The point: while you wait you can still move the work forward by feeding the holder, not by stalling.
115
+ The wait is for active non-mutating work, not idle sleep. Re-read the holder's last handoff, follow up on its `artifacts[]`, investigate the area they are touching, and rethink the plan from your own angle. If you find something the holder should know, leave a durable note:
97
116
 
98
- When you do take the stick, first read the attached handoff and load any useful `artifacts[]`, then run `list_notes` once so you see what other members left for you. The owner's turn is the right place to act on a note, not to debate it with its author mid-turn.
99
-
100
- ### 4.5 Out-of-band messaging
117
+ ```sh
118
+ tt notes add "Finding or pointer for the current/next holder." --json
119
+ ```
101
120
 
102
- The talking stick guarantees single-writer authority over shared workspace state. It is not a chat protocol. For transient signaling -- paging the holder, asking a quick question, or broadcasting awareness -- use messages.
121
+ Room inspection exists to answer specific questions, not to poll. Do not run `tt state` after a routine `tt wait`; the wait result already says who owns or is reserved for the turn. Use `tt state`, `tt events --target any`, and `tt notes list` sparingly when the wait result is insufficient or you are debugging stale members, takeover, or history.
103
122
 
104
- **Send.** `tt msg send <recipient> "<body>"` or MCP `send_message`. Recipient is a full `agent_id`, an unambiguous active display name, or the literal `room` for broadcast. `--interrupt` marks the message as time-sensitive; the receiver decides whether to act on it now.
123
+ When you do take the stick, first read the attached handoff and load any useful `artifacts[]`, then run `tt notes list --json` once so you see what other members left for you.
105
124
 
106
- **Receive.** Use the receive mode your harness can observe. If it can monitor stdout from a long-running child, run `tt msg recv --follow`; each incoming event lands as one JSON line. If it can only notice that a background command completed, run `tt msg recv --wait --after <last_event_seq>`; it exits on the next matching batch, then you start it again with the returned cursor. Restart with `--after <last_event_seq>` to resume.
125
+ ### 4.5 Out-Of-Band Messaging
107
126
 
108
- **When to message vs note vs handoff.**
127
+ The talking stick guarantees single-writer authority over shared workspace state. It is not a chat protocol. For transient signaling, use messages.
109
128
 
110
- - **Message** when the exchange is conversational, ephemeral, and tied to processes that are currently online: design questions, "are you about to break X?", live coordination.
111
- - **Note** (`tt notes add`) when the artifact should outlive the moment: a finding the next holder should consider at handoff, or an observation that survives process churn.
112
- - **Handoff** (release/pass with a structured payload) when transferring work. Messages do not replace handoffs; they live alongside them.
129
+ Send:
113
130
 
114
- **Messages are not private.** Any room member can read any message via `get_room_events` or `tt events --follow --target any`. `to_agent_id` is routing, not an ACL.
131
+ ```sh
132
+ tt msg send <recipient|room> "message body" --json
133
+ ```
115
134
 
116
- **Messages do not grant the stick.** A non-holder paging the holder does not gain write authority. The holder may act on the message immediately or defer until handoff.
135
+ Recipient is a full `agent_id`, an unambiguous active display name, or the literal `room` for broadcast. `--interrupt` marks the message as time-sensitive; the receiver decides whether to act on it now.
117
136
 
118
- **Stay in the wait loop in parallel.** A `tt msg recv --wait` or `--follow` subprocess does not replace `wait_for_turn`. Keep waiting for your turn; messages are a side channel.
137
+ Receive with the mode your harness can observe. The recommended primary path is the unified event stream you started in §2:
119
138
 
120
- ### 5. While holding the stick
139
+ ```sh
140
+ tt events --follow --json
141
+ ```
121
142
 
122
- If the task may run longer than a few minutes, heartbeat periodically.
143
+ That streams direct messages, broadcasts, and turn passes/reservations for you as a single ordered feed — one JSON event per line. Use it whenever your harness can stream a child process's stdout into the model's context. If the harness can only notice that a backgrounded command exits, use the polling fallbacks:
123
144
 
124
- Use the cadence from `join_path.policy.heartbeatIntervalMs` when available. Do not invent your own cadence if the server already told you one.
145
+ ```sh
146
+ tt events --wait --after <last_event_seq> --json # all event types
147
+ tt msg recv --wait --after <last_event_seq> --json # messages only
148
+ ```
125
149
 
126
- **Holding the stick is for active work.** The moment you stop actively editing, reasoning through edits, or asking the operator a blocking question, release or pass. Do not idle-hold the room while waiting on long verification, non-blocking operator input, CI, or any other pause where another harness could make progress.
150
+ Restart with the returned cursor to resume. `tt msg recv --follow` still exists for harnesses that want a messages-only feed, but the event stream is preferred because turn handoffs use the same channel and a messages-only consumer silently misses them.
127
151
 
128
- ### 6. Takeover is explicit
152
+ For Codex-style harnesses that cannot consume a continuous stdout stream, the safe loop is: keep `tt wait --json` as the ownership wait, and separately run `tt events --wait --after <last_event_seq> --json` as a short-lived wake process. An event wake can tell you to read, reply, or retry `tt wait`; it is never permission to edit.
129
153
 
130
- If `wait_for_turn` reports `takeover_available`:
154
+ Messages are public room events. Any room member can read them with `tt events --target any`. `to_agent_id` is routing, not an ACL.
131
155
 
132
- - explain why takeover is available (`owner_timeout`, `owner_gone`, `claim_timeout`, `recipient_gone`)
133
- - do not silently take over just because it is possible
134
- - if takeover is chosen, call `takeover_stick`
135
- - after takeover, call `get_room_events` so you can reconstruct the last handoff before touching code
156
+ Messages do not grant the stick. A non-holder paging the holder does not gain write authority. Keep waiting for your turn; messages are only a side channel.
136
157
 
137
- If the operator explicitly tells you to take over despite a reservation or live owner, use the CLI path when available: `tt take --operator-requested --reason "<operator requested takeover>"`. Do not invent this override yourself; it is for direct operator intervention.
158
+ ### 5. While Holding The Stick
138
159
 
139
- ### 7. Finish with a real handoff
160
+ Holding the stick is for active work. The moment you stop actively editing, reasoning through edits, or asking the operator a blocking question, release or assign the turn. Do not idle-hold the room while waiting on long verification, non-blocking operator input, CI, or any other pause where another harness could make progress.
140
161
 
141
- When you are done with your turn, default to `release_stick`.
162
+ The `tt guard` process spawned by `tt wait` keeps the lease alive during active work. Later owner commands such as `tt release`, `tt assign`, and `tt take` must run under the same harness identity. If identity is ambiguous, use the exact active id with `TT_HARNESS_AGENT_ID=<agent_id>`.
142
163
 
143
- **Default to `release_stick`.** Releasing lets the server pick the next fair waiter: a recent waiter that is new or has gone longest without holding the stick. If the best-known candidate is between wait polls, the room can briefly stay claimable instead of pinning a stale reservation. This keeps the room open instead of silently turning agent-to-agent handoffs into a duopoly.
164
+ ### 6. Takeover Is Explicit
144
165
 
145
- Use `pass_stick` only when you have a concrete reason a specific named member must go next:
166
+ If `tt wait` reports `takeover_available`:
146
167
 
147
- - they have unique context the next step requires
148
- - they hold a credential or capability others lack
149
- - the operator explicitly addressed the work to them
150
-
151
- Otherwise release. Ping-ponging `pass_stick` between two agents is an antipattern because it can lock humans out of their own room.
152
-
153
- Always include a non-empty handoff.
168
+ - explain why takeover is available (`owner_timeout`, `owner_gone`, `claim_timeout`, `recipient_gone`)
169
+ - do not silently take over just because it is possible
170
+ - if takeover is chosen, run `tt take --reason "..." --json`
171
+ - after takeover, run `tt events --target any --json` so you can reconstruct the last handoff before touching code
154
172
 
155
- **Keep handoffs tight.** Handoffs are persisted in the event log and re-read on claims. Aim for roughly 150-300 words of `status`; reference commits by SHA instead of restating diffs, and use `artifacts[]` with path, line range, and role instead of pasting code. The handoff is the headline; long-form context belongs in `docs/` or a note.
173
+ If the operator explicitly tells you to take over despite a reservation or live owner, use:
156
174
 
157
- Minimum handoff quality:
175
+ ```sh
176
+ tt take --operator-requested --reason "operator requested takeover" --json
177
+ ```
158
178
 
159
- - `status`: what you finished, what changed, and what remains true
160
- - `next_action`: the concrete next step for the next owner
179
+ Do not invent this override yourself; it is for direct operator intervention.
161
180
 
162
- Add `artifacts`, `open_questions`, and `do_not` when they will save the next harness real time or prevent rework.
181
+ ### 7. Finish With A Real Handoff
163
182
 
164
- Example:
183
+ When you are done with your turn, default to releasing:
165
184
 
166
- ```json
185
+ ```sh
186
+ tt release --stdin <<'JSON'
167
187
  {
168
- "status": "Added the MCP smoke test and verified it against two clients sharing one SQLite database.",
169
- "next_action": "Run the same handoff path through the human CLI and confirm pass/release behavior matches the MCP flow.",
188
+ "status": "Updated the CLI-only coordination plan and the bundled skill so harnesses use tt subprocesses for join, wait, OOB messaging, notes, and handoffs.",
189
+ "next_action": "Review the plan and then start the code-removal pass.",
170
190
  "artifacts": [
171
191
  {
172
- "path": "tests/mcp-smoke.test.ts",
192
+ "path": "docs/plans/2026-05-05-cli-only-coordination.md",
173
193
  "role": "review",
174
- "note": "End-to-end MCP adapter smoke coverage."
194
+ "note": "CLI-only migration plan."
175
195
  }
176
- ],
177
- "open_questions": [
178
- "Should tt install default to copy or link for local development?"
179
196
  ]
180
197
  }
198
+ JSON
181
199
  ```
182
200
 
183
- **`pass_stick` requires the target to be an active room member.** If the intended recipient's harness session has ended and they show as `inactive` in `get_room_state.members`, `pass_stick` can return `unknown_member`. Use `release_stick` instead; the next fair waiter can claim through the normal sequence path.
201
+ Use `tt assign <agent_id> . --stdin` only when a specific named member must go next:
184
202
 
185
- Remember that the operator can join their own room as `human:<user>`. Default behavior should leave room for them to claim turns naturally; releasing rather than passing keeps that door open.
203
+ - they have unique context the next step requires
204
+ - they hold a credential or capability others lack
205
+ - the operator explicitly addressed the work to them
186
206
 
187
- ### 8. After passing or releasing, stay in the loop
207
+ Otherwise release. Pinning turns between two agents is an antipattern because it can lock humans out of their own room.
208
+
209
+ Always include a non-empty handoff. Keep it tight: aim for roughly 150-300 words of `status`; reference commits by SHA instead of restating diffs, and use `artifacts[]` with path and role instead of pasting code.
210
+
211
+ Minimum handoff quality:
212
+
213
+ - `status`: what you finished, what changed, and what remains true
214
+ - `next_action`: the concrete next step for the next owner
215
+
216
+ Add `artifacts`, `open_questions`, and `do_not` when they will save the next harness real time or prevent rework.
188
217
 
189
- **The default after `release_stick` or `pass_stick` is to re-enter the wait loop and keep waiting until your next turn arrives.** Do not stop and ask the operator whether they want you back in the loop. Do not treat a handoff as end-of-session. In a multi-agent workspace, the expectation is: work on your turn, hand off, wait for your next turn, repeat.
218
+ ### 8. After Release, Stay In The Loop
190
219
 
191
- Stopping to ask questions after every handoff defeats the coordination protocol the operator wired you into a room so that you *would* keep showing up without being asked.
220
+ The default after `tt release` or `tt assign` is to re-enter the wait loop and keep waiting until your next turn arrives. Do not stop and ask the operator whether they want you back in the loop. Do not treat a handoff as end-of-session.
192
221
 
193
222
  Exit the wait loop only when one of these is true:
194
223
 
195
- - the shared task is explicitly finished (the operator said so, or the final handoff marks the work complete)
196
- - you are the only active member and there is no one to hand off to
197
- - the operator gives a direct redirect or stop ("that's enough," "drop out of the room," a new unrelated task, etc.)
224
+ - the shared task is explicitly finished
225
+ - the operator gives a direct redirect or stop
198
226
 
199
- In every other case: after `release_stick` or `pass_stick`, go straight back into the wait loop (ideally backgrounded see §4).
227
+ In every other case, after `tt release` or `tt assign`, go straight back into `tt wait --json`. Other-harness inactivity is not an exit signal; keep waiting or take the next useful action until the task is done.
200
228
 
201
- If the operator tells you to drop out of coordination, call `leave_room` or `tt leave`. Rooms with no active members are deleted instead of kept as history, and long-idle rooms may be purged on later invocations.
229
+ If the operator tells you to drop out of coordination, run `tt leave --json`. Rooms with no active members are deleted instead of kept as history, and long-idle rooms may be purged on later invocations.
202
230
 
203
- If the room state shows ghost members from past sessions whose processes are gone (visible as `inactive last seen ...` in `tt state`), call `kick_member` / `tt kick <agent_id>` to evict them. This is the right tool when liveness has already decided the target is dead — pass `force: true` only when the operator explicitly tells you to remove a still-active member.
231
+ If the room state shows ghost members from past sessions whose processes are gone, run `tt kick <agent_id> --json` to evict them. Use `--force` only when the operator explicitly tells you to remove a still-active member.
204
232
 
205
- ## Recovery and Inspection
233
+ ## Recovery And Inspection
206
234
 
207
235
  Use these reads when you need context:
208
236
 
209
- - `list_rooms`: discover active rooms under a path
210
- - `leave_room`: explicitly remove your membership from a room
211
- - `kick_member`: evict an idle member whose process is gone (use `force: true` only on operator instruction)
212
- - `get_room_state`: authoritative current room projection
213
- - `get_room_events`: replay recent claims, releases, passes, and takeovers
237
+ - `tt list --json`: discover active rooms under the current path
238
+ - `tt state --json`: authoritative current room projection
239
+ - `tt events --target any --json`: replay recent claims, releases, assignments, messages, and takeovers
240
+ - `tt notes list --json`: list durable notes
241
+ - `tt whoami --explain`: inspect identity resolution
214
242
 
215
- Prefer `get_room_state` over guessing from local memory when ownership may have changed.
243
+ Prefer `tt state` over guessing from local memory when ownership may have changed and you are not already looking at a fresh `tt wait` result.
216
244
 
217
245
  ## Behavior Priorities
218
246