dsh-tower 2.0.3 → 2.0.4

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.
Files changed (52) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/README.en.md +19 -13
  3. package/README.md +19 -13
  4. package/SECURITY.md +4 -1
  5. package/docs/README.md +30 -0
  6. package/docs/architecture/overview.md +3 -2
  7. package/docs/examples/first-mission.md +2 -1
  8. package/docs/faq.md +11 -7
  9. package/docs/guide/install-upgrade-migration.md +14 -5
  10. package/docs/guide/quickstart.md +12 -7
  11. package/docs/guide/scenarios-and-philosophy.md +86 -69
  12. package/docs/operations/security.md +18 -12
  13. package/docs/reference/blockers.md +11 -10
  14. package/docs/reference/config.md +7 -6
  15. package/docs/reference/errors.md +7 -1
  16. package/docs/reference/events.md +7 -4
  17. package/docs/reference/testing.md +2 -1
  18. package/docs/reference/tools.md +7 -6
  19. package/docs/zh/README.md +1 -1
  20. package/docs/zh/faq.md +9 -6
  21. package/docs/zh/guide/install-upgrade-migration.md +11 -4
  22. package/docs/zh/guide/quickstart.md +13 -8
  23. package/docs/zh/guide/scenarios-and-philosophy.md +55 -50
  24. package/docs/zh/operations/security.md +13 -6
  25. package/docs/zh/reference/blockers.md +10 -10
  26. package/docs/zh/reference/config.md +7 -6
  27. package/docs/zh/reference/errors.md +2 -1
  28. package/docs/zh/reference/events.md +6 -3
  29. package/docs/zh/reference/testing.md +3 -2
  30. package/docs/zh/reference/tools.md +7 -6
  31. package/index.js +26 -17
  32. package/lib/config.js +100 -6
  33. package/lib/doctor.js +11 -5
  34. package/lib/errors.js +14 -2
  35. package/lib/git.js +36 -2
  36. package/lib/modeStore.js +54 -20
  37. package/lib/store.js +65 -10
  38. package/lib/tests.js +35 -1
  39. package/lib/tools.js +257 -47
  40. package/lib/tower.js +268 -45
  41. package/lib/workspaceLock.js +44 -20
  42. package/package.json +3 -2
  43. package/scripts/check-docs.mjs +35 -0
  44. package/skills/tower-recovery.md +7 -5
  45. package/ui-bundle/README.md +111 -0
  46. package/ui-bundle/client.js +1980 -0
  47. package/ui-bundle/cordis.patch.yml +3 -0
  48. package/ui-bundle/icon.svg +6 -0
  49. package/ui-bundle/index.js +2 -0
  50. package/ui-bundle/locale/en.json +6 -0
  51. package/ui-bundle/locale/zh.json +6 -0
  52. package/ui-bundle/package.json +35 -0
@@ -3,14 +3,15 @@
3
3
  [简体中文](../zh/guide/scenarios-and-philosophy.md)
4
4
 
5
5
  Tower is not a replacement for every multi-agent pattern. It is a **delivery protocol for changes to a
6
- Git repository**: a small number of bounded missions, isolated writers, independent review, evidence,
7
- and a merge gate. This page explains the design choices behind it, the situations where it pays off,
8
- and when Agent Teams, Ralph loops, Workflow orchestration, or ordinary parallel subagents are a better
9
- fit.
6
+ Git repository**: a small number of bounded missions, isolated writers, optional independent review,
7
+ evidence, and a merge gate. This page explains the design choices behind it, the situations where it
8
+ pays off, and when Agent Teams, Ralph loops, Workflow orchestration, or ordinary parallel subagents are
9
+ a better fit.
10
10
 
11
- If you only remember one sentence: **use Tower when the output is a reviewed, integrated repository
12
- change; use the other patterns when the output is exploration, repeated attempts, or programmatic
13
- fan-out.**
11
+ If you only remember one sentence: **use Tower when the output is an integrated repository change that
12
+ must land through a controlled merge; use the other patterns when the output is exploration, repeated
13
+ attempts, or programmatic fan-out.** Enable `review.requireReview` when the change also needs an
14
+ independent reviewer.
14
15
 
15
16
  ## 1. The design philosophy
16
17
 
@@ -19,8 +20,8 @@ Tower makes several deliberate trade-offs. They explain both its strengths and i
19
20
  ### 1.1 The repository is the unit of accountability
20
21
 
21
22
  A mission is not a chat thread or a task card. It is a contract attached to a branch and a worktree,
22
- with a declared write scope, dependencies, completion evidence, and a review record. The question
23
- "what changed, who changed it, and what proved it?" has a durable answer in
23
+ with a declared write scope, dependencies, completion evidence, and an optional review record. The
24
+ question "what changed, who changed it, and what proved it?" has a durable answer in
24
25
  `<git-common-dir>/dsh-tower/state.json` and the Git history, not only in a conversation.
25
26
 
26
27
  ### 1.2 One writer per mission
@@ -38,15 +39,17 @@ requirements are still being discovered.
38
39
 
39
40
  ### 1.4 Integration is a separate, privileged step
40
41
 
41
- Workers never merge. A reviewer inspects a specific branch tip; the tower runs preflight; only then
42
- does `tower_merge` perform a `--no-ff` merge. The gate re-checks scope, base freshness, tasks, review
43
- binding, worktree ownership, worker state, tests, and evidence. Separation of duties is the point:
44
- the agent that wrote the code is not the agent that approves it, and neither is the agent that merges.
42
+ Workers never merge. The tower runs preflight; only then does `tower_merge` perform a `--no-ff` merge.
43
+ The gate re-checks scope, base freshness, tasks, worktree ownership, worker state, tests, and evidence.
44
+ When review is enabled, a reviewer also inspects a specific branch tip and the gate checks the review
45
+ binding. Separation of duties is the point when review is on: the agent that wrote the code is not the
46
+ agent that approves it, and neither is the agent that merges.
45
47
 
46
48
  Independent review is optional by default: `review.requireReview:true` enforces it (and then a complete
47
49
  mission must carry a clean, merge-approved review from a reviewer bound to the branch tip). Set the flag
48
- to `true` for sensitive repositories; `reviewPolicy:"none"` + a reason remains available as a per-mission
49
- exemption when the global gate is on. Reviews can be submitted and recorded either way.
50
+ to `true` for sensitive repositories; `reviewPolicy:"none"` + a reason + `gates.allowReviewExemption:true`
51
+ remains available as a per-mission exemption when the global gate is on. Reviews can be submitted and
52
+ recorded either way.
50
53
 
51
54
  ### 1.5 Evidence over assertion
52
55
 
@@ -58,18 +61,20 @@ close a finite set of missions only when their required evidence exists.
58
61
  ### 1.6 Fail closed, recover explicitly
59
62
 
60
63
  Tower prefers a visible blocker over a silent repair. A stale worker is marked, not assumed dead; a
