dsh-tower 2.0.3 → 2.1.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +141 -0
- package/COMPATIBILITY.md +38 -0
- package/CONTRIBUTING.md +150 -2
- package/README.en.md +59 -16
- package/README.md +57 -16
- package/SECURITY.md +31 -1
- package/adapters/default.js +10 -0
- package/adapters/store-fs.js +6 -0
- package/adapters/vcs-git.js +4 -0
- package/app/batch.js +79 -0
- package/app/board.js +25 -0
- package/app/checkCompletion.js +76 -0
- package/app/enrichedMissions.js +26 -0
- package/app/findings.js +78 -0
- package/app/gate.js +108 -0
- package/app/init.js +249 -0
- package/app/merge.js +567 -0
- package/app/messages.js +66 -0
- package/app/mission.js +35 -0
- package/app/missionContext.js +14 -0
- package/app/plan.js +42 -0
- package/app/provision.js +193 -0
- package/app/read.js +57 -0
- package/app/rebase.js +302 -0
- package/app/recording.js +72 -0
- package/app/review.js +145 -0
- package/app/roster.js +123 -0
- package/app/spawn.js +125 -0
- package/app/teardown.js +184 -0
- package/app/tower.js +524 -0
- package/cordis.patch.yml +61 -53
- package/docs/README.md +33 -1
- package/docs/architecture/overview.md +114 -14
- package/docs/board.md +72 -0
- package/docs/examples/first-mission.md +2 -1
- package/docs/faq.md +11 -7
- package/docs/guide/hot-reload.md +1 -1
- package/docs/guide/install-upgrade-migration.md +22 -6
- package/docs/guide/quickstart.md +12 -7
- package/docs/guide/release.md +125 -0
- package/docs/guide/scenarios-and-philosophy.md +86 -69
- package/docs/operations/security.md +65 -14
- package/docs/reference/blockers.md +11 -10
- package/docs/reference/config.generated.md +66 -0
- package/docs/reference/config.md +11 -7
- package/docs/reference/errors.generated.md +39 -0
- package/docs/reference/errors.md +10 -2
- package/docs/reference/events.md +7 -4
- package/docs/reference/testing.md +2 -1
- package/docs/reference/tools.generated.md +33 -0
- package/docs/reference/tools.md +8 -7
- package/docs/zh/README.md +4 -3
- package/docs/zh/faq.md +9 -6
- package/docs/zh/guide/hot-reload.md +1 -1
- package/docs/zh/guide/install-upgrade-migration.md +17 -5
- package/docs/zh/guide/quickstart.md +13 -8
- package/docs/zh/guide/scenarios-and-philosophy.md +55 -50
- package/docs/zh/operations/security.md +43 -7
- package/docs/zh/reference/blockers.md +10 -10
- package/docs/zh/reference/config.md +11 -7
- package/docs/zh/reference/errors.md +4 -1
- package/docs/zh/reference/events.md +6 -3
- package/docs/zh/reference/testing.md +3 -2
- package/docs/zh/reference/tools.md +8 -7
- package/domain/collab/batch.js +112 -0
- package/domain/collab/messages.js +127 -0
- package/domain/collab/roster.js +158 -0
- package/domain/collab/spawn.js +188 -0
- package/domain/config/schema.js +404 -0
- package/domain/contracts/outputs.js +279 -0
- package/domain/contracts/tool-inputs/collaboration.js +58 -0
- package/domain/contracts/tool-inputs/findings.js +29 -0
- package/domain/contracts/tool-inputs/index.js +94 -0
- package/domain/contracts/tool-inputs/integration.js +37 -0
- package/domain/contracts/tool-inputs/missions.js +94 -0
- package/domain/contracts/tool-inputs/ops.js +75 -0
- package/domain/contracts/tool-inputs/shared.js +25 -0
- package/domain/errors.js +96 -0
- package/domain/gate.js +125 -0
- package/domain/integration/gate.js +176 -0
- package/domain/integration/init.js +225 -0
- package/domain/integration/liveness.js +31 -0
- package/domain/integration/merge.js +377 -0
- package/domain/integration/provision.js +124 -0
- package/domain/integration/rebase.js +236 -0
- package/domain/integration/review.js +52 -0
- package/domain/integration/teardown.js +118 -0
- package/domain/mission.js +68 -0
- package/domain/missions/completion.js +114 -0
- package/domain/missions/findings.js +201 -0
- package/domain/missions/lifecycle.js +185 -0
- package/domain/missions/plan.js +149 -0
- package/domain/missions/review.js +179 -0
- package/domain/planning.js +118 -0
- package/domain/read/enrichedMissions.js +58 -0
- package/domain/read/missionContext.js +53 -0
- package/domain/read/views.js +128 -0
- package/domain/report.js +59 -0
- package/domain/roster.js +40 -0
- package/domain/scope.js +105 -0
- package/domain/state/schema.js +233 -0
- package/domain/state/semantics.js +117 -0
- package/domain/state.js +33 -0
- package/domain/summary.js +114 -0
- package/domain/vocabulary.js +179 -0
- package/index.js +86 -34
- package/lib/briefing.js +176 -0
- package/lib/compatibility.js +108 -0
- package/lib/config.js +54 -302
- package/lib/doctor.js +108 -9
- package/lib/git.js +93 -15
- package/lib/hmr.js +4 -3
- package/lib/leases.js +3 -2
- package/lib/legacy.js +20 -9
- package/lib/modeState.js +39 -0
- package/lib/modeStore.js +35 -33
- package/lib/persistence.js +349 -0
- package/lib/presets.js +35 -0
- package/lib/spawn-prechecks.js +168 -0
- package/lib/spawn-support.js +79 -0
- package/lib/store.js +57 -85
- package/lib/tests.js +46 -11
- package/lib/tool-registry.js +544 -0
- package/lib/workspaceLock.js +46 -22
- package/lib/worktreeOwnership.js +5 -4
- package/locale/en.json +23 -1
- package/locale/zh.json +22 -0
- package/package.json +33 -4
- package/ports/clock.js +6 -0
- package/ports/ids.js +7 -0
- package/ports/index.js +2 -0
- package/ports/store.js +11 -0
- package/ports/vcs.js +11 -0
- package/scripts/architecture.mjs +94 -0
- package/scripts/check-docs.mjs +44 -3
- package/scripts/check-pack.mjs +49 -0
- package/scripts/domain-metrics.mjs +48 -0
- package/scripts/generate-config-reference.mjs +46 -0
- package/scripts/generate-error-reference.mjs +29 -0
- package/scripts/generate-tools-reference.mjs +56 -0
- package/scripts/issue-audit.mjs +259 -0
- package/scripts/lib/cli.mjs +76 -0
- package/scripts/lib/tmp.mjs +20 -0
- package/scripts/mount-smoke/fixtures.mjs +162 -0
- package/scripts/mount-smoke/host.json +4 -0
- package/scripts/mount-smoke/probe.mjs +125 -0
- package/scripts/mount-smoke/surface.mjs +141 -0
- package/scripts/mount-smoke.mjs +270 -0
- package/scripts/pack-manifest.txt +203 -0
- package/scripts/release-check.mjs +303 -0
- package/skills/tower-recovery.md +7 -5
- package/tools/adopt.js +72 -0
- package/tools/batch.js +78 -0
- package/tools/complete.js +53 -0
- package/tools/diff.js +39 -0
- package/tools/doctor.js +50 -0
- package/tools/finding.js +40 -0
- package/tools/findings.js +39 -0
- package/tools/import-legacy.js +42 -0
- package/tools/inbox.js +39 -0
- package/tools/index.js +39 -0
- package/tools/init.js +63 -0
- package/tools/interrupt.js +42 -0
- package/tools/legacy-map.js +44 -0
- package/tools/merge.js +39 -0
- package/tools/mission.js +41 -0
- package/tools/plan.js +39 -0
- package/tools/preflight.js +44 -0
- package/tools/rebase.js +39 -0
- package/tools/recover.js +45 -0
- package/tools/reload.js +52 -0
- package/tools/resource.js +54 -0
- package/tools/review.js +45 -0
- package/tools/roster.js +60 -0
- package/tools/send.js +147 -0
- package/tools/spawn.js +196 -0
- package/tools/status.js +94 -0
- package/tools/teardown.js +42 -0
- package/tools/test.js +61 -0
- package/types/cordis.d.ts +6 -0
- package/types/index.d.ts +339 -0
- package/ui-bundle/README.md +111 -0
- package/ui-bundle/client.js +1980 -0
- package/ui-bundle/cordis.patch.yml +3 -0
- package/ui-bundle/icon.svg +6 -0
- package/ui-bundle/index.js +2 -0
- package/ui-bundle/locale/en.json +6 -0
- package/ui-bundle/locale/zh.json +6 -0
- package/ui-bundle/package.json +35 -0
- package/lib/errors.js +0 -111
- package/lib/tools.js +0 -2250
- package/lib/tower.js +0 -2689
- /package/{lib → domain}/batch.js +0 -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,
|
|
7
|
-
and a merge gate. This page explains the design choices behind it, the situations where it
|
|
8
|
-
and when Agent Teams, Ralph loops, Workflow orchestration, or ordinary parallel subagents are
|
|
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
|
|
12
|
-
|
|
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
|
|
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.
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
|
49
|
-
exemption when the global gate is on. Reviews can be submitted and
|
|
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
|
|
62
|
-
intent that the next `tower_merge` reconciles. The cost is occasional manual
|
|
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
|
|
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
|
|
69
|
-
|
|
70
|
-
not
|
|
71
|
-
|
|
72
|
-
|
|
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
|
|
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
|
|
126
|
-
|
|
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:**
|
|
129
|
-
|
|
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
|
|
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
|
|
162
|
-
| Interactive UI pairing / exploratory debugging | Ordinary agent (or a single worker) | Tight feedback loops and frequent human steering;
|
|
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
|
|
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
|
|
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,
|
|
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
|
|
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
|
|
203
|
-
has less flexible peer-to-peer coordination and more structure. Agent Teams can decide
|
|
204
|
-
build and *whether* to proceed; Tower can then execute that decision as missions. They are
|
|
205
|
-
or complementary, not concurrent: Tower mode refuses the Team task-board tools so the two
|
|
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
|
|
215
|
-
is "I do not know whether this can be done, and repeated fresh
|
|
216
|
-
often better. If the problem is "I know the slices; build and
|
|
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
|
|
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,
|
|
245
|
-
|
|
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.
|
|
257
|
+
### 4.7 Concrete examples by workflow
|
|
248
258
|
|
|
249
|
-
**Tower** — output is a repository change that must land through isolation and
|
|
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.
|
|
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
|
|
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.
|
|
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
|
|
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;
|
|
336
|
-
|
|
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
|
|
345
|
-
|
|
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,
|
|
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**:
|
|
358
|
-
|
|
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
|
|
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;
|
|
8
|
-
(`tip-moved`) unless a clean
|
|
9
|
-
|
|
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
|
-
- **
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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.
|
|
35
|
-
`tests.
|
|
36
|
-
|
|
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.
|
|
@@ -43,8 +44,56 @@ Tower's guarantees are **coordination guarantees**, not a sandbox. Understand wh
|
|
|
43
44
|
- **Legacy import is read-only.** Imported snapshots live under the canonical state directory and are never
|
|
44
45
|
activated, adopted, or resumed; an operator must explicitly re-plan/migrate work.
|
|
45
46
|
|
|
47
|
+
## Repository protection
|
|
48
|
+
|
|
49
|
+
This section is about **this repository**, not about a repository Tower runs on. Server-side branch
|
|
50
|
+
protection is not a plugin feature — Tower writes to the local base branch and cannot configure a
|
|
51
|
+
remote — but `dsh-tower` enables it for its own `main`, because the code that is the gate is also the
|
|
52
|
+
code an attacker would most want to change:
|
|
53
|
+
|
|
54
|
+
- `main` requires a pull request for every change, **enforced for admins**, so a direct push is
|
|
55
|
+
rejected even for the maintainer.
|
|
56
|
+
- Required checks are `test (22)`, `test (24)` and `mount`. The mount job packs the tarball and boots
|
|
57
|
+
it in a throwaway profile, so "the tests pass" cannot land a bundle that fails to appear after
|
|
58
|
+
`dsh plugin add`.
|
|
59
|
+
- Force-push and branch deletion are blocked, so history cannot be rewritten under a published tag.
|
|
60
|
+
- There are no mandatory approvals: with one maintainer, a self-approval requirement would be a rubber
|
|
61
|
+
stamp. The evidence instead is the four-line PR body (failure mode, change, test, blast radius) for
|
|
62
|
+
the two-key paths, written in [CONTRIBUTING.md](../../CONTRIBUTING.md#landing-changes).
|
|
63
|
+
|
|
64
|
+
What this buys: no untested change reaches `main`, a red or missing required check cannot be bypassed
|
|
65
|
+
by the owner, and history is append-only. What it does **not** buy: a second reader, protection against
|
|
66
|
+
a compromised maintainer token, or any protection for the repositories Tower itself operates on — those
|
|
67
|
+
remain deployment concerns. The settings, their rationale and a verification command are recorded in
|
|
68
|
+
[SECURITY.md](../../SECURITY.md#repository-protection-on-main).
|
|
69
|
+
|
|
70
|
+
## Model-initiated mode entry (threat model)
|
|
71
|
+
|
|
72
|
+
`mode.allowAgentControl:true` means a prompt injection in a repository file, issue text, or fetched
|
|
73
|
+
page can ask the model to “enter tower mode and fix this”. Tower does **not** authenticate the human
|
|
74
|
+
intent behind that entry. What it does provide:
|
|
75
|
+
|
|
76
|
+
- the entry is recorded with actor, action, reason, and timestamp; `tower_status.mode.history`
|
|
77
|
+
surfaces the recent transitions without grepping the activity log;
|
|
78
|
+
- the model cannot merge without the preflight gate, review policy, scope checks, tests, and
|
|
79
|
+
clean-base checks; writing the plan does not bypass them;
|
|
80
|
+
- workers are tool-restricted and instructed to stay in their worktree, but the main-checkout
|
|
81
|
+
protection is enforced by scope/merge checks and the preset, **not** by an OS sandbox;
|
|
82
|
+
- `mode.workspaceLock` prevents a second Tower session from driving the same repository.
|
|
83
|
+
|
|
84
|
+
It does **not** defend against: a model that legitimately passes every gate while acting on malicious
|
|
85
|
+
instructions; repository hooks or test commands the repository itself declares; or filesystem/shell
|
|
86
|
+
access outside the worktree by a worker that ignores its instructions. For a higher-assurance team,
|
|
87
|
+
set `mode.allowAgentControl:false`, keep `review.requireReview:true`, review the repository before
|
|
88
|
+
Tower work, and run the host under OS-level isolation.
|
|
89
|
+
|
|
46
90
|
## Not enforced by the plugin (deployment concerns)
|
|
47
91
|
|
|
92
|
+
- **Worktree isolation is a protocol convention, not an OS sandbox.** Workers are assigned a dedicated
|
|
93
|
+
worktree and branch and told to stay there, but the `tower-worker` preset still includes `pwsh`,
|
|
94
|
+
`write`, and `edit`; those tools can write absolute paths or run Git in the main checkout. The scope
|
|
95
|
+
gate checks the committed branch diff, not filesystem access. For hard isolation use a container,
|
|
96
|
+
separate OS user, or a restricted host tool policy.
|
|
48
97
|
- **Sandboxing.** Host plugins run outside the filesystem sandbox; the reviewer's shell ability is
|
|
49
98
|
removed at the tool-surface level, but the underlying process still has whatever OS permissions DSH
|
|
50
99
|
has. Deployments that need hard isolation must restrict the process/user themselves.
|
|
@@ -59,8 +108,10 @@ Tower's guarantees are **coordination guarantees**, not a sandbox. Understand wh
|
|
|
59
108
|
from disk. Only enable HMR watch roots for checkouts you trust; a reload executes the current files.
|
|
60
109
|
- **Prompt injection.** The reviewer reads untrusted branch content (diff/comments). The read-only preset
|
|
61
110
|
limits impact, but no model-side protection is absolute.
|
|
62
|
-
- **Base branch protection.** Tower writes to the local base branch; server-side branch protection
|
|
63
|
-
rules are not part of the plugin.
|
|
111
|
+
- **Base branch protection.** Tower writes to the local base branch; server-side branch protection and
|
|
112
|
+
push rules are not part of the plugin. This repository's own `main` protection is described in
|
|
113
|
+
[Repository protection](#repository-protection); enabling equivalent protection on the repository you
|
|
114
|
+
run Tower on remains a deployment concern.
|
|
64
115
|
|
|
65
116
|
## Reporting
|
|
66
117
|
|
|
@@ -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 (
|
|
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` |
|
|
22
|
-
| `review-mission-mismatch` |
|
|
23
|
-
| `not-clean` |
|
|
24
|
-
| `review-hold` |
|
|
25
|
-
| `review-not-approved` |
|
|
26
|
-
| `tip-moved` |
|
|
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
|
|
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` |
|
|
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)
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Config reference (generated)
|
|
2
|
+
|
|
3
|
+
> Generated by `npm run docs:generate:config` from `domain/config/schema.js`. Values are defaults before repo config.
|
|
4
|
+
|
|
5
|
+
| Key | Default | Description |
|
|
6
|
+
|---|---|---|
|
|
7
|
+
| `section` | `""` | Legacy alias for mode.promptSection: replaces the whole Tower-mode system prompt text. |
|
|
8
|
+
| `allowAgentControl` | `` | Legacy alias for mode.allowAgentControl: register tower_control so the model may toggle the mode. |
|
|
9
|
+
| `init.autoGitInit` | `false` | tower_init may run git init and create an empty initial commit when the directory is not a repository. |
|
|
10
|
+
| `init.snapshotDirty` | `false` | tower_init may snapshot uncommitted tracked changes into a dangling commit used as the mission baseline. |
|
|
11
|
+
| `init.autoExclude` | `true` | Add in-repo Tower artifacts (MISSIONS.md, in-repo worktree roots) to .git/info/exclude so they do not look like user dirt. |
|
|
12
|
+
| `mode.promptSection` | `` | Replacement Tower-mode system prompt text. Empty keeps the built-in reminder. |
|
|
13
|
+
| `mode.sectionAppend` | `` | Extra text appended to the Tower-mode system prompt section (team conventions). |
|
|
14
|
+
| `mode.allowAgentControl` | `true` | Register tower_control so the model may enter/leave the mode with a reason. |
|
|
15
|
+
| `mode.autoPauseGoal` | `true` | Pause an active goal when entering Tower mode. |
|
|
16
|
+
| `mode.requireResumeAuthorization` | `false` | Require an authorization reference when resuming a mission paused with pauseCause=user. |
|
|
17
|
+
| `mode.requireHumanAckOnFirstEntry` | `false` | Require a human /tower ack before the model may enter Tower mode for the first time in a session. |
|
|
18
|
+
| `mode.workspaceLock` | `false` | Allow only one Tower session per repository (advisory <git-common-dir>/dsh-tower/tower.lock). |
|
|
19
|
+
| `mode.workspaceLockScope` | `"all"` | all = every repo-scoped tool acquires the workspace lock; mutations = only tools that write state/worktrees do. |
|
|
20
|
+
| `mode.planModePolicy` | `"clear"` | On Tower entry: clear an active plan mode, or refuse to enter until the plan is exited. |
|
|
21
|
+
| `mode.workspaceStaleMs` | `300000` | A workspace lock older than this is stale and can be taken over. |
|
|
22
|
+
| `mode.heartbeatMs` | `10000` | Workspace-lock heartbeat interval while Tower mode is on. |
|
|
23
|
+
| `mode.denyTools` | `["create_goal","todo_write","team_task_create","team_task_update","team_task_reopen","team_task_list","spawn_teammate","wait_agent","workflow","ralph","subagent","subagent_fork"]` | Tools refused while Tower mode is active. |
|
|
24
|
+
| `mode.storePath` | `` | Directory for modes.json; defaults to $DSH_HOME/tower-mode. |
|
|
25
|
+
| `mode.maxEntries` | `200` | Maximum persisted mode entries. |
|
|
26
|
+
| `mode.lockTimeoutMs` | `5000` | How long saveModes waits for the cross-process modes.lock before giving up. |
|
|
27
|
+
| `review.requireReview` | `false` | Require an independent clean review before merge. Default false: review is optional; set true to enforce the review gate globally. |
|
|
28
|
+
| `review.maxRoundsPerReviewer` | `5` | Review-round cap per reviewer per mission branch. |
|
|
29
|
+
| `merge.timeoutMs` | `900000` | Default tower_merge timeout, including pre-merge hooks. |
|
|
30
|
+
| `merge.maxBufferBytes` | `67108864` | Captured merge output buffer. |
|
|
31
|
+
| `git.timeoutMs` | `15000` | Default timeout for Git commands other than merge; merge uses merge.timeoutMs. |
|
|
32
|
+
| `worktrees.root` | `` | Default parent directory for mission worktrees; empty derives <main-checkout-parent>/.dsh-tower-worktrees/<hash>. |
|
|
33
|
+
| `spawn.workerPreset` | `"tower-worker"` | Agent preset for worker missions. |
|
|
34
|
+
| `spawn.reviewerPreset` | `"tower-reviewer"` | Agent preset for reviewers. |
|
|
35
|
+
| `spawn.maxDepth` | `1` | Subagent depth requested when spawning tower agents. |
|
|
36
|
+
| `spawn.provider` | `` | Subagent provider id; empty picks spawn, then the first registered provider. |
|
|
37
|
+
| `spawn.workerModel` | `{}` | Model route for workers; omitted inherits the parent session. |
|
|
38
|
+
| `spawn.reviewerModel` | `{}` | Model route for reviewers; omitted inherits the parent session (recommended). |
|
|
39
|
+
| `spawn.maxLiveWorkers` | `4` | Maximum live worker entries allowed per repository at once. |
|
|
40
|
+
| `spawn.staleMs` | `15000` | Roster entries with no catalog activity after this age are marked stale and block merge (0 disables). |
|
|
41
|
+
| `spawn.maxWaitMs` | `90000` | Upper bound for tower_spawn waitMs (default 90s, Kimi-compatible). |
|
|
42
|
+
| `spawn.requireLease` | `` | Optional lease name tower_spawn must hold before starting a worker. |
|
|
43
|
+
| `send.maxPerMinute` | `120` | Per-repository tower_send rate limit per minute (0 disables). |
|
|
44
|
+
| `send.interruptDefault` | `false` | Default value of tower_send.interrupt when the caller omits it. |
|
|
45
|
+
| `tests.enabled` | `true` | Run declared test discovery when a mission configures it. |
|
|
46
|
+
| `tests.admission` | `"off"` | Run discovery before spawning a worker, when completing, or only on explicit tower_test (default off: repository code runs only on an explicit tower_test). |
|
|
47
|
+
| `tests.timeoutMs` | `60000` | Per discovery command timeout. |
|
|
48
|
+
| `tests.maxBytes` | `16777216` | Maximum captured stdout bytes per command. |
|
|
49
|
+
| `tests.autoChecks` | `true` | Attach a tests check to the completion report when discovery runs. |
|
|
50
|
+
| `tests.allowPackageDiscovery` | `true` | Allow package.json tower.testDiscovery commands from the mission worktree (executes repository code; see security docs). |
|
|
51
|
+
| `gates.requireChecks` | `false` | Require at least one completion check (tower_complete.checks) before a mission can merge. |
|
|
52
|
+
| `gates.requireTests` | `false` | Require a passing test-discovery receipt for the reviewed worktree tip before merge. |
|
|
53
|
+
| `gates.allowReviewExemption` | `false` | Allow reviewPolicy:none missions with a non-empty reviewExemptionReason to skip review blockers. |
|
|
54
|
+
| `docs.board` | `true` | Write a human-readable MISSIONS.md after mission changes. |
|
|
55
|
+
| `docs.boardLocation` | `"common"` | common = <git-common-dir>/dsh-tower/MISSIONS.md; repo = <repoRoot>/MISSIONS.md. |
|
|
56
|
+
| `tools.exposeOperational` | `true` | Master switch for batch/resource/import/legacy/recover/test/doctor tools. |
|
|
57
|
+
| `tools.exposeBatch` | `true` | Register tower_batch. |
|
|
58
|
+
| `tools.exposeImport` | `true` | Register tower_import_legacy/tower_legacy_map. |
|
|
59
|
+
| `tools.exposeLeases` | `true` | Register tower_resource advisory leases. |
|
|
60
|
+
| `tools.exposeTests` | `true` | Register tower_test; gates.requireTests requires it. |
|
|
61
|
+
| `tools.exposeRecovery` | `true` | Register tower_recover (stale state-lock escape). |
|
|
62
|
+
| `tools.exposeDoctor` | `true` | Register tower_doctor (read-only health contract). |
|
|
63
|
+
| `leases.ttlMs` | `900000` | Default advisory lease lifetime; expiry never auto-releases. |
|
|
64
|
+
| `dev.hotReload` | `true` | Register tower_reload and /tower reload when the DSH HMR service is available. |
|
|
65
|
+
| `dev.reloadDelayMs` | `50` | Delay before a scheduled reload, so the tool result is delivered first. |
|
|
66
|
+
| `dev.reloadRequiredIds` | `["tower-bundle","tower","tower-skills","preset-tower-worker","preset-tower-reviewer"]` | Loader entry ids passed to reconcileProfile as required. |
|