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.
- package/README.md +51 -49
- package/dist/cli/install-commands.js +83 -36
- package/dist/cli/instructions-commands.js +113 -0
- package/dist/cli/output.js +5 -2
- package/dist/cli/registry.js +18 -27
- package/dist/cli/room-commands.js +1 -1
- package/dist/cli/startup-maintenance.js +27 -1
- package/dist/cli.js +2 -2
- package/dist/config.js +2 -2
- package/dist/identity.js +4 -4
- package/dist/index.js +3 -2
- package/dist/install-audit.js +21 -0
- package/dist/install-migration.js +84 -0
- package/dist/install.js +0 -69
- package/dist/instructions.js +256 -0
- package/dist/update-migration.js +135 -0
- package/docs/plans/2026-05-04-diff-walker-design.md +585 -0
- package/docs/plans/2026-05-05-cli-only-coordination.md +224 -0
- package/docs/plans/2026-05-06-harness-instructions-v6-converged.md +220 -0
- package/docs/plans/out-of-band-signaling-implementation.md +5 -5
- package/docs/receive-consumer-contract.md +8 -6
- package/docs/releases/0.3.0.md +77 -0
- package/docs/releases/0.4.0.md +71 -0
- package/docs/talking-stick-plan.md +3 -2
- package/package.json +4 -3
- package/scripts/postinstall-mcp-cleanup.cjs +25 -0
- package/skills/talking-stick/SKILL.md +132 -104
- package/dist/mcp-server.js +0 -244
- package/dist/server.js +0 -3
|
@@ -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 =
|
|
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:
|
|
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.
|
|
4
|
-
"description": "
|
|
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
|
|
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.
|
|
26
|
+
### 1. Use The CLI
|
|
28
27
|
|
|
29
|
-
|
|
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
|
-
|
|
30
|
+
Useful commands:
|
|
32
31
|
|
|
33
|
-
|
|
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
|
|
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
|
-
|
|
42
|
-
|
|
43
|
-
|
|
57
|
+
```sh
|
|
58
|
+
tt join --json
|
|
59
|
+
```
|
|
44
60
|
|
|
45
|
-
|
|
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
|
-
|
|
63
|
+
After joining, load editable collaboration instructions once:
|
|
48
64
|
|
|
49
|
-
|
|
65
|
+
```sh
|
|
66
|
+
tt instructions show --json
|
|
67
|
+
```
|
|
50
68
|
|
|
51
|
-
|
|
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
|
-
|
|
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
|
-
```
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
100
|
+
### 4. While Waiting
|
|
74
101
|
|
|
75
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
-
|
|
99
|
-
|
|
100
|
-
|
|
117
|
+
```sh
|
|
118
|
+
tt notes add "Finding or pointer for the current/next holder." --json
|
|
119
|
+
```
|
|
101
120
|
|
|
102
|
-
|
|
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
|
-
|
|
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
|
-
|
|
125
|
+
### 4.5 Out-Of-Band Messaging
|
|
107
126
|
|
|
108
|
-
|
|
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
|
-
|
|
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
|
-
|
|
131
|
+
```sh
|
|
132
|
+
tt msg send <recipient|room> "message body" --json
|
|
133
|
+
```
|
|
115
134
|
|
|
116
|
-
|
|
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
|
-
|
|
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
|
-
|
|
139
|
+
```sh
|
|
140
|
+
tt events --follow --json
|
|
141
|
+
```
|
|
121
142
|
|
|
122
|
-
If the
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
-
|
|
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
|
-
|
|
158
|
+
### 5. While Holding The Stick
|
|
138
159
|
|
|
139
|
-
|
|
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
|
-
|
|
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
|
-
|
|
164
|
+
### 6. Takeover Is Explicit
|
|
144
165
|
|
|
145
|
-
|
|
166
|
+
If `tt wait` reports `takeover_available`:
|
|
146
167
|
|
|
147
|
-
-
|
|
148
|
-
-
|
|
149
|
-
-
|
|
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
|
-
|
|
173
|
+
If the operator explicitly tells you to take over despite a reservation or live owner, use:
|
|
156
174
|
|
|
157
|
-
|
|
175
|
+
```sh
|
|
176
|
+
tt take --operator-requested --reason "operator requested takeover" --json
|
|
177
|
+
```
|
|
158
178
|
|
|
159
|
-
|
|
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
|
-
|
|
181
|
+
### 7. Finish With A Real Handoff
|
|
163
182
|
|
|
164
|
-
|
|
183
|
+
When you are done with your turn, default to releasing:
|
|
165
184
|
|
|
166
|
-
```
|
|
185
|
+
```sh
|
|
186
|
+
tt release --stdin <<'JSON'
|
|
167
187
|
{
|
|
168
|
-
"status": "
|
|
169
|
-
"next_action": "
|
|
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": "
|
|
192
|
+
"path": "docs/plans/2026-05-05-cli-only-coordination.md",
|
|
173
193
|
"role": "review",
|
|
174
|
-
"note": "
|
|
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
|
-
|
|
201
|
+
Use `tt assign <agent_id> . --stdin` only when a specific named member must go next:
|
|
184
202
|
|
|
185
|
-
|
|
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
|
-
|
|
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
|
-
|
|
218
|
+
### 8. After Release, Stay In The Loop
|
|
190
219
|
|
|
191
|
-
|
|
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
|
|
196
|
-
-
|
|
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
|
|
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,
|
|
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
|
|
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
|
|
233
|
+
## Recovery And Inspection
|
|
206
234
|
|
|
207
235
|
Use these reads when you need context:
|
|
208
236
|
|
|
209
|
-
- `
|
|
210
|
-
- `
|
|
211
|
-
- `
|
|
212
|
-
- `
|
|
213
|
-
- `
|
|
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 `
|
|
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
|
|