61
- dirty base blocks a merge; a moved review tip blocks a merge; a crash during merge leaves a persistent
62
- intent that the next `tower_merge` reconciles. The cost is occasional manual cleanup; the benefit is
63
- that state never lies about what was integrated.
64
+ dirty base blocks a merge; with the review gate on, a moved review tip blocks a merge; a crash during
65
+ merge leaves a persistent intent that the next `tower_merge` reconciles. The cost is occasional manual
66
+ cleanup; the benefit is that state never lies about what was integrated.
64
67
 
65
- ### 1.7 The human owns the mode
68
+ ### 1.7 Mode control is explicit and attributable
66
69
 
67
70
  Tower mode changes the session's stance: it narrows the tool surface and injects the mission protocol.
68
- The shipped patch allows the model to toggle it with a stated reason, but the mode exists because a
69
- human asked for delivery discipline. Entering pauses an active goal and clears plan mode; leaving does
70
- not silently resume either. Tower intentionally refuses `goal`, `todo`, Team task-board, Workflow,
71
- Ralph, and ordinary subagent tools while it is active, so two orchestration protocols do not fight over
72
- one session.
71
+ The user can always change it with `/tower`; by default the model can also enter or leave with
72
+ `tower_control`, provided it states a concrete reason. Every change records the actor and reason. The
73
+ design point is not that one side owns the switch, but that toggling is deliberate and visible; set
74
+ `mode.allowAgentControl:false` if a deployment wants human-only control. Entering pauses an active goal
75
+ and clears plan mode; leaving does not silently resume either. Tower intentionally refuses `goal`,
76
+ `todo`, Team task-board, Workflow, Ralph, and ordinary subagent tools while it is active, so two
77
+ orchestration protocols do not fight over one session.
73
78
 
74
79
  ### 1.8 Local-first, no hidden service
75
80
 
@@ -86,7 +91,7 @@ The table is the quick version; the subsections below explain each row.
86
91
  | A feature with independent slices | Add OAuth: `token model` → `callback route` → `UI button` + a migration, four missions with mostly separate scopes | Isolated writers, scope reservation, one final review/merge |
87
92
  | Ordered refactor/migration | Rename `oldApi` across a monorepo: codemod → import cleanup → snapshots → docs, each depending on the previous merge | `deps`, branch freshness, serialized merges |
88
93
  | Investigation then change | A survey mission maps every caller of a deprecated crypto API; two build missions migrate and test | Survey cannot mutate; findings feed build missions |
89
- | Sensitive or release-bound change | A payments service change or a public library release needing a reviewed commit and test evidence | Review binding, checks/runs, human-readable audit |
94
+ | Sensitive or release-bound change | A payments service change or a public library release needing test evidence and an auditable merge (enable review for an independent verdict) | Checks/runs, optional review binding, human-readable audit |
90
95
  | Long-running work | A multi-day dependency upgrade interrupted by restarts and context resets | Durable mission/roster/review/worktree state |
91
96
  | Hard integration boundary | Four services in one monorepo, each with an owner, then one release review | Parallel missions with a single merge gate |
92
97
  | Checkable definition of done | A task list plus required tests plus an optional independent review verdict | Completion/review evidence is visible to another agent |
@@ -122,11 +127,13 @@ silently widening it.
122
127
 
123
128
  ### 2.4 A sensitive repository or a release-bound change
124
129
 
125
- Example: a payments service, a library with external users, or a release branch. You want an
126
- independent reviewer, a specific reviewed commit, test evidence, and a human-visible audit trail.
130
+ Example: a payments service, a library with external users, or a release branch. You want test
131
+ evidence and a human-visible audit trail; when review is enabled, you also get an independent reviewer
132
+ and a verdict bound to a specific reviewed commit.
127
133
 
128
- **Why Tower:** review binding, evidence gates, `MISSIONS.md`, activity log, and optional test discovery
129
- give you a defensible record. The reviewer is a separate read-only agent, not the author.
134
+ **Why Tower:** evidence gates, `MISSIONS.md`, and the activity log give you a defensible record;
135
+ when review is enabled, the reviewer is a separate read-only agent, not the author, and the verdict is
136
+ bound to the tip.
130
137
 
131
138
  ### 2.5 Long-running work that spans context compaction or restarts
132
139
 
@@ -155,11 +162,11 @@ the chat", Tower is overhead.
155
162
 
156
163
  | Situation | Better fit | Why |
157
164
  |---|---|---|
158
- | One-file edit, typo, small hotfix | Ordinary agent in a single session | Worktree, review, and merge overhead dominate. |
165
+ | One-file edit, typo, small hotfix | Ordinary agent in a single session | Worktree and merge overhead (plus review when enabled) dominate. |
159
166
  | Requirements are still being discovered | Ordinary agent, Plan mode, or Agent Teams | Tower asks for scope/tasks before work; a wrong contract causes re-planning. |
160
167
  | Open-ended research or brainstorming | Agent Teams, Workflow, or plain subagents | There is no repository change to isolate or merge. |
161
- | Many tiny independent tasks | Workflow or plain parallel subagents | Per-mission review/merge cost is too high. |
162
- | Interactive UI pairing / exploratory debugging | Ordinary agent (or a single worker) | Tight feedback loops and frequent human steering; the review gate adds latency. |
168
+ | Many tiny independent tasks | Workflow or plain parallel subagents | Per-mission merge cost (and review when enabled) is too high. |
169
+ | Interactive UI pairing / exploratory debugging | Ordinary agent (or a single worker) | Tight feedback loops and frequent human steering; an enabled review gate adds latency. |
163
170
  | A one-shot generation with no integration | Plain subagent/Workflow | No branch, no review, no merge decision. |
164
171
  | Cross-repository product work | Agent Teams + ordinary tools | Tower is scoped to one Git repository. |
165
172
 
@@ -172,11 +179,11 @@ integration, and what "done" means.**
172
179
 
173
180
  | Dimension | Tower | Agent Teams | Ralph loop | Workflow orchestration | Ordinary parallel subagents |
174
181
  |---|---|---|---|---|---|
175
- | Primary goal | Deliver reviewed repository changes | Collaborate across people/agents on a shared goal | Repeated fresh attempts at one objective | Programmatic fan-out/pipeline of agent work | Explore or implement in parallel |
182
+ | Primary goal | Deliver integrated repository changes (optional independent review) | Collaborate across people/agents on a shared goal | Repeated fresh attempts at one objective | Programmatic fan-out/pipeline of agent work | Explore or implement in parallel |
176
183
  | Unit of work | Mission (branch + worktree + scope + tasks + review) | Task/teammate on a shared board | Round/attempt | Scripted step/stage | Prompt/task per child |
177
184
  | Isolation | Git worktree + branch per mission; one writer per mission | Shared workspace; coordination by task ownership | Fresh child per round; no built-in branch/merge contract | Per-step child; no Git isolation | Child sessions; may share workspace |
178
185
  | Durable state | Git metadata + JSON state + activity + board | Team task board + sessions | Minimal; each round starts fresh | Run record/results; not a merge ledger | Session/subagent records |
