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,224 @@
1
+ # CLI-Only Coordination And MCP Removal
2
+
3
+ **Status:** draft by `codex:d4bc2492`, incorporating Claude OOB review. **Branch:** `oob-identity-fix-plan`.
4
+
5
+ ## Why This Change
6
+
7
+ Out-of-band messaging exposed a deeper problem: Talking Stick has two harness integration paths, CLI and MCP, and they do not share the same process context. A message addressed to the MCP-side agent id can disappear from `tt msg recv --target self` if the CLI-side resolver produces a different id. Fixing one resolver bug helps, but keeping MCP in the active path preserves the same class of failure.
8
+
9
+ The new direction is simpler: **the `tt` CLI is the only harness contract.** Agents coordinate by running `tt` commands. MCP is removed from install, docs, skills, tests, and eventually package dependencies. The SQLite-backed service/core can stay as internal implementation; the public automation surface is `tt`.
10
+
11
+ ## Goals
12
+
13
+ - Make every agent workflow expressible through CLI commands: `tt join`, `tt wait`, `tt release`, `tt assign`, `tt take`, `tt state`, `tt events`, `tt notes`, and `tt msg`.
14
+ - Make ambient receive CLI-first: `tt events --follow --json` for live stdout consumers, `tt events --wait --after <cursor> --json` for process-completion consumers, and `tt msg recv` only for messages-only consumers. `--wait` and `--follow` default to `--target self`.
15
+ - Remove MCP registration from `tt install` and remove `tt mcp` as a supported command.
16
+ - Automatically remove stale Talking Stick MCP registrations from every supported harness during update/first-run migration.
17
+ - Update the bundled skill so harnesses prefer CLI even when MCP tools exist in older installations.
18
+ - Replace MCP smoke coverage with real child-process CLI smoke coverage, including SIGTERM/cursor behavior.
19
+ - Keep long turns safe by making the CLI-owned lease guardian a first-class contract of `tt wait` / `tt take`.
20
+ - Preserve human-friendly CLI defaults: human shells get readable text unless `--json` is explicit; harness-detected shells get JSON where machine output is expected.
21
+
22
+ ## Non-Goals
23
+
24
+ - No backward compatibility promise for MCP users beyond automatic cleanup of stale Talking Stick-owned MCP registrations. This is an intentional breaking simplification.
25
+ - No plugin requirement. Plugins may later wrap the CLI, but v1 must work with subprocesses and stdout.
26
+ - No daemon. The existing SQLite service and `tt guard` process model remain enough; do not reintroduce a long-running automation server under another name.
27
+ - No change to the single-writer room semantics.
28
+
29
+ ## Target Architecture
30
+
31
+ ### Public Surface
32
+
33
+ `tt` is the public API. Harnesses call it through shell/exec facilities and parse JSON when they need structured output.
34
+
35
+ Core command mapping:
36
+
37
+ | Need | CLI |
38
+ |---|---|
39
+ | Join room | `tt join [path] --json` |
40
+ | Wait/claim | `tt wait [path] --json` |
41
+ | Probe | `tt try [path] --json` |
42
+ | Release | `tt release [path] --stdin` |
43
+ | Assign specific next holder | `tt assign <agent_id> [path] --stdin` |
44
+ | Operator takeover | `tt take [path] --operator-requested --reason ... --json` |
45
+ | State | `tt state [path] --json` |
46
+ | Events | `tt events [path] --after N --target any --json` |
47
+ | Notes | `tt notes add/list ... --json` |
48
+ | Send OOB | `tt msg send <recipient|room> <body...> --json` |
49
+ | Ambient receive | `tt events --follow --json` |
50
+ | Messages-only receive | `tt msg recv --follow --json` |
51
+
52
+ The skill should teach these exact commands. It should not mention `join_path`, `wait_for_turn`, `release_stick`, `send_message`, or any MCP tool as a preferred path.
53
+
54
+ Successful `tt wait` and `tt take` calls must start or repair the internal `tt guard` lease guardian and return its `guardian_pid` in JSON. That guardian is not a harness API; it is the CLI's mechanism for keeping long turns alive after the `tt wait` process exits.
55
+
56
+ ### Internal Surface
57
+
58
+ Keep `TalkingStickService` / `TalkingStickCommands` as internal TypeScript modules backing the CLI. They are not the harness API. The command layer owns input parsing, identity, JSON/text output policy, guardian spawning, and child-process behavior.
59
+
60
+ The CLI-only rule applies to external harness coordination. Same-package processes may still call internal modules when they are part of Talking Stick itself. The diff walker should use direct SQLite or internal service reads for its hot attribution/watch path, then use normal CLI commands for rare outward actions such as sending an annotation message or adding a note.
61
+
62
+ ### Holder Lease Guardian
63
+
64
+ Claude's main review concern is load-bearing: if `tt wait` exits and no process continues heartbeating, a holder doing a long edit can time out and look stale. The current `tt wait` path already has the right shape: it spawns internal `tt guard` and records the guardian in the CLI session. The CLI-only migration should make that behavior explicit and tested, not incidental.
65
+
66
+ Required behavior:
67
+
68
+ - `tt wait --json` returning `your_turn` includes `guardian_pid`.
69
+ - `tt take --json` returning success includes `guardian_pid`.
70
+ - If the caller already owns the turn and the old guardian is gone, `tt wait` repairs it by spawning a replacement.
71
+ - `tt release`, `tt pass`, and `tt assign` do not require the original `tt wait` process to still exist; they rely on the persisted CLI session and identity.
72
+ - Tests kill the guardian and prove the next owner command either repairs or reports the problem clearly.
73
+
74
+ This avoids a harness-level `tt heartbeat` timer and avoids wrapping all work in a daemon-like `tt hold` command.
75
+
76
+ ### Process Cost
77
+
78
+ CLI-only coordination pays a Node startup and SQLite-open cost for every command. That is acceptable for `tt wait` cycles, handoffs, notes, and OOB messages. Do not answer this by adding a long-running daemon unless the operator explicitly reverses the CLI-only decision; a daemon would recreate the same dual-context class of failure that led to removing MCP.
79
+
80
+ ### Identity
81
+
82
+ With MCP removed, issue #19 becomes a CLI-only identity reliability issue instead of a CLI-vs-MCP comparison. The resolver still needs to be stable across repeated shell-outs from the same harness:
83
+
84
+ 1. `TT_HARNESS_AGENT_ID` wins when explicitly exported.
85
+ 2. Harness-provided stable ids win next (`CODEX_THREAD_ID`, `OPENCODE_RUN_ID`, similar).
86
+ 3. Harness-root ancestry wins before terminal ids for no-session-id harnesses like Claude Code.
87
+ 4. Terminal ids (`ITERM_SESSION_ID`, `CMUX_TAB_ID`, etc.) are fallback only after no harness root can be found.
88
+ 5. Human fallback remains `human:<username>`.
89
+
90
+ Live receivers should either use the resolved harness id directly or run under `TT_HARNESS_AGENT_ID=<agent_id>` when a wrapper has already joined a room as that id.
91
+
92
+ ### Install
93
+
94
+ `tt install` should become a skill/bootstrap installer, not an MCP installer. Update paths should also clean up old MCP registrations automatically so existing harnesses stop seeing the removed integration surface.
95
+
96
+ Proposed behavior:
97
+
98
+ - `tt install <harness...> | --all [--print] [--copy] [--link]`: install/update the bundled skill only.
99
+ - Remove `tt install-skill` / `tt uninstall-skill` once `tt install` owns skill installation. There is no compatibility requirement to keep parallel install verbs.
100
+ - `tt uninstall`: remove the skill install and Talking Stick-owned stale MCP config entries.
101
+ - Remove MCP config writes for Claude, Codex, Gemini, and OpenCode.
102
+ - Remove `DEFAULT_SERVER_COMMAND = ["tt", "mcp"]`.
103
+ - Remove native `harness mcp add/remove` command planning.
104
+
105
+ ### Update-Time MCP Cleanup
106
+
107
+ Backward compatibility means removing the stale broken path, not keeping it alive. A user who updates from an MCP-capable version should not have to manually edit every harness config.
108
+
109
+ Required behavior:
110
+
111
+ - The package update lifecycle runs a cleanup pass when the package manager executes install/update scripts.
112
+ - `tt self-update` in versions that know about this migration runs the cleanup pass after the package manager completes.
113
+ - The first normal `tt` invocation after a package version change runs the same cleanup pass, covering users who update from an older `tt self-update`, skip lifecycle scripts, or use `npm update -g`, `mise`, `pnpm`, or another manager.
114
+ - Cleanup targets all supported harness config locations, not only the currently detected harness. Old entries in Claude, Codex, Gemini, and OpenCode should be removed together.
115
+ - The cleanup is idempotent and silent when nothing changes. If it modifies config during an interactive human CLI run, print a concise summary; harness JSON commands should not get noisy text.
116
+ - Always append an audit entry for removals with harness, config path, and removed server key/name so an operator can inspect why an MCP entry disappeared.
117
+ - Only remove Talking Stick-owned MCP entries by strict inverse-of-install matching: canonical server name/key `talking-stick` plus the exact command/args shape this installer previously wrote for that harness.
118
+ - Leave hand-edited or custom entries alone, even if they mention `talking-stick`, when the name/key or command/args no longer match the canonical installed shape.
119
+ - Do not remove unrelated MCP servers or unrelated harness settings.
120
+ - Config writes remain atomic and should preserve formatting where the existing installer machinery already can.
121
+
122
+ Implementation shape:
123
+
124
+ - Add `removeStaleMcpRegistrations({ harnesses: "all", reason: "update" })` in the install/maintenance layer.
125
+ - Track the last package version that completed migration in the Talking Stick data dir, separate from room state, so startup can cheaply decide whether to run it.
126
+ - Expose a non-interactive internal cleanup entrypoint that package lifecycle scripts can call without joining rooms or emitting harness JSON.
127
+ - Reuse the existing harness config discovery/write helpers and adapter-level install shape. Removal should be the inverse of install, not a second parser/matcher.
128
+ - Delete MCP add planning after cleanup support lands, but keep the adapter-owned stale-entry removal path.
129
+ - Add fixture tests for each supported harness proving a stale canonical Talking Stick MCP entry is removed, a neighboring unrelated MCP entry survives, and a hand-edited Talking Stick-looking entry survives.
130
+ - The audit log lives in a dedicated `${TALKING_STICK_DATA_DIR}/update-migrations.log`, not the general maintenance log. Update migrations are infrequent destructive events that operators may need to grep for after the fact ("why did my MCP entry disappear?"); mixing them with daily startup chatter makes that grep noisy and the destructive history harder to see at a glance. Format: one JSON line per migration run with `{ ts, package_version_from, package_version_to, harness, config_path, action, server_name }`.
131
+
132
+ ### OOB Messaging And Ambient Receive
133
+
134
+ OOB stays on the existing `room_events` / `message_sent` substrate, but all live receive UX is CLI-based.
135
+
136
+ The recommended ambient consumer is **`tt events --follow --json`**, not `tt msg recv --follow`. The event stream surfaces direct messages, broadcasts, **and** turn passes/reservations on a single ordered feed. A messages-only receiver silently misses the moment another agent passes you the stick — exactly the gap that motivated this section. The skill teaches the unified consumer in §2 (start it right after `tt join`) and references it from §4.5.
137
+
138
+ Required receive contract:
139
+
140
+ - `tt events --follow --json` emits one JSON event per line for messages, broadcasts, and turn handoffs targeting the caller.
141
+ - It exits cleanly on SIGTERM/SIGHUP and writes the cursor to stderr as today.
142
+ - `tt events --wait --after <cursor> --json` exits after the next matching batch for harnesses that cannot monitor long-running stdout.
143
+ - Event receive is observer-only. It does not claim the stick, does not start a guardian, and must not be treated as permission to edit. A receiver that wakes on `pass`, `release`, or `assignment` still has to run `tt wait --json` and get `your_turn` before touching shared files.
144
+ - `tt msg recv --follow` and `tt msg recv --wait` remain available as messages-only feeds for harnesses that explicitly want the narrower stream, but the skill marks them as fallback rather than primary.
145
+ - First launch starts at the room tail unless `--after` is explicit, avoiding historical replay.
146
+ - Direct messages and room broadcasts are included for `target=self`; the caller's own broadcasts are excluded.
147
+
148
+ ## Implementation Sequence
149
+
150
+ ### Stage 1 — Skill And Plan
151
+
152
+ This PR:
153
+
154
+ - Add this plan.
155
+ - Update `skills/talking-stick/SKILL.md` to be CLI-only.
156
+ - Remove MCP-first language from the OOB skill section.
157
+ - Keep source code unchanged except docs/skill, so Claude can review direction before the destructive code pass.
158
+
159
+ ### Stage 2 — CLI Identity Hardening
160
+
161
+ - Change resolver precedence so harness-root ancestry beats terminal-session fallback when a harness env marker exists but no stable session id is present.
162
+ - Add tests for Claude CLI shell-out matching repeated invocations from the same harness root.
163
+ - Add child-process tests proving `tt events --wait` / `tt events --follow` default to self and receive direct messages and turn handoffs addressed to the active CLI member without `TT_HARNESS_AGENT_ID`.
164
+ - Keep narrower coverage proving `tt msg recv` receives direct messages without widening into non-message events.
165
+ - Add guardian tests proving `tt wait` / `tt take` return a live `guardian_pid`, and that a subsequent `tt wait` repairs a dead guardian for an existing owner.
166
+ - Keep `TT_HARNESS_AGENT_ID` override as the explicit escape hatch.
167
+
168
+ ### Stage 3 — Installer De-MCP
169
+
170
+ - Change `tt install` / `tt uninstall` to manage skill installs plus cleanup of stale Talking Stick MCP entries.
171
+ - Add automatic stale MCP cleanup to package update lifecycle, `tt self-update`, and first-run-after-version-change startup maintenance.
172
+ - Delete MCP add planning from `src/install.ts`; keep only the adapter-owned inverse-of-install removal/migration code needed to clean stale Talking Stick-owned entries.
173
+ - Remove stale Talking Stick MCP entries during `tt uninstall` too; do not remove unrelated harness config.
174
+ - Update README install instructions.
175
+ - Add tests showing `tt install --all` skips missing harnesses silently and does not write MCP config.
176
+ - Add update-migration tests covering all supported harnesses, idempotency, and preservation of unrelated MCP servers.
177
+
178
+ ### Stage 4 — Remove MCP Server Surface
179
+
180
+ - Remove `tt mcp` from the command registry and help.
181
+ - Delete `src/mcp-server.ts` and MCP-specific tests.
182
+ - Delete `src/server.ts` unless another stdio entrypoint still needs it.
183
+ - Remove `@modelcontextprotocol/sdk` from `package.json`.
184
+ - Remove MCP exports from `src/index.ts`.
185
+ - Replace MCP smoke tests with CLI child-process smoke tests covering join/wait/release/msg/notes.
186
+
187
+ ### Stage 5 — Docs And Release Notes
188
+
189
+ - Rewrite README around CLI-first coordination.
190
+ - Update `docs/receive-consumer-contract.md` to describe CLI subprocess consumers, not MCP wrappers.
191
+ - Update older OOB plan docs with a superseded note pointing here.
192
+ - Add a release note marking the change as breaking.
193
+
194
+ ### Stage 6 — Live Dogfood
195
+
196
+ Before merging the code-removal PR:
197
+
198
+ - Start Claude receiver with `tt events --follow --json`.
199
+ - Start Codex receiver the same way.
200
+ - Send direct and broadcast messages both directions.
201
+ - Verify `tt wait --json`, `tt release --stdin`, and `tt assign <agent>` work from harness shell-outs.
202
+ - Verify no MCP subprocess is required for the room to operate.
203
+
204
+ ## Risks
205
+
206
+ - **Harnesses without reliable shell execution.** If a harness cannot run `tt`, it cannot use Talking Stick. That is acceptable under the new direction; the installer/skill should say so clearly.
207
+ - **Lease expiry during long turns.** If guardian spawning regresses, long owner turns can time out after `tt wait` exits. Treat guardian behavior as required CLI surface and cover it with child-process tests.
208
+ - **Per-command process cost.** Repeated `tt` shell-outs pay Node startup and SQLite open cost. Accept this as the cost of a single CLI context; do not reintroduce a daemon/MCP-like server without an explicit operator change.
209
+ - **Long-running receiver lifecycle.** Some harnesses cannot monitor stdout from a running child. Keep `--wait --after` as the supported fallback.
210
+ - **Combined wait/event command ambiguity.** A future `tt await`-style command needs a separate design pass. It must distinguish observer events from ownership results so an agent cannot mistake a message or handoff wake for permission to edit.
211
+ - **Skill drift.** Installed skills may still have old MCP-first text. Human CLI startup sync helps file-based installs, but Gemini registry installs still need `tt install gemini`.
212
+ - **Config cleanup safety.** Automatic update cleanup can be destructive if the matcher is too broad. Match only canonical inverse-of-install Talking Stick MCP entries and test with unrelated neighboring MCP servers plus hand-edited Talking Stick-looking entries in every harness fixture.
213
+ - **Large test deletion.** Removing MCP tests can accidentally reduce protocol coverage. Replace them with CLI tests before deleting assertions.
214
+ - **Diff walker hot path.** A live watcher should not spawn `tt` for every file event. Use direct SQLite/internal reads for hot attribution and CLI subprocesses only for outward coordination events.
215
+
216
+ ## Decisions From Claude Review
217
+
218
+ 1. `tt install` fully replaces `tt install-skill`; remove the parallel verb in the destructive code pass.
219
+ 2. `tt mcp` is removed immediately rather than kept as a migration shim.
220
+ 3. Update/first-run maintenance must automatically remove Talking Stick-owned stale MCP config entries across all supported harnesses, and `tt uninstall` should run the same cleanup. It must not touch unrelated harness config.
221
+ 4. Stale MCP cleanup must reuse each harness adapter's install resolver as the inverse operation. Do not reimplement config matching separately.
222
+ 5. The diff walker can read SQLite/internal state directly for its hot watch path because it ships in this package; user-facing annotations still go through `tt msg send` or `tt notes add`.
223
+ 6. The skill's primary ambient receiver is `tt events --follow --json`, not `tt msg recv --follow`. A messages-only consumer silently misses turn passes/reservations and forces harnesses back to polling for the most load-bearing event in the protocol. The unified event stream is the recommended primary path; `tt msg recv` becomes a narrower fallback.
224
+ 7. Cleanup audit lives in a dedicated `update-migrations.log`, not folded into general maintenance logging. Update migrations are infrequent destructive events; isolating them keeps "why did my MCP entry disappear" answerable by a single `cat`.
@@ -0,0 +1,220 @@
1
+ # v6 converged design — harness instructions
2
+
3
+ > **Status:** converged claude + codex design.
4
+ >
5
+ > **Convergence path:** independent drafts written in parallel, then debated
6
+ > by cross-reference. Outcomes: claude conceded load-mechanism (separate
7
+ > `tt instructions show` call, not piggyback on `tt join`); codex conceded
8
+ > file-structure (single file per layer, not per-harness) and materialization
9
+ > (lazy on edit, never on install). Naming, CLI surface, project-file scope,
10
+ > and bundled-skill scope were already aligned.
11
+ >
12
+ > The pre-debate drafts (`v6-claude.md`, `v6-codex.md`) were deleted after
13
+ > convergence per Wojtek: "if they write something they need to delete the
14
+ > pre-debate versions after convergence."
15
+
16
+ ## Problem
17
+
18
+ v5 collapsed the phase guidance into bundled `SKILL.md`. Wojtek's pushback:
19
+ *"The skill ships with the binary, which means people won't be able to edit. I
20
+ want them to be able to edit, but I still want it to be simple."* `tt install`
21
+ links the bundled skill by default and startup sync can refresh copied
22
+ installs — there is no durable user-edit affordance.
23
+
24
+ v6 fixes this with editable Markdown instructions, seeded lazily, opened with
25
+ `$EDITOR`. Not JSON profiles. Not a config subsystem.
26
+
27
+ ## Shape
28
+
29
+ Two layers of concern, kept separate by design:
30
+
31
+ ### 1. Bundled skill floor (`skills/talking-stick/SKILL.md`)
32
+
33
+ Immutable, package-owned. Covers join, wait, guardian checks, release/handoff,
34
+ event-wake safety, takeover, notes, messages, and the "keep using the stick
35
+ until done" rule. Tells agents how to load the editable collaboration
36
+ instructions. **Does not include phase vocabulary or typical fits** — those
37
+ live in the editable layer with bundled defaults as fallback inside the
38
+ instructions code path, not duplicated into the safety contract.
39
+
40
+ ### 2. Editable collaboration instructions
41
+
42
+ Single Markdown file per layer, with optional per-harness sections inside:
43
+
44
+ ```
45
+ ~/.local/share/talking-stick/instructions.md # user override (optional, XDG-aware)
46
+ <repo>/.talking-stick/instructions.md # project override (optional)
47
+ ```
48
+
49
+ Bundled defaults live as text constants in `src/instructions.ts` — they are
50
+ the seed text and the always-available fallback if no editable file exists.
51
+
52
+ The file uses `## <Harness>` section headers. The effective text for a given
53
+ harness is: shared preamble (everything before the first `##`) + the matching
54
+ harness section.
55
+
56
+ ## Effective-text resolution
57
+
58
+ Additive concatenation in layer order: bundled → user → project. Later layers
59
+ add or override by plain language; the model weighs the concatenated text. No
60
+ merge semantics, no structured fields, no precedence rules beyond "later text
61
+ typically wins by recency." Bundled safety floor (the SKILL.md content)
62
+ remains higher than editable content always — operators cannot use
63
+ instructions to override the coordination safety contract.
64
+
65
+ ## Loading
66
+
67
+ Agents call `tt instructions show --json` once after `tt join` on the first
68
+ substantial task in a room. The command infers the caller's harness from
69
+ identity detection (no `--harness` flag needed). The JSON result includes the
70
+ effective Markdown text and the file paths that contributed to it.
71
+
72
+ If the command fails, agents continue with the bundled `SKILL.md` guidance
73
+ alone. Coordination must never depend on instructions loading successfully.
74
+
75
+ `tt join` returns membership/coordination state only; instructions are
76
+ deliberately separate.
77
+
78
+ ## CLI surface
79
+
80
+ ```
81
+ tt instructions show [--harness <name>] [--scope effective|user|project|bundled] [--json]
82
+ tt instructions edit [--user|--project]
83
+ tt instructions reset [--user|--project]
84
+ ```
85
+
86
+ - `show` defaults to `--scope effective` and the detected current harness.
87
+ - `edit` opens `$VISUAL`, then `$EDITOR`, then a platform default if available;
88
+ prints the file path if no editor is found. Defaults to `--user`.
89
+ - `edit` materializes the seed text on first use, then opens the editor.
90
+ Subsequent edits open the existing file in place.
91
+ - `reset` requires explicit scope (no implicit `--user`); deletes the file at
92
+ the chosen scope so the layer below wins again.
93
+
94
+ **Cut from both drafts:** `set`/`append`/`init`/`diff`. Editor-only for v1.
95
+ Agents holding the stick can write to `<repo>/.talking-stick/instructions.md`
96
+ directly via filesystem.
97
+
98
+ ## Materialization
99
+
100
+ Lazy on first `tt instructions edit`, never on `tt install`. Reasoning:
101
+ - Operators who never customize stay on shipped defaults forever — package
102
+ updates flow through automatically with no stale local copies.
103
+ - Operators who customize get a one-time materialization at the moment they
104
+ show intent (running `edit`).
105
+ - `tt install` stays fast and scriptable; no extra files written.
106
+
107
+ `tt install` final output gains one hint:
108
+
109
+ ```
110
+ Customize collaboration instructions with: tt instructions edit
111
+ ```
112
+
113
+ No interactive prompt.
114
+
115
+ ## Bundled defaults (content)
116
+
117
+ Text constants in `src/instructions.ts`. Short. Cover:
118
+
119
+ - the "keep using Talking Stick until the shared task is done" rule,
120
+ including "prefer continued action unless the task is complete or the
121
+ operator explicitly redirects/stops",
122
+ - the phase vocabulary: draft, adversarial review, convergence,
123
+ implementation, implementation review, test review, release,
124
+ - typical fits (advisory, not enforced):
125
+ - Claude: prose, first-pass synthesis, tool-running, implementation review,
126
+ test review.
127
+ - Codex: adversarial review, convergence, implementation, edge cases,
128
+ release mechanics after operator approval.
129
+ - Gemini/OpenCode: conservative starter guidance until dogfood gives
130
+ evidence.
131
+
132
+ These are defaults, not a scheduler. Talking Stick does not auto-route turns
133
+ based on them.
134
+
135
+ ## Parallel drafting without workspace clutter
136
+
137
+ Wojtek's target default is independent read-only planning first, then debate
138
+ until convergence. His concern was not the independent thinking; it was
139
+ workspace clutter and imposed file structure: *"I'm not sure I want to default
140
+ to the models writing drafts or imposing a file structure on the workspace. I
141
+ guess maybe if they write something they need to delete the pre-debate versions
142
+ after convergence."*
143
+
144
+ So the default is **read-only independent drafts**, not repo draft files.
145
+ Rules when this happens:
146
+
147
+ - **Drafts go in handoff `status` text or room notes by default**, not in
148
+ workspace files. Coordination channels are the natural place for read-only
149
+ position exchange.
150
+ - **If files are unavoidable** (drafts too long for handoffs/notes), use
151
+ files in `docs/plans/` with clear `*-<harness>-draft.md` naming, and
152
+ **delete them after convergence**. Only the converged artifact remains.
153
+ - Single-agent rooms and tiny tasks can skip parallel drafting.
154
+ - The default for larger multi-agent planning is: draft independently, debate,
155
+ converge, then write only the converged artifact if a workspace file is
156
+ useful.
157
+
158
+ This is still prompt guidance, not protocol. Talking Stick does not create
159
+ draft files, track phases, or auto-route turns based on this pattern.
160
+
161
+ ## What we explicitly do not build
162
+
163
+ - No JSON config, no schema, no validator beyond a soft size cap on read.
164
+ - No structured merge semantics. Plain Markdown concatenation.
165
+ - No `set`/`append`/`init`/`diff` commands.
166
+ - No materialization on install.
167
+ - No phase tracking in the protocol. No `tt phase set`. No `phase` field in
168
+ handoff types.
169
+ - No `tt state` rendering changes.
170
+ - No model overlays.
171
+ - No auto-routing by harness.
172
+ - No instruction-text override of the bundled safety floor.
173
+
174
+ ## Implementation order
175
+
176
+ 1. `src/instructions.ts` — bundled default text constants, layer resolver
177
+ (bundled → user → project, additive concatenation), XDG-aware path
178
+ resolution, `## <Harness>` section parser, soft size cap.
179
+ 2. Add `tt instructions show` (CLI + service plumbing).
180
+ 3. Add `tt instructions edit` with `$VISUAL` / `$EDITOR` / platform fallback.
181
+ Materializes seed on first use.
182
+ 4. Add `tt instructions reset`.
183
+ 5. Edit bundled `SKILL.md`: keep current safety contract, add one short line
184
+ pointing agents at `tt instructions show --json` after first `tt join`.
185
+ 6. Update `tt install` final output with the customize hint.
186
+ 7. Tests: `tests/instructions.test.ts` for layer resolution, missing files,
187
+ materialization-only-on-edit, section parsing, additive concatenation,
188
+ bundled-fallback when commands fail. Extend `tests/cli.test.ts` for the
189
+ new commands.
190
+ 8. README: replace `tt install-skill` references with `tt install`; add a
191
+ short paragraph on `tt instructions edit` for customization.
192
+ 9. Release notes entry.
193
+
194
+ ## Acceptance criteria
195
+
196
+ - A fresh user can install with `npm i -g talking-stick && tt install --all`
197
+ and get useful defaults without answering prompts.
198
+ - The same user can run `tt instructions edit` and customize collaboration
199
+ behavior in `$EDITOR`.
200
+ - A package update never overwrites the user's instruction file.
201
+ - An agent runs one command after join (`tt instructions show --json`) and
202
+ receives effective instruction text + source paths.
203
+ - If instruction loading fails, the bundled `SKILL.md` still gives enough
204
+ guidance to coordinate safely (agents will lack phase vocabulary but
205
+ coordination/safety remains intact).
206
+ - No new protocol state, no role enforcement, and no auto-routing are added.
207
+
208
+ ## Process notes (meta)
209
+
210
+ This convergence used parallel-drafting one-off. Each harness wrote an
211
+ independent v6 draft without reading the other's first. Both landed near
212
+ the same shape but differed on three points (file structure, load
213
+ mechanism, materialization). Reading both drafts side by side made the
214
+ real trade-offs visible quickly; concessions went both ways within one
215
+ round.
216
+
217
+ The pre-debate draft files were deleted after convergence per Wojtek. The
218
+ parallel-drafting workflow is captured above as an *optional* operator-
219
+ driven pattern, not a shipped default — to avoid imposing file structure
220
+ on workspaces by default.
@@ -350,7 +350,7 @@ Four bound parameters of the caller's agent_id. Acceptable; SQLite's planner han
350
350
  Add three policy values:
