dsh-tower 2.0.3 → 2.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/README.en.md +19 -13
  3. package/README.md +19 -13
  4. package/SECURITY.md +4 -1
  5. package/docs/README.md +30 -0
  6. package/docs/architecture/overview.md +3 -2
  7. package/docs/examples/first-mission.md +2 -1
  8. package/docs/faq.md +11 -7
  9. package/docs/guide/install-upgrade-migration.md +14 -5
  10. package/docs/guide/quickstart.md +12 -7
  11. package/docs/guide/scenarios-and-philosophy.md +86 -69
  12. package/docs/operations/security.md +18 -12
  13. package/docs/reference/blockers.md +11 -10
  14. package/docs/reference/config.md +7 -6
  15. package/docs/reference/errors.md +7 -1
  16. package/docs/reference/events.md +7 -4
  17. package/docs/reference/testing.md +2 -1
  18. package/docs/reference/tools.md +7 -6
  19. package/docs/zh/README.md +1 -1
  20. package/docs/zh/faq.md +9 -6
  21. package/docs/zh/guide/install-upgrade-migration.md +11 -4
  22. package/docs/zh/guide/quickstart.md +13 -8
  23. package/docs/zh/guide/scenarios-and-philosophy.md +55 -50
  24. package/docs/zh/operations/security.md +13 -6
  25. package/docs/zh/reference/blockers.md +10 -10
  26. package/docs/zh/reference/config.md +7 -6
  27. package/docs/zh/reference/errors.md +2 -1
  28. package/docs/zh/reference/events.md +6 -3
  29. package/docs/zh/reference/testing.md +3 -2
  30. package/docs/zh/reference/tools.md +7 -6
  31. package/index.js +26 -17
  32. package/lib/config.js +100 -6
  33. package/lib/doctor.js +11 -5
  34. package/lib/errors.js +14 -2
  35. package/lib/git.js +36 -2
  36. package/lib/modeStore.js +54 -20
  37. package/lib/store.js +65 -10
  38. package/lib/tests.js +35 -1
  39. package/lib/tools.js +257 -47
  40. package/lib/tower.js +268 -45
  41. package/lib/workspaceLock.js +44 -20
  42. package/package.json +3 -2
  43. package/scripts/check-docs.mjs +35 -0
  44. package/skills/tower-recovery.md +7 -5
  45. package/ui-bundle/README.md +111 -0
  46. package/ui-bundle/client.js +1980 -0
  47. package/ui-bundle/cordis.patch.yml +3 -0
  48. package/ui-bundle/icon.svg +6 -0
  49. package/ui-bundle/index.js +2 -0
  50. package/ui-bundle/locale/en.json +6 -0
  51. package/ui-bundle/locale/zh.json +6 -0
  52. package/ui-bundle/package.json +35 -0
package/CHANGELOG.md CHANGED
@@ -2,6 +2,46 @@
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
+
5
45
  ## 2.0.3(2026-10-18)
6
46
 
7
47
  ### 新增
package/README.en.md CHANGED
@@ -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
- - **Human-owned 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.
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.** A reviewer bound to the current branch tip can submit a `clean` / `merge` verdict; 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; set `review.requireReview:true` to enforce it globally (or use `reviewPolicy:"none"` + reason to exempt a single mission when it is on).
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,7 +33,7 @@ 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 a reviewed commit, test evidence, and an auditable merge;
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
38
  - "done" means tasks + tests (and optionally an independent review), not just a confident message in chat.
39
39
 
@@ -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; ok:true after it
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 and one reviewer round. 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).
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 `false` in code; the bundled `cordis.patch.yml` enables it (`true`) so the model may enter/leave when the user intent or task state warrants it, always stating a reason. The bundled patch also enables `mode.workspaceLock` (single-active tower), `send.interruptDefault`, `init.autoGitInit`, and sets `spawn.staleMs` to 15s.
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 (26 core)
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` exists only when `allowAgentControl: true`; `tower_reload` is registered while `dev.hotReload` is on (default true) and returns `reload-unavailable` without an HMR service (so up to 28 tools). Mission-scoped tools also accept `id` as an alias for `missionId`; snake/camel spellings such as `task_done`/`taskDone` are both accepted.
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.** 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.
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` is `false`; set it to `true` and restart.
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 human-owned activation, 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.
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
@@ -13,9 +13,9 @@ Tower 模式与 mission/审查工作流的灵感来自 Moonshot AI 的 **Kimi Co
13
13
 
14
14
  ## 特性
15
15
 
16
- - **由人类掌握的 Tower 模式。** `/tower` 切换会话级模式:收窄工具面并注入 Tower 协议;`/tower on|off <指令>` 还能把指令作为下一步用户消息转发给模型。
16
+ - **可配置的 Tower 模式。** `/tower` 切换会话级模式:收窄工具面并注入 Tower 协议;`/tower on|off <指令>` 还能把指令作为下一步用户消息转发给模型。默认也允许 Agent 通过 `tower_control` 带理由进出;设 `mode.allowAgentControl:false` 可改为仅人类控制。
17
17
  - **任务级隔离。** 每个 mission 使用独立分支和 Git worktree,worker 不会碰到你的主检出。