179
- | Integration authority | Tower only, after review + gate | Humans/teammates merge or edit manually | Usually the parent/worker applies results | Script applies results | Parent applies results |
186
+ | Integration authority | Tower only, after preflight/gate (plus review when enabled) | Humans/teammates merge or edit manually | Usually the parent/worker applies results | Script applies results | Parent applies results |
180
187
  | Review / gate | Optional independent review (enable `review.requireReview`) + preflight/merge gate | Review is a collaboration convention, not a hard gate | No built-in review gate | No built-in review gate | No built-in review gate |
181
188
  | Parallelism | Multiple missions, disjoint scopes, serialized merges | Many teammates, shared board | Sequential rounds (or external fan-out) | High fan-out, script-controlled | High fan-out |
182
189
  | Human role | Owns the mode; can inspect evidence and release | Collaborator/coordinator | Author of the repeated objective | Author of the orchestration script | Delegator |
@@ -187,11 +194,13 @@ integration, and what "done" means.**
187
194
 
188
195
  Ordinary `subagent`/`subagent_fork` calls are cheap and flexible. They are the right tool for "read
189
196
  these five files in parallel" or "try three approaches". They do not provide a write scope, a
190
- dedicated worktree, a durable mission, an independent review, or a merge gate. Tower wraps the same
191
- subagent primitive in those contracts; it also costs more per child.
197
+ dedicated worktree, a durable mission, independent review, or a merge gate. Tower wraps the same
198
+ subagent primitive in those contracts; it also costs more per child. (Review is optional: enable
199
+ `review.requireReview` when you need the reviewer role.)
192
200
 
193
201
  Choose subagents when the work is read-mostly, short-lived, or you will integrate the result
194
- yourself. Choose Tower when the result must land on a branch and survive a review.
202
+ yourself. Choose Tower when the result must land on a branch under a controlled merge; enable review
203
+ when it must also survive independent review.
195
204
 
196
205
  ### 4.2 Tower vs Agent Teams
197
206
 
@@ -199,11 +208,11 @@ Agent Teams is a **collaboration** pattern: a shared task board, durable teammat
199
208
  and interrupt, and a human/Lead coordinating work. It is excellent when the work is cross-cutting,
200
209
  exploratory, or needs several perspectives, and when the integration decision is human.
201
210
 
202
- Tower is a **delivery** pattern: mission contracts, Git isolation, review, and a hard merge gate. It
203
- has less flexible peer-to-peer coordination and more structure. Agent Teams can decide *what* to
204
- build and *whether* to proceed; Tower can then execute that decision as missions. They are sequential
205
- or complementary, not concurrent: Tower mode refuses the Team task-board tools so the two protocols do
206
- not compete for the same session.
211
+ Tower is a **delivery** pattern: mission contracts, Git isolation, an optional review gate, and a hard
212
+ merge gate. It has less flexible peer-to-peer coordination and more structure. Agent Teams can decide
213
+ *what* to build and *whether* to proceed; Tower can then execute that decision as missions. They are
214
+ sequential or complementary, not concurrent: Tower mode refuses the Team task-board tools so the two
215
+ protocols do not compete for the same session.
207
216
 
208
217
  ### 4.3 Tower vs Ralph loop
209
218
 
@@ -211,9 +220,10 @@ Ralph runs the **same objective** through fresh agents, round after round, with
211
220
  memory. It is useful for iterative search, flaky repair, or "try again with fresh context". It has no
212
221
  mission contract, no independent review, and no merge gate.
213
222
 
214
- Tower is incremental: each mission has a bounded deliverable and lands through review. If the problem
215
- is "I do not know whether this can be done, and repeated fresh attempts may find a way", Ralph is
216
- often better. If the problem is "I know the slices; build and integrate them safely", Tower is better.
223
+ Tower is incremental: each mission has a bounded deliverable and lands through the merge gate (with
224
+ review when enabled). If the problem is "I do not know whether this can be done, and repeated fresh
225
+ attempts may find a way", Ralph is often better. If the problem is "I know the slices; build and
226
+ integrate them safely", Tower is better.
217
227
  You can use Ralph outside Tower mode to find an approach, then encode the result as Tower missions.
218
228
 
219
229
  ### 4.4 Tower vs Workflow orchestration
@@ -225,8 +235,8 @@ Git worktree, a review verdict, or a merge gate.
225
235
 
226
236
  Tower is a **repository delivery protocol** with a small number of missions, not a high-fan-out data
227
237
  plane. Use Workflow for "analyze 200 files in parallel"; use Tower for "make the 6 changes those
228
- analyses justify, with review and a merge". Tower mode refuses Workflow so a script cannot spawn
229
- competing writers under the Tower contract.
238
+ analyses justify, with an optional review and a merge gate". Tower mode refuses Workflow so a script
239
+ cannot spawn competing writers under the Tower contract.
230
240
 
231
241
  ### 4.5 Tower vs Plan mode
232
242
 
@@ -241,12 +251,12 @@ Tower to discover the plan for you.
241
251
  low-risk repositories, scratch work, or human-supervised sessions. Set it to `true` to enforce the
242
252
  independent review gate; the gate then re-checks `no-review`, `not-clean`, `review-hold`,
243
253
  `review-not-approved`, `tip-moved`, and `review-mission-mismatch`. `tower_review` is always available
244
- and records verdicts even when the gate is off. For one mission only, prefer `reviewPolicy:"none"` + a
245
- reason while the global gate is on.
254
+ and records verdicts even when the gate is off. For one mission only, with the global gate on, set
255
+ `reviewPolicy:"none"` + a reason and `gates.allowReviewExemption:true`.
246
256
 
247
- ### 4.6 Concrete examples by workflow
257
+ ### 4.7 Concrete examples by workflow
248
258
 
249
- **Tower** — output is a repository change that must land through isolation and review:
259
+ **Tower** — output is a repository change that must land through isolation and a merge gate:
250
260
 
251
261
  - **OAuth login**: four missions (`token model`, `callback route`, `accept/decline API`, `UI`); the API depends on tokens and email.
252
262
  - **Node 18 → 22 upgrade**: survey breaking API usages, then codemod, test updates, CI config, release notes as separate missions.
@@ -286,7 +296,7 @@ reason while the global gate is on.
286
296
 
287
297
  1. Workflow audits 200 files → structured findings.
288
298
  2. Agent Teams reviews the findings and decides the top six changes.
289
- 3. Tower missions implement those six changes with review and merge.
299
+ 3. Tower missions implement those six changes with optional review and a merge gate.
290
300
  4. Ralph is used after merge only for a stubborn flaky test that does not need a new mission contract.
291
301
 
292
302
  ## 5. Worked scenarios
@@ -299,29 +309,31 @@ A team wants "organization invitations": token model, email delivery, accept/dec
299
309
  `src/ui/invites/**`; make the API depend on tokens and email.
300
310
  2. Spawn workers for the independent missions; the API waits for its deps.
301
311
  3. Each worker commits on its branch, completes with checks.