351
351
 
352
352
  ```ts
353
- waitForEventsMaxWaitMs: number; // default 30_000 (matches waitForTurn)
353
+ waitForEventsMaxWaitMs: number; // default 110_000 (matches waitForTurn)
354
354
  waitForEventsPollMs: number; // default 250 (matches waitForTurn)
355
355
  waitForEventsBatchLimit: number; // default 100
356
356
  ```
@@ -662,7 +662,7 @@ The talking stick guarantees single-writer authority over shared workspace state
662
662
 
663
663
  **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` flags the message as time-sensitive; the receiver decides whether to act on it now.
664
664
 
665
- **Receive.** Use the receive mode your harness can actually 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. SIGTERM exits cleanly; restart with `--after <last_event_seq>` to resume.
665
+ **Receive.** Use the receive mode your harness can actually observe. If it can monitor stdout from a long-running child, run `tt events --follow`; each incoming event lands as one JSON line. If it can only notice that a background command completed, run `tt events --wait --after <last_event_seq>`; it exits on the next matching batch, then you start it again with the returned cursor. SIGTERM exits cleanly; restart with `--after <last_event_seq>` to resume. Use `tt msg recv` only for messages-only consumers that intentionally do not want turn handoff events.
666
666
 
667
667
  **When to message vs note vs handoff.**
668
668
 
@@ -672,12 +672,12 @@ The talking stick guarantees single-writer authority over shared workspace state
672
672
 
673
673
  **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 ACL.
674
674
 
675
- **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.
675
+ **Messages and event wakes do not grant the stick.** A non-holder paging the holder does not gain write authority, and a receiver waking on `pass`, `release`, or `assignment` still has to run `tt wait` and receive `your_turn` before editing. The holder may act on the message immediately or defer until handoff.
676
676
 
677
- **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.
677
+ **Stay in the wait loop in parallel.** A `tt events --wait`, `tt events --follow`, or `tt msg recv` subprocess does not replace `wait_for_turn`. Keep waiting for your turn; receive processes are side channels.
678
678
  ```
