dsh-tower 2.0.2 → 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.
- package/CHANGELOG.md +57 -0
- package/README.en.md +22 -16
- package/README.md +22 -16
- package/SECURITY.md +4 -1
- package/docs/README.md +30 -0
- package/docs/architecture/overview.md +3 -2
- package/docs/examples/first-mission.md +2 -1
- package/docs/faq.md +15 -6
- package/docs/guide/install-upgrade-migration.md +14 -5
- package/docs/guide/quickstart.md +12 -7
- package/docs/guide/scenarios-and-philosophy.md +150 -62
- package/docs/operations/security.md +23 -12
- package/docs/reference/blockers.md +11 -10
- package/docs/reference/config.md +8 -6
- package/docs/reference/errors.md +7 -1
- package/docs/reference/events.md +7 -4
- package/docs/reference/testing.md +2 -1
- package/docs/reference/tools.md +7 -6
- package/docs/zh/README.md +1 -1
- package/docs/zh/faq.md +12 -4
- package/docs/zh/guide/install-upgrade-migration.md +11 -4
- package/docs/zh/guide/quickstart.md +13 -8
- package/docs/zh/guide/scenarios-and-philosophy.md +108 -36
- package/docs/zh/operations/security.md +16 -6
- package/docs/zh/reference/blockers.md +10 -10
- package/docs/zh/reference/config.md +8 -6
- package/docs/zh/reference/errors.md +2 -1
- package/docs/zh/reference/events.md +6 -3
- package/docs/zh/reference/testing.md +3 -2
- package/docs/zh/reference/tools.md +7 -6
- package/index.js +26 -17
- package/lib/config.js +103 -6
- package/lib/doctor.js +11 -5
- package/lib/errors.js +14 -2
- package/lib/git.js +36 -2
- package/lib/modeStore.js +54 -20
- package/lib/store.js +65 -10
- package/lib/tests.js +35 -1
- package/lib/tools.js +257 -47
- package/lib/tower.js +281 -55
- package/lib/workspaceLock.js +44 -20
- package/package.json +3 -2
- package/scripts/check-docs.mjs +35 -0
- package/skills/tower-recovery.md +7 -5
- 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/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,63 @@
|
|
|
2
2
|
|
|
3
3
|
> 自 2.0.0 起,每个版本按 **新增 / 变更 / 修复** 三类组织;更早的版本保留原始流水式记录。
|
|
4
4
|
|
|
5
|
+
## 2.0.4(2026-10-21)
|
|
6
|
+
|
|
7
|
+
### 变更
|
|
8
|
+
|
|
9
|
+
- **文档索引补齐**:根 README 的“文档”区补上《什么时候用 Tower》链接;`docs/README.md` 新增
|
|
10
|
+
“All pages”完整页面索引(指南 / 参考 / 运维与背景),与中文文档索引对齐。
|
|
11
|
+
- **全量文档与产品一致性审查(功能/哲学)**:把 `review.requireReview` 默认 `false`(审查可选)
|
|
12
|
+
同步到快速开始、示例、FAQ、blocker/测试/架构/配置/迁移说明与中英文页面;修正测试门禁描述为
|
|
13
|
+
当前分支 tip(而非“被审查 tip”);修正单 mission 审查豁免需要
|
|
14
|
+
`gates.allowReviewExemption:true`;补齐 2.0.1–2.0.3 升级说明;README 的“何时使用/工作流对比”
|
|
15
|
+
不再把独立审查写成默认必经步骤。
|
|
16
|
+
- **模型可见工具描述同步**:`tower_plan` 的 `reviewPolicy`、`tower_complete` 的完成语义、
|
|
17
|
+
`tower_preflight` 的 review blocker 条件,以及 reviewer 错误文案不再暗示“完成即等待审查”。
|
|
18
|
+
- **模式控制默认改为 Agent 可操作**:`mode.allowAgentControl` 默认 `true`,`tower_control` 默认注册,
|
|
19
|
+
模型可带理由进出 Tower 模式;设 `false` 可恢复仅人类控制。同步删除文档中的“human-owned/人类掌握”
|
|
20
|
+
表述,改为“可配置、显式且可归因”;模式提示、工具参考、安全模型与 UI 说明一并更新。
|
|
21
|
+
|
|
22
|
+
### 修复
|
|
23
|
+
|
|
24
|
+
- **安全审计 2026-10-21(#13)**:授权解析改为 fail-closed(未登记/无法解析的调用者不再被视为
|
|
25
|
+
tower);`tower_merge` 只合并 gate 校验过的 SHA 并在 gate→merge 间重新校验 base/tip;
|
|
26
|
+
已落地对账要求分支 tip 真正包含在 base;reviewer 身份与 spawn tip 缺失均拒绝;完成时拒绝 dirty
|
|
27
|
+
worktree;spawn 先预留 roster 再启动并在失败时回收;provision/teardown 与状态写入增加回滚/归属
|
|
28
|
+
校验;state/tower 锁改为可安全回收死 PID 并避免删除活跃锁;Git 子进程剥离 `GIT_*` 重定向,
|
|
29
|
+
测试发现使用最小环境;lease status 不再回显 token;仓库级配置只能收紧、不能放宽 `mode.*`;
|
|
30
|
+
恢复 skill 删除破坏性 rm 指引。
|
|
31
|
+
- **GitHub Issues #14–#42 的回归项**:stale roster 可恢复;dirty completion、adopt 重复观测、
|
|
32
|
+
spawn 失败、配置嵌套未知键、doctor 坏配置、teardown 分支删除失败、batch receipt 文件校验、
|
|
33
|
+
mode/control/reload 事件、Git 超时配置、不可变 SHA merge、测试 receipt 体积上限等。
|
|
34
|
+
- **模式状态未知时显式提示**:UI 在无法从已加载历史证明模式时显示 `mode unknown` chip,
|
|
35
|
+
不再静默伪装为关闭;同一 session 还会持久化最近已知模式(7 天过期,仅展示,不单独驱动 denied
|
|
36
|
+
行);新增未知调用者对 `tower_mission` / `tower_test` / finding 工具的身份拒绝。
|
|
37
|
+
- **`tower_recover`**:新增恢复诊断/显式 stale state-lock 清理工具;只移动 PID 已死的锁到备份,
|
|
38
|
+
需要 `confirm:"CLEAR_STALE_LOCK"`,绝不重置 state/worktree。
|
|
39
|
+
- **#30 工具层显式错误码**:tools 层的校验/前置条件不再依赖文本 regex,改为直接抛出带稳定 code 的
|
|
40
|
+
`TowerToolError`(invalid-argument / reviewer-prerequisite / spawn-unavailable / preset-missing /
|
|
41
|
+
not-authorized 等)。
|
|
42
|
+
- **文档与实现不一致**:`gates.requireTests` 文档原写“reviewed tip”,实现校验当前 mission 分支
|
|
43
|
+
tip;已同步英文/中文配置、测试与 blocker 参考。
|
|
44
|
+
|
|
45
|
+
## 2.0.3(2026-10-18)
|
|
46
|
+
|
|
47
|
+
### 新增
|
|
48
|
+
|
|
49
|
+
- **`review.requireReview` 全局开关**:默认 `false`(审查可选);设为 `true` 时合并门禁强制独立 clean
|
|
50
|
+
审查(`no-review`/`not-clean`/`review-hold`/`review-not-approved`/`tip-moved`/
|
|
51
|
+
`review-mission-mismatch`)。`tower_review` 始终可提交并记录;全局开启时单 mission 仍可用
|
|
52
|
+
`reviewPolicy:"none"` + 理由做更窄的豁免。
|
|
53
|
+
|
|
54
|
+
### 变更
|
|
55
|
+
|
|
56
|
+
- **应用场景文档补充具体举例**:`docs/guide/scenarios-and-philosophy.md` 与中文版新增 Tower 七类
|
|
57
|
+
场景的“具体例子/为什么用 Tower”速查表,以及 Tower、Agent Teams、Ralph 循环、Workflow 编排、
|
|
58
|
+
普通并行子代理和混合阶段各自的具体例子;同时说明独立审查默认可选、可全局强制,并更新 README、
|
|
59
|
+
FAQ、配置/安全参考页与中文对应页。
|
|
60
|
+
- **离线套件**:219 项(新增 `review.requireReview:false` 无 reviewer 合并用例)。
|
|
61
|
+
|
|
5
62
|
## 2.0.2(2026-10-18)
|
|
6
63
|
|
|
7
64
|
### 新增
|
package/README.en.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
[](LICENSE)
|
|
6
6
|
[中文说明](README.md)
|
|
7
7
|
|
|
8
|
-
**Tower** is a multi-agent orchestration plugin for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (DSH). It turns one agent session into a small engineering team: the session acts as the *control tower*, worker agents do the implementation inside isolated Git worktrees, and
|
|
8
|
+
**Tower** is a multi-agent orchestration plugin for [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) (DSH). It turns one agent session into a small engineering team: the session acts as the *control tower*, worker agents do the implementation inside isolated Git worktrees, and changes pass scope/merge gates into the base branch; independent review can be enforced by config.
|
|
9
9
|
|
|
10
10
|
Tower mode and its mission/review workflow are inspired by the experimental **Tower mode in [Kimi Code](https://www.kimi.com/code)** by Moonshot AI. This is an independent implementation for DSH and is not affiliated with Moonshot AI; see [Acknowledgements](#acknowledgements).
|
|
11
11
|
|
|
@@ -13,9 +13,9 @@ The repository root **is** the DSH bundle: `package.json` declares `dsh.bundle.p
|
|
|
13
13
|
|
|
14
14
|
## Features
|
|
15
15
|
|
|
16
|
-
- **
|
|
16
|
+
- **Configurable Tower mode.** `/tower` toggles a session-level stance that narrows the tool surface and injects the Tower protocol. `/tower on|off <instruction>` also forwards your instruction to the model in the same step. By default the model may also enter/leave with `tower_control` and a concrete reason; set `mode.allowAgentControl:false` for human-only control.
|
|
17
17
|
- **Missions with real isolation.** Every mission gets its own branch and Git worktree; workers never touch your checkout.
|
|
18
|
-
- **Review-gated merges.**
|
|
18
|
+
- **Review-gated merges.** When `review.requireReview:true`, a reviewer bound to the current branch tip must submit a `clean` / `merge` verdict before merge; the merge gate re-checks scope, staleness, task completion, review history, and worktree ownership before a `--no-ff` merge. Independent review is optional by default (the gate is off); use `reviewPolicy:"none"` + reason plus `gates.allowReviewExemption:true` for a single mission when the global gate is on.
|
|
19
19
|
- **Durable coordination.** Roster, inbox, findings, reviews, and mission state are persisted under `.git/dsh-tower/`, so a restart does not lose the plan.
|
|
20
20
|
- **Safe by default.** While Tower mode is active, `create_goal`, `update_goal(resume)`, `todo_write`, the Team task board, and `spawn_teammate` are refused; a paused goal is never resumed automatically.
|
|
21
21
|
- **Traceable finding lifecycle.** `tower_findings` lists, reads, and moves findings through `open → triaged → fixed` / `wontfix` (and can reopen); only the tower or a worker may change state, while reviewers can only read.
|
|
@@ -33,9 +33,9 @@ Tower is a **delivery protocol for changes to a Git repository**, not the defaul
|
|
|
33
33
|
|
|
34
34
|
- a feature or refactor splits into 2–8 missions with clear scopes that can be reviewed independently;
|
|
35
35
|
- ordering matters (migrations, dependencies, branch freshness, scope reservations);
|
|
36
|
-
- the repository is sensitive or release-bound, and you need
|
|
36
|
+
- the repository is sensitive or release-bound, and you need an auditable merge plus test evidence (enable independent review when required);
|
|
37
37
|
- work spans context compaction, restarts, or multiple days and must be recoverable from local state;
|
|
38
|
-
- "done" means tasks + tests
|
|
38
|
+
- "done" means tasks + tests (and optionally an independent review), not just a confident message in chat.
|
|
39
39
|
|
|
40
40
|
It is a poor fit for one-file or one-line hotfixes, requirements still being discovered, open-ended research, many tiny independent tasks, interactive UI pairing, or cross-repository work. Rule of thumb: **if you would not open a PR for it, Tower is probably too heavy.**
|
|
41
41
|
|
|
@@ -45,7 +45,7 @@ How it differs (full guide: [When to use Tower](docs/guide/scenarios-and-philoso
|
|
|
45
45
|
- **Agent Teams**: shared task board and peer collaboration for design, research, and cross-cutting decisions; integration is usually human, with no hard Git gate.
|
|
46
46
|
- **Ralph loop**: fresh agents retry one objective, good for iterative search/repair; no mission contract or merge review.
|
|
47
47
|
- **Workflow orchestration**: scripted high fan-out/pipelines for audits, batch analysis, and verification; no branch isolation or merge gate.
|
|
48
|
-
- **Tower**: a few missions + isolated writers + independent review + evidence + a merge gate, for "we have decided; land it safely".
|
|
48
|
+
- **Tower**: a few missions + isolated writers + optional independent review + evidence + a merge gate, for "we have decided; land it safely".
|
|
49
49
|
|
|
50
50
|
Tower mode refuses Team/Workflow/Ralph/ordinary subagent tools and clears plan mode so two orchestration protocols do not drive one session. Compose by phase instead: use Workflow/Team to analyze and decide, then Tower to execute the repository change.
|
|
51
51
|
|
|
@@ -78,6 +78,10 @@ dsh plugin --profile <profile> add <absolute path to this repository>
|
|
|
78
78
|
|
|
79
79
|
The Host plugin is loaded when the DSH process starts, so **restart DSH after installing or updating**. Remove it with `remove_bundle` and the package name `dsh-tower`.
|
|
80
80
|
|
|
81
|
+
The optional Web UI ships inside the npm package at `ui-bundle/`: for an npm install the target is
|
|
82
|
+
`<profile>/node_modules/dsh-tower/ui-bundle`, or `ui-bundle/` in a source checkout. Install it with
|
|
83
|
+
`plugin_manager({action:"install_bundle", target:"<that directory>"})`, restart DSH, then refresh the page.
|
|
84
|
+
|
|
81
85
|
## Quick start
|
|
82
86
|
|
|
83
87
|
```text
|
|
@@ -87,16 +91,17 @@ tower_init repoRoot=D:\work\repo # records the base (current bra
|
|
|
87
91
|
tower_plan repoRoot=D:\work\repo missions=[{"title":"Feature A","scope":["src/a/**"],"tasks":["implement","commit"],"kind":"build"}]
|
|
88
92
|
tower_spawn repoRoot=D:\work\repo missionId=M1 role=worker
|
|
89
93
|
# the worker implements and commits in its worktree, calls tower_complete; its final report returns here
|
|
94
|
+
# Optional: enable review.requireReview:true first if you need mandatory independent review
|
|
90
95
|
tower_spawn repoRoot=D:\work\repo missionId=M1 role=reviewer
|
|
91
96
|
# the reviewer inspects read-only and calls tower_review (clean+merge, or p1-Nitems/p2-Nitems)
|
|
92
|
-
tower_preflight repoRoot=D:\work\repo missionId=M1 # expect no-review before review
|
|
97
|
+
tower_preflight repoRoot=D:\work\repo missionId=M1 # review optional by default; with review.requireReview expect no-review before review and ok:true after
|
|
93
98
|
tower_merge repoRoot=D:\work\repo missionId=M1
|
|
94
99
|
tower_teardown repoRoot=D:\work\repo
|
|
95
100
|
|
|
96
101
|
/tower off
|
|
97
102
|
```
|
|
98
103
|
|
|
99
|
-
A small change usually takes one worker mission
|
|
104
|
+
A small change usually takes one worker mission; add one reviewer round when independent review is required. A full copy-paste example is in [docs/examples/first-mission.md](docs/examples/first-mission.md); per-tool parameters are in [docs/reference/tools.md](docs/reference/tools.md).
|
|
100
105
|
|
|
101
106
|
## Commands
|
|
102
107
|
|
|
@@ -124,6 +129,7 @@ Image and file attachments are forwarded together with the instruction as one co
|
|
|
124
129
|
autoPauseGoal: true
|
|
125
130
|
denyTools: [create_goal, todo_write, team_task_create, team_task_update, team_task_reopen, spawn_teammate]
|
|
126
131
|
review:
|
|
132
|
+
requireReview: false # review optional by default; set true to enforce independent review
|
|
127
133
|
maxRoundsPerReviewer: 5
|
|
128
134
|
merge:
|
|
129
135
|
timeoutMs: 900000
|
|
@@ -135,21 +141,21 @@ Image and file attachments are forwarded together with the instruction as one co
|
|
|
135
141
|
maxDepth: 1
|
|
136
142
|
```
|
|
137
143
|
|
|
138
|
-
- `mode.allowAgentControl` defaults to `
|
|
144
|
+
- `mode.allowAgentControl` defaults to `true` in code; the bundled `cordis.patch.yml` also sets it explicitly to `true` so the model may enter/leave when the user intent or task state warrants it, always stating a reason. Set it to `false` for human-only control. The bundled patch also enables `mode.workspaceLock` (single-active tower), `send.interruptDefault`, `init.autoGitInit`, and sets `spawn.staleMs` to 15s.
|
|
139
145
|
- `/tower base <branch>` records a session-level init base preference; `/tower on` clears an active plan mode (`mode.planModePolicy:"refuse"` instead refuses entry), keeping plan and Tower mutually exclusive.
|
|
140
146
|
- Repository-level config: put the same JSON shape in `<git-common-dir>/dsh-tower/config.json` (usually `.git/dsh-tower/config.json`) to override `review`/`merge`/`worktrees`/`spawn`. Precedence is code defaults < profile config < repository config < tool arguments. `mode.*` is session-scoped and only the profile layer controls it.
|
|
141
147
|
- Every key and default is in [docs/reference/config.md](docs/reference/config.md); unknown top-level keys are rejected so typos cannot silently disable security-relevant settings, while unknown keys inside a group are ignored. Tool error codes are in [docs/reference/errors.md](docs/reference/errors.md).
|
|
142
148
|
|
|
143
|
-
## Tools (
|
|
149
|
+
## Tools (27 core)
|
|
144
150
|
|
|
145
|
-
`tower_init` · `tower_plan` · `tower_mission` · `tower_status` · `tower_spawn` · `tower_roster` · `tower_adopt` · `tower_diff` · `tower_send` · `tower_inbox` · `tower_complete` · `tower_interrupt` · `tower_finding` · `tower_findings` · `tower_review` · `tower_preflight` · `tower_merge` · `tower_rebase` · `tower_teardown` · `tower_mode` · `tower_doctor` · `tower_test` · `tower_batch` · `tower_resource` · `tower_import_legacy` · `tower_legacy_map`
|
|
151
|
+
`tower_init` · `tower_plan` · `tower_mission` · `tower_status` · `tower_spawn` · `tower_roster` · `tower_adopt` · `tower_diff` · `tower_send` · `tower_inbox` · `tower_complete` · `tower_interrupt` · `tower_finding` · `tower_findings` · `tower_review` · `tower_preflight` · `tower_merge` · `tower_rebase` · `tower_teardown` · `tower_mode` · `tower_doctor` · `tower_recover` · `tower_test` · `tower_batch` · `tower_resource` · `tower_import_legacy` · `tower_legacy_map`
|
|
146
152
|
|
|
147
|
-
`tower_control`
|
|
153
|
+
`tower_control` is registered by default (`allowAgentControl:true`); set it to `false` to disable it. `tower_reload` is registered while `dev.hotReload` is on (default true) and returns `reload-unavailable` without an HMR service (so up to 29 tools). Mission-scoped tools also accept `id` as an alias for `missionId`; snake/camel spellings such as `task_done`/`taskDone` are both accepted.
|
|
148
154
|
|
|
149
155
|
## Safety and guardrails
|
|
150
156
|
|
|
151
157
|
- **No merge without a green gate.** `tower_preflight` is read-only and reports stable blocker codes; `tower_merge` refuses when any blocker remains.
|
|
152
|
-
- **Review is bound to a commit.**
|
|
158
|
+
- **Review is bound to a commit when enabled.** With `review.requireReview:true`, a moved tip reports `tip-moved` and requires a fresh review; reviewers use a read-only preset, and a branch change during review is rejected.
|
|
153
159
|
- **Scope enforcement.** A mission may only change files matched by its declared scope globs; `out-of-scope` blocks the merge.
|
|
154
160
|
- **Worktree ownership.** Dirty worktrees, a running worker, or a branch owned by a closed mission block teardown/merge.
|
|
155
161
|
- **Goal isolation.** Entering Tower mode pauses the active goal and records it; leaving does not resume it. Use `/tower off` and resume the goal yourself.
|
|
@@ -197,7 +203,7 @@ The offline suite needs no DSH process and creates throwaway Git repositories in
|
|
|
197
203
|
## Documentation
|
|
198
204
|
|
|
199
205
|
- [docs/README.md](docs/README.md) — documentation index (new user / operator / maintainer paths)
|
|
200
|
-
- [Chinese docs](docs/zh/README.md) · [Quick start](docs/guide/quickstart.md) · [Install, upgrade and migration](docs/guide/install-upgrade-migration.md)
|
|
206
|
+
- [Chinese docs](docs/zh/README.md) · [Quick start](docs/guide/quickstart.md) · [When to use Tower](docs/guide/scenarios-and-philosophy.md) · [Install, upgrade and migration](docs/guide/install-upgrade-migration.md)
|
|
201
207
|
- [Tools reference](docs/reference/tools.md) · [Config reference](docs/reference/config.md) · [Blockers and failure codes](docs/reference/blockers.md) · [Error codes](docs/reference/errors.md) · [Events](docs/reference/events.md) · [Testing](docs/reference/testing.md) · [Batches/leases/legacy](docs/reference/operations.md) · [Doctor](docs/reference/doctor.md) · [Hot reload](docs/guide/hot-reload.md)
|
|
202
208
|
- [Architecture and state machine](docs/architecture/overview.md) · [Operations runbook](docs/operations/runbook.md) · [Security model](docs/operations/security.md)
|
|
203
209
|
- [FAQ](docs/faq.md) · [Examples](docs/examples/first-mission.md)
|
|
@@ -205,7 +211,7 @@ The offline suite needs no DSH process and creates throwaway Git repositories in
|
|
|
205
211
|
## Troubleshooting
|
|
206
212
|
|
|
207
213
|
- **The plugin does not appear after install/update.** Host plugins load at DSH startup; restart DSH. Confirm the entry point targets this repository root (the folder with `package.json` and `cordis.patch.yml`), not a subdirectory.
|
|
208
|
-
- **`tower_control` is missing.** The config `allowAgentControl
|
|
214
|
+
- **`tower_control` is missing.** The config sets `allowAgentControl:false`; set it back to `true` and restart.
|
|
209
215
|
- **Merge is blocked.** Run `tower_preflight` and read the blocker codes above; `stale-base` means run `tower_rebase` first.
|
|
210
216
|
- **A mission branch is stale after base moved.** `tower_rebase` rebases inside the worktree; a clean conflict-free rebase waives re-review for the previous verdict.
|
|
211
217
|
- **A merge commit exists but `tower_merge` reported a failure.** Re-run `tower_merge`: it detects the landed merge commit (or a branch already contained in the base) and records it as reconciled instead of merging twice.
|
|
@@ -217,7 +223,7 @@ Issues and pull requests are welcome. Please run `npm test` before opening a PR;
|
|
|
217
223
|
|
|
218
224
|
## Acknowledgements
|
|
219
225
|
|
|
220
|
-
- **Kimi Code (Moonshot AI)** — the Tower mode concept, including
|
|
226
|
+
- **Kimi Code (Moonshot AI)** — the Tower mode concept, including an explicit session-level mode switch, an isolated Git worktree per mission, and the review-gated merge protocol, is inspired by the experimental Tower mode in [Kimi Code](https://www.kimi.com/code) ([source](https://github.com/MoonshotAI/kimi-code)). This project re-implements those ideas on top of DeepSeek Harness services; it contains no Kimi Code source code and is not affiliated with or endorsed by Moonshot AI.
|
|
221
227
|
- **DeepSeek Harness** — for the plugin, tool, session, and subagent APIs this project is built on.
|
|
222
228
|
|
|
223
229
|
## License
|
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
[](LICENSE)
|
|
6
6
|
[English](README.en.md)
|
|
7
7
|
|
|
8
|
-
**Tower** 是 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)(DSH)的多代理编排插件。它把一个 agent 会话变成一个小型工程团队:会话本身是*控制塔*,worker agent 在隔离的 Git worktree
|
|
8
|
+
**Tower** 是 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness)(DSH)的多代理编排插件。它把一个 agent 会话变成一个小型工程团队:会话本身是*控制塔*,worker agent 在隔离的 Git worktree 里实现任务,改动经 scope/合并门禁合入基线分支;独立审查可在配置中强制开启。
|
|
9
9
|
|
|
10
10
|
Tower 模式与 mission/审查工作流的灵感来自 Moonshot AI 的 **Kimi Code** 中实验性的 Tower 模式([Kimi Code](https://www.kimi.com/code))。本项目是面向 DSH 的独立实现,与 Moonshot AI 无隶属关系;详见[致谢](#致谢)。
|
|
11
11
|
|
|
@@ -13,9 +13,9 @@ Tower 模式与 mission/审查工作流的灵感来自 Moonshot AI 的 **Kimi Co
|
|
|
13
13
|
|
|
14
14
|
## 特性
|
|
15
15
|
|
|
16
|
-
-
|
|
16
|
+
- **可配置的 Tower 模式。** `/tower` 切换会话级模式:收窄工具面并注入 Tower 协议;`/tower on|off <指令>` 还能把指令作为下一步用户消息转发给模型。默认也允许 Agent 通过 `tower_control` 带理由进出;设 `mode.allowAgentControl:false` 可改为仅人类控制。
|
|
17
17
|
- **任务级隔离。** 每个 mission 使用独立分支和 Git worktree,worker 不会碰到你的主检出。
|
|
18
|
-
- **审查门禁合并。**
|
|
18
|
+
- **审查门禁合并。** 开启 `review.requireReview:true` 时,审查者针对当前分支 tip 给出 `clean` / `merge` 结论;合并门禁重新校验 scope、分支新鲜度、任务完成度、审查记录与 worktree 归属,通过后才执行 `--no-ff` 合并。独立审查默认可选(门禁关闭);全局开启时,单个 mission 用 `reviewPolicy:"none"` + 理由并开启 `gates.allowReviewExemption:true` 做更窄豁免。
|
|
19
19
|
- **可恢复的协作状态。** roster、inbox、findings、reviews 与 mission 状态持久化在 `.git/dsh-tower/` 下,重启不会丢计划。
|
|
20
20
|
- **默认安全。** Tower 模式开启期间拒绝 `create_goal`、`update_goal(resume)`、`todo_write`、Team 任务板与 `spawn_teammate`;被暂停的 goal 不会被自动恢复。
|
|
21
21
|
- **可追溯的 finding 生命周期。** `tower_findings` 列表、读取并按 `open → triaged → fixed` / `wontfix` 流转,也可重新打开;只有 tower 或 worker 能改状态,reviewer 只能读。
|
|
@@ -33,9 +33,9 @@ Tower 是**面向 Git 仓库变更的交付协议**,不是所有多代理场
|
|
|
33
33
|
|
|
34
34
|
- 一个特性/重构能拆成 2–8 个 scope 清晰、可独立审查的 mission;
|
|
35
35
|
- 有依赖顺序、需要分支新鲜度与 scope 约束的迁移;
|
|
36
|
-
- 敏感仓库、发布绑定变更,或需要"
|
|
36
|
+
- 敏感仓库、发布绑定变更,或需要"可审计合并 + 测试证据"(需要时开启独立审查)的工作;
|
|
37
37
|
- 跨上下文压缩、重启、多天协作,需要从本地状态恢复的工作;
|
|
38
|
-
- 需要把"完成"定义成任务 +
|
|
38
|
+
- 需要把"完成"定义成任务 + 测试(可选独立审查),而不是聊天里的一句"好了"。
|
|
39
39
|
|
|
40
40
|
不适合:单文件/一行 hotfix、需求仍在探索、开放式研究、大量极小的独立任务、交互式 UI 配对、或跨仓库工作。判断标准:**如果你不会为它开 PR,Tower 很可能太重。**
|
|
41
41
|
|
|
@@ -45,7 +45,7 @@ Tower 是**面向 Git 仓库变更的交付协议**,不是所有多代理场
|
|
|
45
45
|
- **Agent Teams**:共享任务板与多人/多 agent 协作,适合设计、研究、横切决策;集成通常由人做,没有 Git 隔离的硬门禁。
|
|
46
46
|
- **Ralph 循环**:用新鲜 agent 对同一目标反复尝试,适合迭代搜索/修复;没有 mission 契约与合并审查。
|
|
47
47
|
- **Workflow 编排**:脚本化高扇出/流水线,适合批量分析、审计、验证;不做 Git 分支隔离与合并门禁。
|
|
48
|
-
- **Tower**:少量 mission + 隔离写入 +
|
|
48
|
+
- **Tower**:少量 mission + 隔离写入 + 可选独立审查 + 证据 + 合并门禁,适合"决定要做、需要安全落地"的仓库变更。
|
|
49
49
|
|
|
50
50
|
Tower 模式会拒绝 Team/Workflow/Ralph/普通 subagent 工具并清除 plan mode,避免两套编排协议同时驱动一个会话;请按阶段组合,例如先用 Workflow/Team 分析决策,再用 Tower 执行仓库变更。
|
|
51
51
|
|
|
@@ -78,6 +78,10 @@ dsh plugin --profile <profile> add <本仓库的绝对路径>
|
|
|
78
78
|
|
|
79
79
|
Host 插件在 DSH 进程启动时加载,**安装或更新后需重启 DSH**。卸载使用 `remove_bundle`,包名 `dsh-tower`。
|
|
80
80
|
|
|
81
|
+
可选的 Web UI 随 npm 包一起发布在 `ui-bundle/`:npm 安装后目标为
|
|
82
|
+
`<profile>/node_modules/dsh-tower/ui-bundle`,源码安装时为目标仓库的 `ui-bundle/` 目录。用
|
|
83
|
+
`plugin_manager({action:"install_bundle", target:"<该目录>"})` 安装并重启 DSH,然后刷新页面。
|
|
84
|
+
|
|
81
85
|
## 快速开始
|
|
82
86
|
|
|
83
87
|
```text
|
|
@@ -87,16 +91,17 @@ tower_init repoRoot=D:\work\repo # 首次初始化,记录 base
|
|
|
87
91
|
tower_plan repoRoot=D:\work\repo missions=[{"title":"Feature A","scope":["src/a/**"],"tasks":["implement","commit"],"kind":"build"}]
|
|
88
92
|
tower_spawn repoRoot=D:\work\repo missionId=M1 role=worker
|
|
89
93
|
# worker 在 worktree 内实现并提交,调用 tower_complete;最终报告会返回本会话
|
|
94
|
+
# 可选:需要强制独立审查时,先开启 review.requireReview:true
|
|
90
95
|
tower_spawn repoRoot=D:\work\repo missionId=M1 role=reviewer
|
|
91
96
|
# reviewer 只读审查并调用 tower_review(clean+merge 或 p1-Nitems/p2-Nitems)
|
|
92
|
-
tower_preflight repoRoot=D:\work\repo missionId=M1 #
|
|
97
|
+
tower_preflight repoRoot=D:\work\repo missionId=M1 # 默认审查可选;开启 review.requireReview 时审查前预期 no-review,审查后 ok:true
|
|
93
98
|
tower_merge repoRoot=D:\work\repo missionId=M1
|
|
94
99
|
tower_teardown repoRoot=D:\work\repo
|
|
95
100
|
|
|
96
101
|
/tower off
|
|
97
102
|
```
|
|
98
103
|
|
|
99
|
-
小改动通常一轮 worker
|
|
104
|
+
小改动通常一轮 worker 即可完成;需要独立审查时再加一轮 reviewer。完整可复制示例见 [docs/examples/first-mission.md](docs/examples/first-mission.md),逐工具参数见 [docs/reference/tools.md](docs/reference/tools.md)。
|
|
100
105
|
|
|
101
106
|
## 命令
|
|
102
107
|
|
|
@@ -124,6 +129,7 @@ tower_teardown repoRoot=D:\work\repo
|
|
|
124
129
|
autoPauseGoal: true
|
|
125
130
|
denyTools: [create_goal, todo_write, team_task_create, team_task_update, team_task_reopen, spawn_teammate]
|
|
126
131
|
review:
|
|
132
|
+
requireReview: false # 默认审查可选;需要强制独立审查时改为 true
|
|
127
133
|
maxRoundsPerReviewer: 5
|
|
128
134
|
merge:
|
|
129
135
|
timeoutMs: 900000
|
|
@@ -135,21 +141,21 @@ tower_teardown repoRoot=D:\work\repo
|
|
|
135
141
|
maxDepth: 1
|
|
136
142
|
```
|
|
137
143
|
|
|
138
|
-
- 代码中 `mode.allowAgentControl` 默认 `
|
|
144
|
+
- 代码中 `mode.allowAgentControl` 默认 `true`;随包 `cordis.patch.yml` 也显式设为 `true`:模型可在用户意图/任务状态明确时自行进出,但必须给出理由;设为 `false` 时只有人类能切换。随包 patch 还默认开启 `mode.workspaceLock`(单活塔)、`send.interruptDefault`、`init.autoGitInit`,并把 `spawn.staleMs` 设为 15s。
|
|
139
145
|
- `/tower base <branch>` 可设置会话级 init base 偏好;`/tower on` 会清除活跃 plan mode(`mode.planModePolicy:"refuse"` 则拒绝进入),保证 plan/tower 互斥。
|
|
140
146
|
- 仓库级配置:在 `<git-common-dir>/dsh-tower/config.json`(通常是 `.git/dsh-tower/config.json`)放入同样的 JSON 结构,可覆盖 `review`/`merge`/`worktrees`/`spawn`;优先级为代码默认 < profile < 仓库配置 < 工具参数。`mode.*` 属于会话级,只在 profile 生效。
|
|
141
147
|
- 所有键与默认值见 [docs/reference/config.md](docs/reference/config.md);未知顶层键会被拒绝(防止拼写错误静默失效),嵌套分组内的未知键会被忽略。工具错误码见 [docs/reference/errors.md](docs/reference/errors.md)。
|
|
142
148
|
|
|
143
|
-
## 工具(
|
|
149
|
+
## 工具(27 个核心)
|
|
144
150
|
|
|
145
|
-
`tower_init` · `tower_plan` · `tower_mission` · `tower_status` · `tower_spawn` · `tower_roster` · `tower_adopt` · `tower_diff` · `tower_send` · `tower_inbox` · `tower_complete` · `tower_interrupt` · `tower_finding` · `tower_findings` · `tower_review` · `tower_preflight` · `tower_merge` · `tower_rebase` · `tower_teardown` · `tower_mode` · `tower_doctor` · `tower_test` · `tower_batch` · `tower_resource` · `tower_import_legacy` · `tower_legacy_map`
|
|
151
|
+
`tower_init` · `tower_plan` · `tower_mission` · `tower_status` · `tower_spawn` · `tower_roster` · `tower_adopt` · `tower_diff` · `tower_send` · `tower_inbox` · `tower_complete` · `tower_interrupt` · `tower_finding` · `tower_findings` · `tower_review` · `tower_preflight` · `tower_merge` · `tower_rebase` · `tower_teardown` · `tower_mode` · `tower_doctor` · `tower_recover` · `tower_test` · `tower_batch` · `tower_resource` · `tower_import_legacy` · `tower_legacy_map`
|
|
146
152
|
|
|
147
|
-
`tower_control`
|
|
153
|
+
`tower_control` 默认注册(`allowAgentControl:true`);设为 `false` 可禁用;`tower_reload` 在 `dev.hotReload`(默认 true)时注册,无 HMR 服务调用会返回 `reload-unavailable`(因此最多 29 个工具)。mission 级工具同时接受 `id` 作为 `missionId` 的别名;`task_done`/`taskDone` 等 snake/camel 写法均可。
|
|
148
154
|
|
|
149
155
|
## 安全与约束
|
|
150
156
|
|
|
151
157
|
- **门禁不全绿不合并。** `tower_preflight` 是只读检查,返回稳定的 blocker code;存在 blocker 时 `tower_merge` 拒绝合并。
|
|
152
|
-
- **审查绑定提交。**
|
|
158
|
+
- **审查绑定提交。** 开启 `review.requireReview` 时,审查后分支 tip 变化会报 `tip-moved`,必须重新审查;reviewer 使用只读 preset,若在审查期间改动分支,提交审查会被拒绝。
|
|
153
159
|
- **scope 强制。** mission 只能修改其 scope glob 匹配的文件,越界会以 `out-of-scope` 阻止合并。
|
|
154
160
|
- **worktree 归属。** 脏工作树、运行中的 worker、已关闭 mission 的分支都会阻止合并或 teardown。
|
|
155
161
|
- **goal 隔离。** 进入 Tower 模式会暂停活跃 goal 并记录;退出不会自动恢复,需要你自行恢复。
|
|
@@ -193,7 +199,7 @@ npm test # node --test tests/*.test.mjs
|
|
|
193
199
|
## 文档
|
|
194
200
|
|
|
195
201
|
- [docs/README.md](docs/README.md) — 文档索引(新用户 / 运维 / 维护者三条阅读路径)
|
|
196
|
-
- [中文文档](docs/zh/README.md) · [快速开始](docs/guide/quickstart.md) · [安装、升级与迁移](docs/guide/install-upgrade-migration.md)
|
|
202
|
+
- [中文文档](docs/zh/README.md) · [快速开始](docs/guide/quickstart.md) · [何时使用 Tower](docs/guide/scenarios-and-philosophy.md) · [安装、升级与迁移](docs/guide/install-upgrade-migration.md)
|
|
197
203
|
- [工具参考](docs/reference/tools.md) · [配置参考](docs/reference/config.md) · [blocker 与失败码](docs/reference/blockers.md) · [错误码](docs/reference/errors.md) · [事件](docs/reference/events.md) · [测试准入](docs/reference/testing.md) · [批次/租约/旧版](docs/reference/operations.md) · [Doctor](docs/reference/doctor.md) · [热重载](docs/guide/hot-reload.md)
|
|
198
204
|
- [架构与状态机](docs/architecture/overview.md) · [运维 runbook](docs/operations/runbook.md) · [安全模型](docs/operations/security.md)
|
|
199
205
|
- [FAQ](docs/faq.md) · [示例](docs/examples/first-mission.md)
|
|
@@ -201,7 +207,7 @@ npm test # node --test tests/*.test.mjs
|
|
|
201
207
|
## 常见问题
|
|
202
208
|
|
|
203
209
|
- **安装/更新后插件不出现。** Host 插件在 DSH 启动时加载,请重启 DSH;并确认安装目标指向本仓库根目录(含 `package.json` 与 `cordis.patch.yml` 的那一层),而不是子目录。
|
|
204
|
-
- **没有 `tower_control`。**
|
|
210
|
+
- **没有 `tower_control`。** 配置中被设为 `allowAgentControl:false`;改回 `true` 并重启。
|
|
205
211
|
- **合并被阻止。** 运行 `tower_preflight` 查看 blocker code;`stale-base` 表示先执行 `tower_rebase`。
|
|
206
212
|
- **基线前进后分支过期。** `tower_rebase` 在 worktree 内完成 rebase;干净且无冲突的 rebase 可免去上一轮审查的重审。
|
|
207
213
|
- **合并提交已经存在,但 `tower_merge` 报了失败。** 重新执行 `tower_merge` 即可:它会检测已落地的合并提交(或分支已包含在 base 中)并记录为 reconciled,不会重复合并。
|
|
@@ -213,7 +219,7 @@ npm test # node --test tests/*.test.mjs
|
|
|
213
219
|
|
|
214
220
|
## 致谢
|
|
215
221
|
|
|
216
|
-
- **Kimi Code(Moonshot AI)**:Tower
|
|
222
|
+
- **Kimi Code(Moonshot AI)**:Tower 模式的整体概念——明确的会话级模式开关、每个 mission 独立 Git worktree、审查门禁合并协议——灵感来自 Kimi Code 的实验性 Tower 模式([官网](https://www.kimi.com/code)、[源码](https://github.com/MoonshotAI/kimi-code))。本项目在 DeepSeek Harness 的服务之上重新实现这些想法,不包含 Kimi Code 源码,也与 Moonshot AI 无隶属关系。
|
|
217
223
|
- **DeepSeek Harness**:本插件构建所依赖的插件、工具、会话与子代理 API。
|
|
218
224
|
|
|
219
225
|
## License
|
package/SECURITY.md
CHANGED
|
@@ -17,4 +17,7 @@ Please do **not** publish exploit details in a public issue. Open a minimal issu
|
|
|
17
17
|
|
|
18
18
|
## Supported versions
|
|
19
19
|
|
|
20
|
-
Security fixes target the latest released
|
|
20
|
+
Security fixes target the latest released `2.x` line (currently `2.0.4`). Older pre-release snapshots
|
|
21
|
+
are not maintained. Private reports are acknowledged in the minimal public issue and handled through
|
|
22
|
+
the maintainer's private channel; do not attach exploit details, tokens, or production logs to a
|
|
23
|
+
public issue.
|
package/docs/README.md
CHANGED
|
@@ -16,3 +16,33 @@ Reference pages are the source of truth for the current release; the [tools refe
|
|
|
16
16
|
implementation by `npm run docs:check` in CI (including the Chinese pages).
|
|
17
17
|
|
|
18
18
|
Other useful pages: [When to use Tower](guide/scenarios-and-philosophy.md), [Install, upgrade and migration](guide/install-upgrade-migration.md), [Hot reload](guide/hot-reload.md), [FAQ](faq.md), [CHANGELOG](../CHANGELOG.md).
|
|
19
|
+
|
|
20
|
+
## All pages
|
|
21
|
+
|
|
22
|
+
**Guides**
|
|
23
|
+
|
|
24
|
+
- [When to use Tower, and how it differs from Agent Teams, Ralph, Workflow and parallel subagents](guide/scenarios-and-philosophy.md)
|
|
25
|
+
- [Quick start](guide/quickstart.md)
|
|
26
|
+
- [Install, upgrade and migration](guide/install-upgrade-migration.md)
|
|
27
|
+
- [Hot reload (development)](guide/hot-reload.md)
|
|
28
|
+
|
|
29
|
+
**Reference**
|
|
30
|
+
|
|
31
|
+
- [Tools](reference/tools.md)
|
|
32
|
+
- [Configuration](reference/config.md)
|
|
33
|
+
- [Blockers and failure codes](reference/blockers.md)
|
|
34
|
+
- [Tool error codes](reference/errors.md)
|
|
35
|
+
- [Events](reference/events.md)
|
|
36
|
+
- [Testing and evidence](reference/testing.md)
|
|
37
|
+
- [Batches, leases and legacy import](reference/operations.md)
|
|
38
|
+
- [Doctor](reference/doctor.md)
|
|
39
|
+
|
|
40
|
+
**Operations and background**
|
|
41
|
+
|
|
42
|
+
- [Operations runbook](operations/runbook.md)
|
|
43
|
+
- [Security model](operations/security.md)
|
|
44
|
+
- [Architecture and state machine](architecture/overview.md)
|
|
45
|
+
- [First mission example](examples/first-mission.md)
|
|
46
|
+
- [FAQ](faq.md)
|
|
47
|
+
|
|
48
|
+
Chinese pages: [中文文档索引](zh/README.md).
|
|
@@ -46,8 +46,9 @@ set by `tower_merge`/reconciliation.
|
|
|
46
46
|
3. Survey missions must not change files; build missions must stay inside `scope`.
|
|
47
47
|
4. The main checkout must be clean for the files this merge would overwrite and on the base branch.
|
|
48
48
|
5. Dependency missions must be merged/abandoned.
|
|
49
|
-
6.
|
|
50
|
-
(unless a clean rebase waived it). No worker may be
|
|
49
|
+
6. If `review.requireReview:true` (default false), a review must exist, belong to this mission, be
|
|
50
|
+
clean, approve merge, and be bound to the tip (unless a clean rebase waived it). No worker may be
|
|
51
|
+
running.
|
|
51
52
|
|
|
52
53
|
## Merge
|
|
53
54
|
|
|
@@ -23,7 +23,8 @@ Wait for the worker's final report (delivered to this session) or check `tower_r
|
|
|
23
23
|
creates `src/greet.txt`, commits on `tower/m1-add-greeting`, marks both tasks done, and calls
|
|
24
24
|
`tower_complete`.
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
This example follows the strict workflow: enable `review.requireReview:true` in the profile or
|
|
27
|
+
repository config before the review step (default is optional review). Spawn the reviewer:
|
|
27
28
|
|
|
28
29
|
```json
|
|
29
30
|
{"repoRoot":"D:\\work\\demo","missionId":"M1","role":"reviewer"}
|
package/docs/faq.md
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
# FAQ
|
|
2
2
|
|
|
3
3
|
**When should I use Tower instead of Agent Teams, Ralph, Workflow, or ordinary subagents?**
|
|
4
|
-
Use Tower when the output is
|
|
4
|
+
Use Tower when the output is an integrated change to one Git repository (enable review when you also
|
|
5
|
+
need an independent verdict). Use ordinary
|
|
5
6
|
subagents for read-only exploration or quick independent subtasks, Agent Teams for cross-cutting human
|
|
6
7
|
collaboration, Ralph for repeated fresh attempts at one objective, and Workflow for programmatic
|
|
7
8
|
high-fan-out analysis. The full decision guide, scenarios, and comparison table are in
|
|
@@ -9,19 +10,21 @@ high-fan-out analysis. The full decision guide, scenarios, and comparison table
|
|
|
9
10
|
|
|
10
11
|
**Can I combine Tower with Team/Workflow/Ralph?**
|
|
11
12
|
Not concurrently in the same session: Tower mode refuses their tools and clears plan mode. Compose by
|
|
12
|
-
phase instead—use Workflow/Team to analyze and decide, then start Tower to execute and
|
|
13
|
-
repository change. See the [full guide](guide/scenarios-and-philosophy.md#4-how-tower-differs-from-other-dsh-workflow-patterns).
|
|
13
|
+
phase instead—use Workflow/Team to analyze and decide, then start Tower to execute (and optionally
|
|
14
|
+
review) the repository change. See the [full guide](guide/scenarios-and-philosophy.md#4-how-tower-differs-from-other-dsh-workflow-patterns).
|
|
14
15
|
|
|
15
16
|
**Why did `tower_preflight` fail with `no-review` right after the worker finished?**
|
|
16
|
-
That
|
|
17
|
-
turns green.
|
|
17
|
+
That happens only when `review.requireReview:true` is enabled: a completed mission awaits an
|
|
18
|
+
independent review. Spawn a reviewer; after a clean review the gate turns green. With the default
|
|
19
|
+
`review.requireReview:false`, review is optional and no `no-review` blocker is produced.
|
|
18
20
|
|
|
19
21
|
**Do I need to poll the worker?**
|
|
20
22
|
No. The worker's final report is delivered to this session; `tower_roster` shows live activity. Polling
|
|
21
23
|
wastes turns.
|
|
22
24
|
|
|
23
25
|
**`/tower` says the mode is on but `tower_control` is missing.**
|
|
24
|
-
`mode.allowAgentControl` is
|
|
26
|
+
`mode.allowAgentControl` is disabled. It defaults to `true`; if it was set to `false`, set it back to
|
|
27
|
+
`true` in the profile patch and restart DSH.
|
|
25
28
|
|
|
26
29
|
**The merge hook takes minutes and `tower_merge` failed.**
|
|
27
30
|
Retry with a larger `timeoutMs`: `tower_merge({ missionId, timeoutMs: 1800000 })`. The default is 15
|
|
@@ -36,6 +39,12 @@ whose commit exists (`recoveredFromFailure`) and records it.
|
|
|
36
39
|
Correct: the branch is already contained in the base. Call `tower_merge` to record the landed merge
|
|
37
40
|
instead of rebasing.
|
|
38
41
|
|
|
42
|
+
**Can I require independent review?**
|
|
43
|
+
Yes. Set `review.requireReview:true` in the profile or repository config to enable the global review
|
|
44
|
+
gate (default is `false`, review optional). When enabled, mission-level `reviewPolicy:"none"` + a
|
|
45
|
+
reason + `gates.allowReviewExemption:true` is the narrower exemption. `tower_review` works and records
|
|
46
|
+
verdicts either way.
|
|
47
|
+
|
|
39
48
|
**Can a reviewer edit files?**
|
|
40
49
|
No. Reviewers use the read-only `tower-reviewer` preset (no write/edit/pwsh); a branch changed after the
|
|
41
50
|
reviewer spawned is rejected. Reviewers file `tower_finding` for issues outside the mission.
|
|
@@ -29,13 +29,22 @@ The Host plugin loads at DSH startup: **restart DSH after install or update**.
|
|
|
29
29
|
|
|
30
30
|
## Migration notes
|
|
31
31
|
|
|
32
|
-
- **
|
|
32
|
+
- **2.0.3 → 2.0.4**: no state/config migration. This is a security-hardening and integrity release
|
|
33
|
+
(authorization, merge SHA binding, dirty-worktree completion, stale-lock recovery, limited test/git
|
|
34
|
+
process environment, `tower_recover`, UI 0.2.2). Review `review.requireReview`, `tests.admission` and
|
|
35
|
+
worker tool permissions against your threat model after upgrading.
|
|
36
|
+
- **2.0.1 → 2.0.3**: no state migration. Independent review became **optional by default** in 2.0.3
|
|
37
|
+
(`review.requireReview:false`); set it to `true` to keep the old review-gated merges. 2.0.1 added
|
|
38
|
+
`tower_batch` `abandon`, accepted merged members in batch close, made doctor skip torn-down worktrees,
|
|
39
|
+
and fixed terminal-mission spawn/preflight edge cases. The optional `ui-bundle` 0.2.1 adds the
|
|
40
|
+
persistent Tower-mode chip and mode-aware denied-tool rows.
|
|
41
|
+
- **1.x → 2.0 (released)**: no state migration is needed (`schemaVersion` stays 1; new fields are
|
|
33
42
|
optional). Behavior changes to review: `mode.denyTools` now also denies `workflow`, `ralph`, `subagent`,
|
|
34
43
|
`subagent_fork`, `wait_agent` and `team_task_list` while Tower mode is active (override with an explicit
|
|
35
|
-
list); `spawn.maxLiveWorkers` defaults to 4; `mode.workspaceLock` is off
|
|
36
|
-
longer complete/abandon/scope a mission directly — use
|
|
37
|
-
and `tower_reload` when HMR is available. Restart DSH
|
|
38
|
-
[hot reload](hot-reload.md).
|
|
44
|
+
list); `spawn.maxLiveWorkers` defaults to 4; `mode.workspaceLock` is off in the code default and on in
|
|
45
|
+
the bundled patch. Workers can no longer complete/abandon/scope a mission directly — use
|
|
46
|
+
`tower_complete`. New tools: `tower_interrupt`, and `tower_reload` when HMR is available. Restart DSH
|
|
47
|
+
once after upgrading; see [hot reload](hot-reload.md).
|
|
39
48
|
- **1.3 → 1.4**: no state migration is needed. New: repository-level config
|
|
40
49
|
(`<git-common-dir>/dsh-tower/config.json`), stable `[tower:<code>]` tool errors, `tower_findings`,
|
|
41
50
|
and `id`/`missionId` + snake/camel input aliases. Existing calls keep working; restart DSH to load
|
package/docs/guide/quickstart.md
CHANGED
|
@@ -31,14 +31,17 @@ The call returns immediately with the child agent id. The worker works inside th
|
|
|
31
31
|
commits, marks tasks done, and calls `tower_complete`; its final report is delivered back to this
|
|
32
32
|
session. Use `tower_roster` to observe activity; do not poll in a loop.
|
|
33
33
|
|
|
34
|
-
## 4.
|
|
34
|
+
## 4. Optional: review
|
|
35
|
+
|
|
36
|
+
Independent review is optional by default. If you want the strict workflow, enable it in the profile
|
|
37
|
+
or repository config first (`review.requireReview:true`), then:
|
|
35
38
|
|
|
36
39
|
```
|
|
37
40
|
tower_spawn repoRoot=D:\work\repo missionId=M1 role=reviewer
|
|
38
41
|
```
|
|
39
42
|
|
|
40
43
|
Reviewers use the read-only `tower-reviewer` preset. They inspect `tower_diff` and submit
|
|
41
|
-
`tower_review
|
|
44
|
+
`tower_review`; with `review.requireReview:true`, a `clean` + `merge` verdict is required to merge.
|
|
42
45
|
|
|
43
46
|
## 5. Gate, merge, clean up
|
|
44
47
|
|
|
@@ -48,8 +51,9 @@ tower_merge repoRoot=D:\work\repo missionId=M1
|
|
|
48
51
|
tower_teardown repoRoot=D:\work\repo
|
|
49
52
|
```
|
|
50
53
|
|
|
51
|
-
`tower_preflight` before review
|
|
52
|
-
`ok:true`.
|
|
54
|
+
With the review gate enabled, `tower_preflight` before review reports `no-review`, and after a clean
|
|
55
|
+
review it should be `ok:true`. With the default (`review.requireReview:false`), no review blocker is
|
|
56
|
+
required. `tower_merge` refuses while blockers remain. `tower_teardown` removes merged/abandoned
|
|
53
57
|
worktrees and branches.
|
|
54
58
|
|
|
55
59
|
```
|
|
@@ -59,8 +63,9 @@ worktrees and branches.
|
|
|
59
63
|
## If something fails
|
|
60
64
|
|
|
61
65
|
Read the blocker code and use [the blocker reference](../reference/blockers.md). The most common cases:
|
|
62
|
-
`stale-base` (run `tower_rebase`), `no-review` (
|
|
63
|
-
`timeoutMs`), `tip-moved` (
|
|
66
|
+
`stale-base` (run `tower_rebase`), `no-review` (only with `review.requireReview:true`; spawn a
|
|
67
|
+
reviewer), `merge-hook-failed` (retry, or raise `timeoutMs`), `tip-moved` (only with the review gate;
|
|
68
|
+
the branch changed after review, review again).
|
|
64
69
|
|
|
65
70
|
Thrown tool failures carry a `[tower:<code>]` prefix; see [error codes](../reference/errors.md)
|
|
66
71
|
(e.g. `preset-missing` means restart DSH after installing the bundle, `not-initialized` means run
|
|
@@ -73,7 +78,7 @@ JSON file at `<git-common-dir>/dsh-tower/config.json` (usually `.git/dsh-tower/c
|
|
|
73
78
|
|
|
74
79
|
```json
|
|
75
80
|
{
|
|
76
|
-
"review": { "maxRoundsPerReviewer": 3 },
|
|
81
|
+
"review": { "requireReview": true, "maxRoundsPerReviewer": 3 },
|
|
77
82
|
"merge": { "timeoutMs": 1800000 },
|
|
78
83
|
"worktrees": { "root": "D:/tower-worktrees" }
|
|
79
84
|
}
|