302
- 4. Spawn reviewers; a clean+merge review is required.
312
+ 4. With `review.requireReview:true`, spawn reviewers and require a clean+merge verdict; otherwise
313
+ review is optional.
303
314
  5. `tower_preflight` and `tower_merge` each mission; resolve scope/base/review blockers.
304
315
  6. `tower_teardown`; `MISSIONS.md` is the human-readable record.
305
316
 
306
317
  **Why not Team/Workflow?** The work is a known set of repository changes that must land in a specific
307
- order with independent review. Team tasks would not isolate writes; Workflow would analyze but not
308
- gate the merge.
318
+ order under a merge gate (and optional independent review). Team tasks would not isolate writes;
319
+ Workflow would analyze but not gate the merge.
309
320
 
310
321
  ### Scenario B: migration with a survey
311
322
 
312
323
  1. Survey mission: "map all callers of `oldApi`"; scope empty, read-only.
313
324
  2. Build missions: codemod, test updates, docs; depend on the survey's findings.
314
- 3. Reviewers check the diff against the survey; tests must pass for the reviewed tip.
325
+ 3. With review enabled, reviewers check the diff against the survey; the tests gate still validates the
326
+ current branch tip. With the default optional review, skip the reviewer and rely on the same gate/tests.
315
327
  4. Merge in dependency order.
316
328
 
317
329
  **Why not plain subagents?** The survey must not accidentally mutate; the codemod must not touch
318
- out-of-scope files; the review must bind to the exact commit.
330
+ out-of-scope files; with review enabled, the review must bind to the exact commit.
319
331
 
320
332
  ### Scenario C: incident hotfix
321
333
 
322
334
  A one-line fix in production. Use an ordinary agent, commit and push through your normal process.
323
- Tower would add a worktree, a reviewer, a gate, and a merge step; for a one-line urgent fix that is
324
- mostly latency. If the "hotfix" is actually several coordinated changes, Tower becomes reasonable.
335
+ Tower would add a worktree, a merge gate, and (if enabled) a reviewer; for a one-line urgent fix that
336
+ is mostly latency. If the "hotfix" is actually several coordinated changes, Tower becomes reasonable.
325
337
 
326
338
  ### Scenario D: broad codebase audit
327
339
 
@@ -332,8 +344,9 @@ Tower missions from those findings.
332
344
  ### Scenario E: sensitive release
333
345
 
334
346
  A library release with external consumers. Plan missions for the change, migration guide, and
335
- release notes; require tests and review; use `tower_batch` to close the release evidence only when
336
- all required checks are present; merge and tag outside Tower as your release process requires.
347
+ release notes; enable `review.requireReview:true` if the release requires independent review, require
348
+ tests, and use `tower_batch` to close the release evidence only when all required checks are present;
349
+ merge and tag outside Tower as your release process requires.
337
350
 
338
351
  ## 6. Choosing in practice: a short decision path
339
352
 
@@ -341,8 +354,9 @@ all required checks are present; merge and tag outside Tower as your release pro
341
354
  2. **Would you open a PR for it?** No → Tower is too heavy; use a normal agent.
342
355
  3. **Do the slices have stable scopes and a known definition of done?** No → plan/explore first; then
343
356
  return to Tower.
344
- 4. **Do you need independent review and a merge gate?** Yes → Tower. If no, plain subagents may be
345
- enough.
357
+ 4. **Do you need a merge gate?** Repository changes with integration risk → Tower. Enable
358
+ `review.requireReview:true` if you also need independent review. If neither isolation nor evidence
359
+ is needed, plain subagents may be enough.
346
360
  5. **Do you need many parallel analyses or repeated fresh attempts?** Use Workflow/Ralph for that
347
361
  phase; encode the resulting changes as Tower missions.
348
362
  6. **Do you need cross-cutting human collaboration?** Use Agent Teams to decide; execute the decided
@@ -350,12 +364,13 @@ all required checks are present; merge and tag outside Tower as your release pro
350
364
 
351
365
  ## 7. Cost, limits, and anti-patterns
352
366
 
353
- - **Per-mission overhead is real**: worktree creation, spawn, completion checks, review round, gate,
354
- merge. Keep missions meaningful (roughly a PR-sized slice), not one task per function.
367
+ - **Per-mission overhead is real**: worktree creation, spawn, completion checks, an optional review
368
+ round, gate, merge. Keep missions meaningful (roughly a PR-sized slice), not one task per function.
355
369
  - **Merges serialize**: overlapping scopes auto-add dependencies; independent missions still merge
356
370
  one at a time onto the base. Do not expect linear speedup for merge-heavy work.
357
- - **Review is not free**: every mission needs a reviewer and a clean verdict. Exemptions are opt-in
358
- and require a reason; they are not the default.
371
+ - **Review is not free when enabled**: each mission then needs a reviewer and a clean verdict.
372
+ `review.requireReview:false` (the default) makes review optional; when the gate is on, exemptions
373
+ are opt-in and require a reason.
359
374
  - **Too-fine missions** increase coordination and merge cost. **Too-coarse missions** lose the benefit
360
375
  of parallel review and make scope conflicts likely.
361
376
  - **Tower is not a sandbox**: it is a coordination protocol. Host permissions, repository hooks, and
@@ -369,9 +384,11 @@ all required checks are present; merge and tag outside Tower as your release pro
369
384
 
370
385
  - [ ] The work produces a repository change that deserves a PR-style review.
371
386
  - [ ] I can name 2–8 missions with non-overlapping scopes and a rough dependency order.
372
- - [ ] Each mission has a testable definition of done (tasks, checks/tests, review).
387
+ - [ ] Each mission has a testable definition of done (tasks, checks/tests, optional review).
388
+ - [ ] If this change needs independent review, `review.requireReview` is on (default is off).
373
389
  - [ ] I know which missions can run in parallel and which must wait.
374
- - [ ] I accept the review/merge overhead and will inspect `MISSIONS.md`/the branch.
390
+ - [ ] I accept the merge-gate overhead (and review overhead if enabled) and will inspect
391
+ `MISSIONS.md`/the branch.
375
392
  - [ ] I am not currently relying on a Team task board, Workflow script, Ralph loop, or plan mode in
376
393
  the same session.
377
394
  - [ ] I have a recovery path if a worker stalls (interrupt/adopt) or a merge conflicts.
@@ -4,9 +4,10 @@ Tower's guarantees are **coordination guarantees**, not a sandbox. Understand wh
4
4
 
5
5
  ## Enforced by the plugin
6
6
 
7
- - **Review binding.** `tower_review` records the branch tip it inspected; the gate rejects a moved tip
8
- (`tip-moved`) unless a clean conflict-free rebase waived it. A reviewer that modifies the branch after
9
- spawning is rejected (`reviewer must not modify the mission branch`).
7
+ - **Review binding (when review is enabled).** `tower_review` records the branch tip it inspected;
8
+ with `review.requireReview:true`, the gate rejects a moved tip (`tip-moved`) unless a clean
9
+ conflict-free rebase waived it. A reviewer that modifies the branch after spawning is rejected
10
+ (`reviewer must not modify the mission branch`).
10
11
  - **Review is optional by default, enforceable by config.** `review.requireReview:false` is the