679
679
 
680
- Also: a one-line addition to §1 ("Check that Talking Stick is available") noting that `tt msg recv --wait` / `--follow` may be running as sibling processes and should be left alone.
680
+ Also: a one-line addition to §1 ("Check that Talking Stick is available") noting that `tt events --follow`, `tt msg recv --wait`, or `tt msg recv --follow` may be running as sibling processes and should be left alone.
681
681
 
682
682
  ### 4.1 Skill propagation
683
683
 
@@ -1,6 +1,6 @@
1
1
  # Receive Consumer Contract
2
2
 
3
- `send_message` appends `message_sent` events to the room event log. `wait_for_events` is the canonical receive primitive. CLI consumers (`tt msg recv --wait`, `tt msg recv --follow`) and future harness-native consumers should share the same cursor and retry rules.
3
+ `send_message` appends `message_sent` events to the room event log. `wait_for_events` is the canonical receive primitive. CLI consumers (`tt events --wait`, `tt events --follow`, `tt msg recv --wait`, `tt msg recv --follow`) and future harness-native consumers should share the same cursor and retry rules.
4
4
 
5
5
  ## Delivery
6
6
 
@@ -11,20 +11,22 @@
11
11
 
12
12
  ## Receive Modes
13
13
 
14
- - Use `tt msg recv --follow --after <cursor>` when the harness can monitor stdout from a long-running child. Each output line is one `RoomEvent` JSON object.
15
- - Use `tt msg recv --wait --after <cursor>` when the harness can only notice process completion. The process exits after the next matching batch or timeout; restart it with the latest processed cursor.
14
+ - Use `tt events --follow --after <cursor>` when the harness can monitor stdout from a long-running child. Each output line is one `RoomEvent` JSON object.
15
+ - Use `tt events --wait --after <cursor>` when the harness can only notice process completion. The process exits after the next matching batch or timeout; restart it with the latest processed cursor.
16
+ - Use `tt msg recv --wait` or `tt msg recv --follow` only when the consumer intentionally wants messages without turn handoffs.
16
17
  - If no `--after` is supplied in `--wait` or `--follow` mode, the CLI starts from the current event tail to avoid flooding a new consumer with history.