18
- - **审查门禁合并。** 审查者针对当前分支 tip 给出 `clean` / `merge` 结论;合并门禁重新校验 scope、分支新鲜度、任务完成度、审查记录与 worktree 归属,通过后才执行 `--no-ff` 合并。独立审查默认可选,设 `review.requireReview:true` 可全局强制(仍可随时提交 review)。
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,7 +33,7 @@ Tower 是**面向 Git 仓库变更的交付协议**,不是所有多代理场
33
33
 
34
34
  - 一个特性/重构能拆成 2–8 个 scope 清晰、可独立审查的 mission;
35
35
  - 有依赖顺序、需要分支新鲜度与 scope 约束的迁移;
36
- - 敏感仓库、发布绑定变更,或需要"被审查 commit + 测试证据 + 可审计合并"的工作;
36
+ - 敏感仓库、发布绑定变更,或需要"可审计合并 + 测试证据"(需要时开启独立审查)的工作;
37
37
  - 跨上下文压缩、重启、多天协作,需要从本地状态恢复的工作;
38
38
  - 需要把"完成"定义成任务 + 测试(可选独立审查),而不是聊天里的一句"好了"。
39
39
 
@@ -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 # 审查前 预期 no-review;审查后应为 ok:true
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 + 一轮 reviewer 即可完成。完整可复制示例见 [docs/examples/first-mission.md](docs/examples/first-mission.md),逐工具参数见 [docs/reference/tools.md](docs/reference/tools.md)。
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` 默认 `false`;随包 `cordis.patch.yml` 设为 `true`:模型可在用户意图/任务状态明确时自行进出,但必须给出理由;设为 `false` 时只有人类能切换。随包 patch 还默认开启 `mode.workspaceLock`(单活塔)、`send.interruptDefault`、`init.autoGitInit`,并把 `spawn.staleMs` 设为 15s。
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
- ## 工具(26 个核心)
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` 仅在 `allowAgentControl: true` 时注册;`tower_reload` 在 `dev.hotReload`(默认 true)时注册,无 HMR 服务调用会返回 `reload-unavailable`(因此最多 28 个工具)。mission 级工具同时接受 `id` 作为 `missionId` 的别名;`task_done`/`taskDone` 等 snake/camel 写法均可。
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
- - **审查绑定提交。** 审查后分支 tip 变化会报 `tip-moved`,必须重新审查;reviewer 使用只读 preset,若在审查期间改动分支,提交审查会被拒绝。
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`。** 配置 `allowAgentControl` 为 `false`;改为 `true` 并重启。
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 模式的整体概念——由人类开启的模式、每个 mission 独立 Git worktree、审查门禁合并协议——灵感来自 Kimi Code 的实验性 Tower 模式([官网](https://www.kimi.com/code)、[源码](https://github.com/MoonshotAI/kimi-code))。本项目在 DeepSeek Harness 的服务之上重新实现这些想法,不包含 Kimi Code 源码,也与 Moonshot AI 无隶属关系。
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 version (`1.x`). Older pre-release snapshots are not maintained.
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. A review must exist, belong to this mission, be clean, approve merge, and be bound to the tip
50
- (unless a clean rebase waived it). No worker may be running.
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
- Spawn the reviewer:
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 a reviewed, integrated change to one Git repository. Use ordinary
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 review the
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 is expected: a completed mission awaits review. Spawn a reviewer; after a clean review the gate
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 off. Set it to `true` in the profile patch and restart DSH.
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
@@ -39,7 +42,8 @@ instead of rebasing.
39
42
  **Can I require independent review?**
40
43
  Yes. Set `review.requireReview:true` in the profile or repository config to enable the global review
41
44
  gate (default is `false`, review optional). When enabled, mission-level `reviewPolicy:"none"` + a
42
- reason is the narrower exemption. `tower_review` works and records verdicts either way.
45
+ reason + `gates.allowReviewExemption:true` is the narrower exemption. `tower_review` works and records
46
+ verdicts either way.
43
47
 
44
48
  **Can a reviewer edit files?**
45
49
  No. Reviewers use the read-only `tower-reviewer` preset (no write/edit/pwsh); a branch changed after the
@@ -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
- - **1.x → 2.0 (unreleased)**: no state migration is needed (`schemaVersion` stays 1; new fields are
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 by default. Workers can no
36
- longer complete/abandon/scope a mission directly — use `tower_complete`. New tools: `tower_interrupt`,
37
- and `tower_reload` when HMR is available. Restart DSH once after upgrading; see
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
@@ -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. Review
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`. A `clean` + `merge` verdict is required to merge.
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 is expected to report `no-review`; after a clean review it should be
52
- `ok:true`. `tower_merge` refuses while blockers remain. `tower_teardown` removes merged/abandoned
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` (spawn a reviewer), `merge-hook-failed` (retry, or raise
63
- `timeoutMs`), `tip-moved` (the branch changed after review; review again).
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
  }