11
12
  default; set it to `true` to enforce the independent-review gate. Mission-level
12
13
  `reviewPolicy:"none"` + reason is the narrower exemption when the global gate is on. With the gate
@@ -22,18 +23,18 @@ Tower's guarantees are **coordination guarantees**, not a sandbox. Understand wh
22
23
  file findings, and submit a review.
23
24
  - **Scope gate.** A mission may only change files matched by its declared scope globs; out-of-scope
24
25
  changes block the merge.
25
- - **Worktree isolation.** Workers operate in a dedicated worktree and branch; the main checkout is only
26
- touched by merge/teardown.
27
- - **Human-owned mode.** `/tower` is user-owned. With `mode.allowAgentControl` the model may toggle it,
28
- but must state a reason; the shipped patch enables that by default — set it to `false` to make the
29
- mode human-only.
26
+ - **Mode control is explicit and configurable.** `/tower` is always available. With
27
+ `mode.allowAgentControl:true` (the default), the model may also enter/leave with `tower_control` and
28
+ a mandatory reason; every change records actor/reason. Set it to `false` for human-only mode control.
29
+ The point is an attributable change, not a particular owner.
30
30
  - **No automatic goal resume.** Entering pauses the active goal; leaving does not resume it.
31
31
  - **Advisory workspace lock.** `mode.workspaceLock` prevents two Tower sessions from accidentally driving
32
32
  one repository; it is a same-user coordination lock, not authentication between users.
33
- - **Test discovery is repository code.** `tower_test`/`tower_complete` execute `package.json`
34
- `tower.testDiscovery` commands in the mission worktree with the DSH process's OS permissions. Set
35
- `tests.allowPackageDiscovery:false` for untrusted repositories; output/time budgets fail closed but are
36
- not a sandbox.
33
+ - **Test discovery is repository code.** `tower_test`/`tower_complete` can execute `package.json`
34
+ `tower.testDiscovery` commands in the mission worktree with the DSH process's OS permissions.
35
+ `tests.admission` defaults to `off`, so this happens only on an explicit `tower_test`; set
36
+ `tests.allowPackageDiscovery:false` for untrusted repositories. Output/time budgets fail closed but
37
+ are not a sandbox.
37
38
  - **Review exemption is opt-in.** `reviewPolicy:"none"` requires `gates.allowReviewExemption:true` and a
38
39
  non-empty reason. It is off by default because a model-driven tower could otherwise self-exempt; the
39
40
  exemption and its reason are recorded in state/events and never granted to workers.
@@ -45,6 +46,11 @@ Tower's guarantees are **coordination guarantees**, not a sandbox. Understand wh
45
46
 
46
47
  ## Not enforced by the plugin (deployment concerns)
47
48
 
49
+ - **Worktree isolation is a protocol convention, not an OS sandbox.** Workers are assigned a dedicated
50
+ worktree and branch and told to stay there, but the `tower-worker` preset still includes `pwsh`,
51
+ `write`, and `edit`; those tools can write absolute paths or run Git in the main checkout. The scope
52
+ gate checks the committed branch diff, not filesystem access. For hard isolation use a container,
53
+ separate OS user, or a restricted host tool policy.
48
54
  - **Sandboxing.** Host plugins run outside the filesystem sandbox; the reviewer's shell ability is
49
55
  removed at the tool-surface level, but the underlying process still has whatever OS permissions DSH
50
56
  has. Deployments that need hard isolation must restrict the process/user themselves.
@@ -1,14 +1,15 @@
1
1
  # Blockers and failure codes
2
2
 
3
3
  `tower_preflight` returns `{ok:false, blockers:[{code, detail}]}`. `tower_merge` and `tower_rebase`
4
- return the same shape for operation failures. Codes are stable; the detail is human-facing.
4
+ return the same shape for operation failures. Codes are stable; the detail is human-facing. The
5
+ tables below define 32 stable blocker/failure codes.
5
6
 
6
7
  ## Gate blockers (26)
7
8
 
8
9
  | Code | Meaning / next action |
9
10
  |---|---|
10
11
  | `mission-missing` | Unknown mission id. Check `tower_status`. |
11
- | `mission-not-completed` | Mission is not `completed`; only a completed mission (awaiting review) merges. |
12
+ | `mission-not-completed` | Mission is not `completed`; only a completed mission (ready for preflight/merge) merges. |
12
13
  | `tasks-open` | Open tasks remain; the worker must finish or `task_drop` with a reason. |
13
14
  | `blockers-present` | The mission has blockers; clear them after resolving. |
14
15
  | `no-check-evidence` | `gates.requireChecks` is enabled and the completion report has no `checks`. Return the completed mission to `active`, re-run `tower_complete` with checks, then review again. |
@@ -18,20 +19,20 @@ return the same shape for operation failures. Codes are stable; the detail is hu
18
19
  | `out-of-scope` | Changed files outside the mission scope; widen scope deliberately or revert. |
19
20
  | `base-dirty` | The main checkout has uncommitted changes the merge would overwrite. |
20
21
  | `deps-unmerged` | A dependency mission is not merged/abandoned. |
21
- | `no-review` | No review on the branch: spawn a reviewer. |
22
- | `review-mission-mismatch` | The latest review belongs to another mission. |
23
- | `not-clean` | Latest review is `p1-Nitems`/`p2-Nitems`; another round is required. |
24
- | `review-hold` | Latest review recommends hold; a later clean review must supersede it. |
25
- | `review-not-approved` | Latest clean review says `fix-then-merge` or `hold`; only `merge` approves. |
26
- | `tip-moved` | The branch changed after review; review again (or use a clean rebase waiver). |
22
+ | `no-review` | `review.requireReview:true` and no review exists on the branch: spawn a reviewer (or disable the review gate). |
23
+ | `review-mission-mismatch` | `review.requireReview:true` and the latest review belongs to another mission. |
24
+ | `not-clean` | `review.requireReview:true` and latest review is `p1-Nitems`/`p2-Nitems`; another round is required. |
25
+ | `review-hold` | `review.requireReview:true` and latest review recommends hold; a later clean review must supersede it. |
26
+ | `review-not-approved` | `review.requireReview:true` and latest clean review says `fix-then-merge` or `hold`; only `merge` approves. |
27
+ | `tip-moved` | `review.requireReview:true` and the branch changed after review; review again (or use a clean rebase waiver). |
27
28
  | `worker-busy` | A roster agent for this mission is running; wait or retire it. |
28
29
  | `worker-status-unknown` | The parent catalog is unavailable, so a live roster agent cannot be proven stopped; retry after the catalog recovers or adopt it. |
29
30
  | `base-wrong-branch` | The main checkout is not on the recorded base branch. |
30
31
  | `branch-owned-by-closed-missions` | The mission is already merged/abandoned; re-plan under a new title. |
31
32
  | `worker-stale` | A roster worker for this mission has no catalog activity beyond `spawn.staleMs`; adopt it (or interrupt it only if it is actually running) before merge. |