17
18
  - A one-shot `tt msg recv --after <cursor>` is a non-blocking drain operation.
18
19
 
19
20
  ## Filtering
20
21
 
21
- - `target=self` receives direct messages to the caller plus broadcasts from other agents. It excludes the caller's own broadcasts.
22
- - `target=any` receives all matching messages and is intended for audit/debug views.
22
+ - `target=self` is the default for `--wait` and `--follow`. It receives direct messages to the caller plus broadcasts from other agents. It excludes the caller's own broadcasts.
23
+ - `target=any` receives all matching events/messages and is intended for audit/debug views.
23
24
  - `--from <agent>` resolves a full `agent_id` or unambiguous active display name and is enforced server-side.
24
25
 
25
26
  ## Consumer Responsibilities
26
27
 
27
- - Keep `wait_for_turn` running separately. Message receive processes do not claim or grant the stick.
28
+ - Keep `wait_for_turn` / `tt wait` running separately. Receive processes do not claim or grant the stick, even when they return pass, release, or assignment events.
29
+ - Treat an event wake as a prompt to read, reply, or retry `tt wait`. It is not permission to mutate shared files; only a `your_turn` wait result with a live guardian grants ownership.
28
30
  - Decide how to surface `delivery_hint=interrupt`; the server only records the hint.