32
- | `tests-missing` | `gates.requireTests` is enabled and there is no passing discovery receipt for the reviewed tip; run `tower_test` or `tower_complete`. |
33
+ | `tests-missing` | `gates.requireTests` is enabled and there is no passing discovery receipt for the current branch tip; run `tower_test` or `tower_complete`. |
33
34
  | `tests-failed` | The latest discovery receipt failed or did not meet minCount/required checks. Fix the tests and re-run. |
34
- | `review-exemption-invalid` | The mission requests `reviewPolicy:"none"` but `gates.allowReviewExemption` is off (or the reason is missing). |
35
+ | `review-exemption-invalid` | `review.requireReview:true` and the mission requests `reviewPolicy:"none"` while `gates.allowReviewExemption` is off (or the reason is missing). |
35
36
  | `merge-intent-pending` | A merge intent was recorded before a crash/failure; run `tower_merge` to reconcile before another gate. |
36
37
 
37
38
  ## Merge failures (4)
@@ -22,7 +22,7 @@ win, profile keys survive when the repo does not set them. `tower_status` report
22
22
 
23
23
  ```json
24
24
  {
25
- "review": { "maxRoundsPerReviewer": 3 },
25
+ "review": { "requireReview": true, "maxRoundsPerReviewer": 3 },
26
26
  "merge": { "timeoutMs": 1800000 },
27
27
  "worktrees": { "root": "D:/tower-worktrees" },
28
28
  "spawn": { "reviewerPreset": "tower-reviewer", "maxDepth": 2 }
@@ -38,12 +38,12 @@ violates the declared schema (for example `merge.timeoutMs` below 1000) fail wit
38
38
  | Key | Default | Meaning |
39
39
  |---|---|---|
40
40
  | `section` | `''` | Legacy alias: replace the whole Tower-mode prompt text. Empty keeps the built-in reminder. |
41
- | `allowAgentControl` | `false` (bundled patch: `true`) | Legacy alias: register `tower_control`. |
41
+ | `allowAgentControl` | `true` (alias of `mode.allowAgentControl`) | Legacy alias: register `tower_control` so the model may toggle the mode. |
42
42
  | `init.autoGitInit` | `false` (bundled patch: `true`) | `tower_init` may run `git init` + an empty initial commit when `repoRoot` is an absolute, existing directory that is not a repository. |
43
43
  | `init.snapshotDirty` | `false` | `tower_init` may snapshot uncommitted **tracked** changes into a dangling commit used as the mission baseline (untracked files are not included; the commit is kept alive under `refs/tower/snapshot/*`). |
44
44
  | `mode.promptSection` | `''` | Replacement prompt text (takes precedence over `section` when both set). |
45
45
  | `mode.sectionAppend` | `''` | Extra text appended after the reminder (team conventions). |
46
- | `mode.allowAgentControl` | `false` | Register `tower_control`; the model may enter/leave with a reason. |
46
+ | `mode.allowAgentControl` | `true` | Register `tower_control`; the model may enter/leave with a reason. Set `false` for human-only mode control. |
47
47
  | `mode.autoPauseGoal` | `true` | Pause an active goal on entry; the goal is never auto-resumed on exit. |
48
48
  | `mode.requireResumeAuthorization` | `false` | Resuming a mission paused with `pauseCause:user` requires an `authorization` reference. |
49
49
  | `mode.workspaceLock` | `false` (bundled patch: `true`) | Allow only one Tower session per repository (`tower.lock`); others get `workspace-busy`. |
@@ -58,6 +58,7 @@ violates the declared schema (for example `merge.timeoutMs` below 1000) fail wit
58
58
  | `review.maxRoundsPerReviewer` | `5` | Review-round cap per reviewer per branch. |
59
59
  | `merge.timeoutMs` | `900000` (15 min) | Default `tower_merge` timeout, including hooks. A per-call `timeoutMs` wins. |
60
60
  | `merge.maxBufferBytes` | `67108864` (64 MB) | Merge output buffer. |
61
+ | `git.timeoutMs` | `15000` | Default timeout for Git commands other than merge; merge uses `merge.timeoutMs`. |
61
62
  | `worktrees.root` | `''` | Default worktree parent; empty derives `<checkout parent>/.dsh-tower-worktrees/<hash>`. |
62
63
  | `spawn.workerPreset` | `tower-worker` | Preset used for `role=worker`. |
63
64
  | `spawn.reviewerPreset` | `tower-reviewer` | Preset used for `role=reviewer`. |
@@ -72,14 +73,14 @@ violates the declared schema (for example `merge.timeoutMs` below 1000) fail wit
72
73
  | `send.maxPerMinute` | `120` | Per-repository `tower_send` rate limit (0 disables); exceeding it returns `rate-limited`. |
73
74
  | `send.interruptDefault` | `false` (bundled patch: `true`) | Default for `tower_send.interrupt` (interrupt the running turn before delivering). |
74
75
  | `tests.enabled` | `true` | Run declared test discovery when the worktree `package.json` configures it. |
75
- | `tests.admission` | `complete` | `spawn` runs discovery before starting a worker, `complete` at `tower_complete`, `off` only on explicit `tower_test`. |
76
+ | `tests.admission` | `off` | `spawn` runs discovery before starting a worker, `complete` at `tower_complete`, `off` only on explicit `tower_test` (default; repository code is not executed automatically). |
76
77
  | `tests.timeoutMs` | `60000` | Per discovery command timeout. |
77
78
  | `tests.maxBytes` | `16777216` (16 MiB) | Captured stdout cap per command. |
78
79
  | `tests.autoChecks` | `true` | Attach an automatic `tests` check to the completion report. |
79
80
  | `tests.allowPackageDiscovery` | `true` | Allow repo-controlled `tower.testDiscovery` commands (executes worktree code; see security). |
80
81
  | `gates.requireChecks` | `false` | Require at least one `tower_complete.checks` entry before merge (`no-check-evidence`). |
81
- | `gates.requireTests` | `false` | Require a passing discovery receipt for the reviewed tip (`tests-missing`). |
82
- | `gates.allowReviewExemption` | `false` | Allow `reviewPolicy:"none"` + reason to skip review blockers; default off deliberately. |
82
+ | `gates.requireTests` | `false` | Require a passing discovery receipt for the current mission branch tip (`tests-missing`); independent of the review gate. |
83
+ | `gates.allowReviewExemption` | `false` | With `review.requireReview:true`, allow `reviewPolicy:"none"` + a non-empty reason to skip review blockers. Off deliberately; irrelevant while the global review gate is off. |
83
84
  | `docs.board` | `true` | Write `MISSIONS.md` after mutations. |
84
85
  | `docs.boardLocation` | `common` | `common` = `<git-common-dir>/dsh-tower/MISSIONS.md`; `repo` = `<repoRoot>/MISSIONS.md`. |
85
86
  | `leases.ttlMs` | `900000` | Default advisory lease lifetime; expiry never auto-releases. |
@@ -1,7 +1,12 @@
1
1
  # Tool error codes
2
2
 
3
3
  Tool failures are thrown errors, not `{ok:false}` results (gate outcomes are the exception: see
4
- [blockers.md](blockers.md)). Every thrown error carries a stable code as a message prefix:
4
+ [blockers.md](blockers.md)). Every thrown error carries a stable code as a message prefix. This
5
+ release defines 31 tool error codes.
6
+
7
+ Every `TowerToolError` also carries `retryable` (boolean), `nextAction` (string or `null`) and `details`
8
+ (structured context or `null`) for programmatic callers; the message prefix remains the stable contract
9
+ for text-only clients.
5
10
 
6
11
  ```
7
12
  [tower:mission-not-found] unknown mission "M9"
@@ -18,6 +23,7 @@ message without a more specific match is reported as `tool-internal`.
18
23
  | `mission-not-found` | No mission with that id exists. | a stale or mistyped `M9` |
19
24
  | `finding-not-found` | No finding with that id exists. | `tower_findings({id:"F99"})` |
20
25
  | `invalid-transition` | The requested state transition is not allowed. | a blocked→merged attempt; a finding transition not in the graph; a reviewer mutating findings; completing a mission with open tasks, blockers, no commits, or unread inbox messages. |
26
+ | `worktree-dirty` | The mission worktree has uncommitted changes and cannot complete. | staged, modified, or untracked files left behind before `tower_complete` |
21
27
  | `state-locked` | Another Tower writer holds the state lock. | concurrent mutation after the lock timeout |
22
28
  | `state-corrupt` | The Tower state file is unreadable or invalid. | hand-edited `state.json` |
23
29
  | `config-invalid` | Tower configuration is invalid. | malformed repo `config.json`, a value that violates the schema |
@@ -1,8 +1,8 @@
1
1
  # Tower events
2
2
 
3
3
  Tower emits process-local Cordis events after successful tool calls (mutations and read-only tools), so
4
- other plugins can observe a repository without polling. Events are **not** sent over the network and carry
5
- no telemetry.
4
+ other plugins can observe a repository without polling. This release emits 29 process-local events.
5
+ Events are **not** sent over the network and carry no telemetry.
6
6
 
7
7
  ```js
8
8
  ctx.on('tower/merge', (payload) => {
@@ -32,14 +32,17 @@ ctx.on('tower/merge', (payload) => {
32
32
  | `tower/status` | `tower_status` read the dashboard |
33
33
  | `tower/preflight` | `tower_preflight` evaluated the gate |
34
34
  | `tower/doctor` | `tower_doctor` completed its read-only checks |
35
+ | `tower/recover` | `tower_recover` inspected or cleared a stale state lock |
35
36
  | `tower/test` | `tower_test` ran discovery |
36
37
  | `tower/batch` | `tower_batch` created, inspected or closed a batch |
37
38
  | `tower/resource` | `tower_resource` acquired/released/inspected leases |
38
39
  | `tower/import_legacy` | `tower_import_legacy` stored a legacy snapshot |
39
40
  | `tower/legacy_map` | `tower_legacy_map` mapped or listed legacy ids |
41
+ | `tower/mode` | `tower_mode` read/changed the session stance (`value.mode`, `allowAgentControl`, `deniedWhileActive`) |
42
+ | `tower/control` | `tower_control` entered/left the mode (`value.mode`, actor/reason in `value`) |
43
+ | `tower/reload` | `tower_reload` returned a reload schedule/result |
40
44
 
41
- `tower_mode`, `tower_control` and `tower_reload` do not emit Tower events. Payloads are JSON:
42
- `{tool, repoRoot, value}`. Listener exceptions never affect the tool result.
45
+ Payloads are JSON: `{tool, repoRoot, value}`. Listener exceptions never affect the tool result.
43
46
 
44
47
  For a durable audit trail use `<git-common-dir>/dsh-tower/activity.jsonl` and `MISSIONS.md` instead;
45
48
  events are process-local and are not replayed.
@@ -50,7 +50,8 @@ discovery fails.
50
50
  - `tower_test({repoRoot,missionId})` runs discovery on demand and records a receipt.
51
51
  - `tower_complete` adds a `tests` check when `tests.autoChecks` is on.
52
52
  - `gates.requireChecks` requires any completion check; `gates.requireTests` requires a passing receipt
53
- for the reviewed tip (`tests-missing`).
53
+ for the current mission branch tip (`tests-missing`). Review is independent of this gate: with
54
+ `review.requireReview:false` the tests gate still checks the branch tip.
54
55
 
55
56
  ## Trust boundary
56
57
 
@@ -1,10 +1,10 @@
1
1
  # Tools reference
2
2
 
3
3
  All tools take `repoRoot` (an absolute path inside the target Git repository) and return JSON.
4
- The build exposes up to 28 tools: 19 core repository tools below (including `tower_interrupt`),
5
- `tower_mode`, `tower_control` when `mode.allowAgentControl` is enabled (the bundled patch enables it),
4
+ The build exposes up to 29 tools: 19 core repository tools below (including `tower_interrupt`),
5
+ `tower_mode`, `tower_control` (registered by default; set `mode.allowAgentControl:false` to disable),
6
6
  `tower_reload` while `dev.hotReload` is on, and the 2.1 verification/ops tools `tower_doctor`,
7
- `tower_test`, `tower_batch`, `tower_resource`, `tower_import_legacy`, `tower_legacy_map`.
7
+ `tower_recover`, `tower_test`, `tower_batch`, `tower_resource`, `tower_import_legacy`, `tower_legacy_map`.
8
8
 
9
9
  `tower_mission` uses `id` (alias `missionId`); every other mission-scoped tool uses `missionId`
10
10
  (alias `id`). Other input aliases: `task_done`/`taskDone`, `task_drop`/`taskDrop`,
@@ -31,7 +31,7 @@ findings but not mutate them. Violations throw `[tower:not-authorized]` or
31
31
  | Tool | Parameters | Purpose / notes |
32
32
  |---|---|---|
33
33
  | `tower_init` | `base?`, `autoGitInit?`, `snapshotDirty?`, `reanchor?` | Create `<git-common-dir>/dsh-tower/state.json`. `autoGitInit` runs `git init` + empty initial commit; `snapshotDirty` records a dangling snapshot commit of uncommitted tracked changes used as the mission baseline; `reanchor` changes base only when no non-terminal mission exists. Returns `dirty`, `snapshotCommit`, `reanchored`. |
34
- | `tower_plan` | `missions[]` (`title`, `scope[]`, `tasks[]?`, `deps[]?`, `kind?`, `context?`, `references[]?` ≤20, `reviewPolicy?`, `reviewExemptionReason?`) | Create missions `M1..`; overlapping build scopes auto-add a dependency; rejects unknown deps and cycles. `reviewPolicy:"none"` requires a reason and `gates.allowReviewExemption`. |
34
+ | `tower_plan` | `missions[]` (`title`, `scope[]`, `tasks[]?`, `deps[]?`, `kind?`, `context?`, `references[]?` ≤20, `reviewPolicy?`, `reviewExemptionReason?`) | Create missions `M1..`; overlapping build scopes auto-add a dependency; rejects unknown deps and cycles. `reviewPolicy:"none"` requires a non-empty reason; when the review gate is on, preflight also requires `gates.allowReviewExemption`. |
35
35
  | `tower_mission` | `id` (alias `missionId`), `status?`, `task_done?`, `task_drop?`+`task_drop_reason?`, `blocker?`, `clear_blockers?`, `note?`, `scope?`, `pause_cause?`, `authorization?` | Update one mission. Worker-safe fields are task/blocker/note; `merged` cannot be set here. Paused missions record `pause_cause` (user/failure/resource/dependency); resuming a user-paused mission honors `mode.requireResumeAuthorization`. |
36
36
  | `tower_status` | `missionId?`, `offset?`, `limit?`, `includeGate?`, `format?` | Dashboard by default. `missionId` returns full detail (tasks/notes/reviews/findings/completionReport). `offset`/`limit` page missions (default 20, max 100), `includeGate` adds gate digests, `format:"markdown"` returns the board. |
37
37
  | `tower_spawn` | `missionId` (alias `id`), `role` (`worker`/`reviewer`), `name?`, `instructions?`, `worktreeRoot?`, `wait?`, `waitMs?`, `takeover?`, `includeDirtyBase?` | Provision/reuse the worktree and start a subagent. Worker uses `tower-worker`; reviewer requires a `completed` mission and uses the read-only `tower-reviewer`. `takeover:true` replaces a live worker entry that is no longer running (increments ownerGeneration). Only one live worker per mission; `spawn.maxLiveWorkers` caps the repository. |
@@ -40,7 +40,7 @@ findings but not mutate them. Violations throw `[tower:not-authorized]` or
40
40
  | `tower_diff` | `missionId` (alias `id`), `maxBytes?` | Read-only merge-base diff: files, commits, capped patch. Safe for reviewers. |
41
41
  | `tower_send` | `to`, `subject`, `body`, `scope?`, `interrupt?`, `consentRef?` | Durable message to a roster name, `tower`, or `all`; delivers live to a running agent. `interrupt:true` interrupts the running turn first (Kimi-style), then delivers; `consentRef` is recorded for audit. Rate-limited by `send.maxPerMinute`. |
42
42
  | `tower_inbox` | `limit?`, `include_read?` | Read/ack messages addressed to the caller; unread messages block `tower_complete`. |
43
- | `tower_complete` | `missionId` (alias `id`), `report`, `checks?` | Worker reports completion (mission becomes `completed`, awaiting review). Requires current owner, no open tasks/blockers, ≥1 commit, no unread inbox. `checks` records `{name, command?, exitCode?, evidence?}` evidence; `gates.requireChecks` can demand it. When configured, test discovery runs automatically and adds a `tests` check; failure throws `[tower:tests-failed]`. |
43
+ | `tower_complete` | `missionId` (alias `id`), `report`, `checks?` | Worker reports completion (mission becomes `completed`, ready for preflight and optional review). Requires current owner, no open tasks/blockers, ≥1 commit, no unread inbox. `checks` records `{name, command?, exitCode?, evidence?}` evidence; `gates.requireChecks` can demand it. When configured, test discovery runs automatically and adds a `tests` check; failure throws `[tower:tests-failed]`. |
44
44
  | `tower_interrupt` | `to?` (roster name), `agentId?`, `reason?` | Interrupt one running roster agent via `subagents.interrupt`, record `state:"interrupted"`. Idempotent (not running → `interrupted:false`). |
45
45
  | `tower_finding` | `type`, `title`, `summary`, `details`, `suggested_fix`, `severity?`, `missionId?`, `location?` | Record an out-of-scope issue; reviewers use this instead of editing. Finds start as `open`. |
46
46
  | `tower_findings` | `id?`, `status?`, `note?`, filters (`type?`, `severity?`, `missionId?`, `open?`, `limit?`) | Lifecycle tool: list/read/transition. Statuses `open → triaged → fixed`/`wontfix`, reopen allowed. Only the tower or a worker may mutate; a reviewer can list/read. |
@@ -50,9 +50,10 @@ findings but not mutate them. Violations throw `[tower:not-authorized]` or
50
50
  | `tower_rebase` | `missionId` (alias `id`) | Rebase the branch onto the base in its worktree. Refuses while the worker runs or the worktree is dirty. Already-contained branches return `alreadyMerged` untouched. |
51
51
  | `tower_teardown` | `force?`, `exclude?`, `dry_run?` (alias `dryRun`) | Remove eligible merged/abandoned worktrees and branches; running agents are always kept. |
52
52
  | `tower_mode` | — | Report mode, last change, paused goal, denied tools, store path, plugin version, HMR availability, workspace-lock holder. |
53
- | `tower_control` | `action` (`enter`/`exit`), `reason` | Model-initiated mode change; only when `mode.allowAgentControl` is true; reason is mandatory. |
53
+ | `tower_control` | `action` (`enter`/`exit`), `reason` | Model-initiated mode change; registered by default; disable with `mode.allowAgentControl:false`; reason is mandatory. |
54
54
  | `tower_reload` | `repoRoot?` | Dev-only: ask DSH HMR to reconcile the profile and reload the Host plugin from disk. Registered while `dev.hotReload` is on; scheduled after the result (default 50 ms); fails with `reload-unavailable` without HMR. When `repoRoot` is supplied the caller must be the tower. |
55
55
  | `tower_doctor` | — (takes `repoRoot`) | Read-only health contract: git, state schema, config, presets/subagents/HMR, workspace lock, roster, worktree realpath/ownership, test config, leases. Returns `{ok, checks[{id,status,detail}], environmentContract}`. Never writes. |
56
+ | `tower_recover` | `action` (`status`/`clear-stale-lock`), `confirm?` | Recovery diagnostics plus an explicit stale state-lock repair. `clear-stale-lock` requires `confirm:"CLEAR_STALE_LOCK"` and only moves a lock whose PID is provably dead to a backup; it never resets state/worktrees. |
56
57
  | `tower_test` | `missionId` (alias `id`) | Run the worktree's `package.json` `tower.testDiscovery` and record a receipt; `ok:false` on failure. Use `tower_complete` for automatic admission checks. |
57
58
  | `tower_batch` | `action` (`create`/`status`/`close`/`abandon`), `missionIds?`, `exclusions?`, `requiredChecks?`, `receiptPaths?`, `batchId?`, `checks?`, `treeTip?`, `receiptHashes?`, `reason?` | Finite evidence batch. Create freezes members/checks/receipts; close verifies every required check and receipt hash; merged members are eligible; abandon retires a stale open batch without deleting missions. Membership is immutable. |
58
59
  | `tower_resource` | `action` (`acquire`/`release`/`status`), `name?`, `holder?`, `token?`, `ttlMs?`, `force?` | Advisory per-repository lease in `<common>/dsh-tower/leases.json`. No OS CPU/memory hard cap; expired leases require explicit `force` and the correct token. |