29
31
  - Dedupe on `event_id` if restart replay is possible.
30
32
  - Treat message bodies as room-visible text, not private data.
@@ -0,0 +1,77 @@
1
+ # Talking Stick 0.3.0
2
+
3
+ Date: 2026-05-05
4
+
5
+ Breaking release that makes the `tt` CLI the only harness integration contract.
6
+ Talking Stick no longer installs or serves an MCP adapter. Agents coordinate by
7
+ running `tt` subprocesses for join/wait/handoff, notes, messages, and event
8
+ receive.
9
+
10
+ ## Breaking Changes
11
+
12
+ ### MCP server surface removed
13
+
14
+ Removed the MCP stdio server implementation, `tt mcp` command registration,
15
+ MCP-specific tests, and the `@modelcontextprotocol/sdk` dependency. The package
16
+ exports no MCP server helpers. `tt --help` no longer advertises MCP startup, and
17
+ `tt install` no longer writes MCP server config.
18
+
19
+ ### `tt install` is skill-only
20
+
21
+ `tt install <harness>` now installs or refreshes the bundled
22
+ `talking-stick` skill for Claude Code, Codex, Gemini, and OpenCode. The older
23
+ `tt install-skill` and `tt uninstall-skill` command surface is gone because
24
+ `tt install` / `tt uninstall` own skill installation directly.
25
+
26
+ ## Migration
27
+
28
+ ### Stale MCP cleanup
29
+
30
+ Updates remove stale Talking Stick MCP registrations from older installs instead
31
+ of keeping the broken dual integration path alive.
32
+
33
+ Cleanup runs from:
34
+
35
+ - package postinstall when installed under `node_modules/talking-stick`
36
+ - `tt self-update` after the package manager command returns
37
+ - the first normal installed-package `tt` invocation after a package-version
38
+ change
39
+ - explicit `tt install` and `tt uninstall`
40
+
41
+ Each run appends JSONL audit entries to
42
+ `${TALKING_STICK_DATA_DIR}/update-migrations.log`. OpenCode cleanup is
43
+ shape-strict: only the canonical `mcp.talking-stick` entry with `["tt", "mcp"]`
44
+ is removed. Claude Code, Codex, and Gemini use their native `mcp remove`
45
+ commands for the old `talking-stick` server name.
46
+
47
+ ## CLI-Only Runtime
48
+
49
+ The bundled skill now teaches harnesses to start
50
+ `tt events --follow --json` as the ambient receiver, keep
51
+ `tt wait --json` running for turn ownership, and verify the
52
+ returned guardian pid before long edits. `tt msg recv` remains a messages-only
53
+ fallback; the unified event stream is the primary OOB path because turn
54
+ handoffs and messages share one ordered feed.
55
+
56
+ For harnesses that cannot consume a long-running stdout stream, the documented
57
+ fallback is `tt events --wait --after <cursor> --json` as an observer-only wake
58
+ process alongside the normal `tt wait --json` ownership loop. Event wakes do not
59
+ grant the stick; agents still need a `your_turn` wait result and live guardian
60
+ before editing.
61
+
62
+ CLI identity resolution now prefers stable harness ancestry over transient
63
+ terminal ids when no explicit harness session id exists. That keeps repeated
64
+ shell-outs from one harness attached to the same room member.
65
+
66
+ ## Verification
67
+
68
+ ```bash
69
+ npm run typecheck
70
+ npm test
71
+ npm run build
72
+ git diff --check
73
+ ```
74
+
75
+ Stage validation covered the migration runner, install/uninstall/self-update
76
+ cleanup wiring, child-process CLI receive behavior, guardian repair, full-suite
77
+ tests after MCP deletion, and built `dist/` output with no MCP/server files.