dsh-tower 2.0.2 → 2.0.3

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 CHANGED
@@ -2,6 +2,23 @@
2
2
 
3
3
  > 自 2.0.0 起,每个版本按 **新增 / 变更 / 修复** 三类组织;更早的版本保留原始流水式记录。
4
4
 
5
+ ## 2.0.3(2026-10-18)
6
+
7
+ ### 新增
8
+
9
+ - **`review.requireReview` 全局开关**:默认 `false`(审查可选);设为 `true` 时合并门禁强制独立 clean
10
+ 审查(`no-review`/`not-clean`/`review-hold`/`review-not-approved`/`tip-moved`/
11
+ `review-mission-mismatch`)。`tower_review` 始终可提交并记录;全局开启时单 mission 仍可用
12
+ `reviewPolicy:"none"` + 理由做更窄的豁免。
13
+
14
+ ### 变更
15
+
16
+ - **应用场景文档补充具体举例**:`docs/guide/scenarios-and-philosophy.md` 与中文版新增 Tower 七类
17
+ 场景的“具体例子/为什么用 Tower”速查表,以及 Tower、Agent Teams、Ralph 循环、Workflow 编排、
18
+ 普通并行子代理和混合阶段各自的具体例子;同时说明独立审查默认可选、可全局强制,并更新 README、
19
+ FAQ、配置/安全参考页与中文对应页。
20
+ - **离线套件**:219 项(新增 `review.requireReview:false` 无 reviewer 合并用例)。
21
+
5
22
  ## 2.0.2(2026-10-18)
6
23
 
7
24
  ### 新增
package/README.en.md CHANGED
@@ -5,7 +5,7 @@
5
5
  [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](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 nothing reaches your base branch without an independent review and a hard merge gate.
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
 
@@ -15,7 +15,7 @@ The repository root **is** the DSH bundle: `package.json` declares `dsh.bundle.p
15
15
 
16
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.
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 must submit a `clean` / `merge` verdict; the merge gate re-checks scope, staleness, task completion, review history, and worktree ownership before a `--no-ff` merge.
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).
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.
@@ -35,7 +35,7 @@ Tower is a **delivery protocol for changes to a Git repository**, not the defaul
35
35
  - ordering matters (migrations, dependencies, branch freshness, scope reservations);
36
36
  - the repository is sensitive or release-bound, and you need a reviewed commit, test evidence, and an auditable merge;
37
37
  - work spans context compaction, restarts, or multiple days and must be recoverable from local state;
38
- - "done" means tasks + tests + independent review, not just a confident message in chat.
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
 
package/README.md CHANGED
@@ -5,7 +5,7 @@
5
5
  [![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](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
 
@@ -15,7 +15,7 @@ Tower 模式与 mission/审查工作流的灵感来自 Moonshot AI 的 **Kimi Co
15
15
 
16
16
  - **由人类掌握的 Tower 模式。** `/tower` 切换会话级模式:收窄工具面并注入 Tower 协议;`/tower on|off <指令>` 还能把指令作为下一步用户消息转发给模型。
17
17
  - **任务级隔离。** 每个 mission 使用独立分支和 Git worktree,worker 不会碰到你的主检出。
18
- - **审查门禁合并。** 审查者必须针对当前分支 tip 给出 `clean` / `merge` 结论;合并门禁重新校验 scope、分支新鲜度、任务完成度、审查记录与 worktree 归属,通过后才执行 `--no-ff` 合并。
18
+ - **审查门禁合并。** 审查者针对当前分支 tip 给出 `clean` / `merge` 结论;合并门禁重新校验 scope、分支新鲜度、任务完成度、审查记录与 worktree 归属,通过后才执行 `--no-ff` 合并。独立审查默认可选,设 `review.requireReview:true` 可全局强制(仍可随时提交 review)。
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 只能读。
@@ -35,7 +35,7 @@ Tower 是**面向 Git 仓库变更的交付协议**,不是所有多代理场
35
35
  - 有依赖顺序、需要分支新鲜度与 scope 约束的迁移;
36
36
  - 敏感仓库、发布绑定变更,或需要"被审查 commit + 测试证据 + 可审计合并"的工作;
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
 
package/docs/faq.md CHANGED
@@ -36,6 +36,11 @@ whose commit exists (`recoveredFromFailure`) and records it.
36
36
  Correct: the branch is already contained in the base. Call `tower_merge` to record the landed merge
37
37
  instead of rebasing.
38
38
 
39
+ **Can I require independent review?**
40
+ Yes. Set `review.requireReview:true` in the profile or repository config to enable the global review
41
+ 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.
43
+
39
44
  **Can a reviewer edit files?**
40
45
  No. Reviewers use the read-only `tower-reviewer` preset (no write/edit/pwsh); a branch changed after the
41
46
  reviewer spawned is rejected. Reviewers file `tower_finding` for issues outside the mission.
@@ -43,6 +43,11 @@ does `tower_merge` perform a `--no-ff` merge. The gate re-checks scope, base fre
43
43
  binding, worktree ownership, worker state, tests, and evidence. Separation of duties is the point:
44
44
  the agent that wrote the code is not the agent that approves it, and neither is the agent that merges.
45
45
 
46
+ Independent review is optional by default: `review.requireReview:true` enforces it (and then a complete
47
+ mission must carry a clean, merge-approved review from a reviewer bound to the branch tip). Set the flag
48
+ to `true` for sensitive repositories; `reviewPolicy:"none"` + a reason remains available as a per-mission
49
+ exemption when the global gate is on. Reviews can be submitted and recorded either way.
50
+
46
51
  ### 1.5 Evidence over assertion
47
52
 
48
53
  "Done" is a claim; a commit, a diff, a passing test receipt, and an independent review are evidence.
@@ -74,6 +79,18 @@ Git metadata, so it survives restarts and is visible to a human with ordinary Gi
74
79
 
75
80
  ## 2. Situations where Tower is a good fit
76
81
 
82
+ The table is the quick version; the subsections below explain each row.
83
+
84
+ | Situation | Concrete example | Why Tower |
85
+ |---|---|---|
86
+ | 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
+ | 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
+ | Investigation then change | A survey mission maps every caller of a deprecated crypto API; two build missions migrate and test | Survey cannot mutate; findings feed build missions |
89
+ | Sensitive or release-bound change | A payments service change or a public library release needing a reviewed commit and test evidence | Review binding, checks/runs, human-readable audit |
90
+ | Long-running work | A multi-day dependency upgrade interrupted by restarts and context resets | Durable mission/roster/review/worktree state |
91
+ | Hard integration boundary | Four services in one monorepo, each with an owner, then one release review | Parallel missions with a single merge gate |
92
+ | Checkable definition of done | A task list plus required tests plus an optional independent review verdict | Completion/review evidence is visible to another agent |
93
+
77
94
  ### 2.1 A feature that naturally splits into independent slices
78
95
 
79
96
  Example: add OAuth login, split into "token model", "callback route", "UI button", and "migration +
@@ -160,7 +177,7 @@ integration, and what "done" means.**
160
177
  | 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 |
161
178
  | 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 |
162
179
  | Integration authority | Tower only, after review + gate | Humans/teammates merge or edit manually | Usually the parent/worker applies results | Script applies results | Parent applies results |
163
- | Review / gate | Mandatory independent review + 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 |
180
+ | 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 |
164
181
  | 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 |
165
182
  | Human role | Owns the mode; can inspect evidence and release | Collaborator/coordinator | Author of the repeated objective | Author of the orchestration script | Delegator |
166
183
  | Best for | Feature delivery, migrations, release-bound changes | Design, research, cross-cutting collaboration | Iterative search/repair with fresh context | Large audits, batch analysis, deterministic pipelines | Quick exploration or independent subtasks |
@@ -218,6 +235,60 @@ Tower entry clears an active plan (or refuses entry under `mode.planModePolicy:"
218
235
  Tower session cannot use the goal/todo/team/workflow tools. Plan first, then execute; do not expect
219
236
  Tower to discover the plan for you.
220
237
 
238
+ ### 4.6 Review is optional by default
239
+
240
+ `review.requireReview:false` is the default, so a completed mission can merge without a reviewer for
241
+ low-risk repositories, scratch work, or human-supervised sessions. Set it to `true` to enforce the
242
+ independent review gate; the gate then re-checks `no-review`, `not-clean`, `review-hold`,
243
+ `review-not-approved`, `tip-moved`, and `review-mission-mismatch`. `tower_review` is always available
244
+ and records verdicts even when the gate is off. For one mission only, prefer `reviewPolicy:"none"` + a
245
+ reason while the global gate is on.
246
+
247
+ ### 4.6 Concrete examples by workflow
248
+
249
+ **Tower** — output is a repository change that must land through isolation and review:
250
+
251
+ - **OAuth login**: four missions (`token model`, `callback route`, `accept/decline API`, `UI`); the API depends on tokens and email.
252
+ - **Node 18 → 22 upgrade**: survey breaking API usages, then codemod, test updates, CI config, release notes as separate missions.
253
+ - **Deprecated crypto migration**: a read-only survey mission maps call sites; build missions replace them package by package.
254
+ - **Release hardening**: three missions for the change, migration guide, and release notes; close a `tower_batch` with required tests before tagging.
255
+ - **Monorepo service split**: one mission per package with disjoint scopes; a final review mission checks integration.
256
+
257
+ **Agent Teams** — output is a decision, design, or cross-cutting collaboration, not a single mergeable branch:
258
+
259
+ - Architecture review with a backend, frontend, and security teammate, each contributing findings to a shared board.
260
+ - Incident postmortem: one teammate reconstructs the timeline, another checks logs, a third drafts actions.
261
+ - Product requirements discovery: several perspectives converge on a spec; the human decides what to build.
262
+ - Cross-repository investigation where there is no single repo to isolate or merge.
263
+
264
+ **Ralph loop** — output is a better attempt at the *same* objective, with fresh context:
265
+
266
+ - A flaky test that needs several independent attempts to reproduce and fix.
267
+ - Performance optimization where each round tries a different hypothesis against an eval.
268
+ - "Find any working approach" exploration where the parent does not know the path.
269
+ - Repeated prompt/skill tuning until an eval threshold is met.
270
+
271
+ **Workflow orchestration** — output is a large, programmatic fan-out or pipeline:
272
+
273
+ - Audit 200 files for unsafe API usage and produce a structured report.
274
+ - Run a dependency upgrade matrix across many packages/versions in parallel.
275
+ - Multi-angle research or adversarial verification of a proposal.
276
+ - Generate/translate/test many independent artifacts and aggregate the results.
277
+
278
+ **Ordinary parallel subagents** — output is quick parallel read-mostly work or independent explorations:
279
+
280
+ - Read five candidate files in parallel and summarize each.
281
+ - Try three implementations of the same function and compare.
282
+ - Scan a repo for a risky pattern without changing it.
283
+ - Run independent document lookups before the parent writes the answer.
284
+
285
+ **Mixed phases (recommended)** — analyze with Workflow/Teams, then deliver with Tower:
286
+
287
+ 1. Workflow audits 200 files → structured findings.
288
+ 2. Agent Teams reviews the findings and decides the top six changes.
289
+ 3. Tower missions implement those six changes with review and merge.
290
+ 4. Ralph is used after merge only for a stubborn flaky test that does not need a new mission contract.
291
+
221
292
  ## 5. Worked scenarios
222
293
 
223
294
  ### Scenario A: four-slice feature
@@ -7,6 +7,11 @@ Tower's guarantees are **coordination guarantees**, not a sandbox. Understand wh
7
7
  - **Review binding.** `tower_review` records the branch tip it inspected; the gate rejects a moved tip
8
8
  (`tip-moved`) unless a clean conflict-free rebase waived it. A reviewer that modifies the branch after
9
9
  spawning is rejected (`reviewer must not modify the mission branch`).
10
+ - **Review is optional by default, enforceable by config.** `review.requireReview:false` is the
11
+ default; set it to `true` to enforce the independent-review gate. Mission-level
12
+ `reviewPolicy:"none"` + reason is the narrower exemption when the global gate is on. With the gate
13
+ off, separation of duties is not enforced by the plugin; use it only for trusted or human-supervised
14
+ repositories.
10
15
  - **Role enforcement.** The caller is resolved against the roster. Worker mission updates are limited to
11
16
  task/blocker/note; `completed`, `abandoned`, scope widening and blocker clearing are tower-only, and
12
17
  completion (with its unread-inbox/commit gates) must go through `tower_complete`. Tower-only tools reject
@@ -54,6 +54,7 @@ violates the declared schema (for example `merge.timeoutMs` below 1000) fail wit
54
54
  | `mode.denyTools` | goal/todo/team/workflow/subagent tools | Tools refused while the mode is active (12 defaults). |
55
55
  | `mode.storePath` | `$DSH_HOME/tower-mode` | Directory for `modes.json`. |
56
56
  | `mode.maxEntries` | `200` | Maximum persisted mode entries (1–2000). |
57
+ | `review.requireReview` | `false` | Enforce an independent clean review before merge. Default `false` (review optional); set `true` to require `no-review`/`not-clean`/`review-hold`/`review-not-approved`/`tip-moved`/`review-mission-mismatch` checks. `tower_review` remains available either way. |
57
58
  | `review.maxRoundsPerReviewer` | `5` | Review-round cap per reviewer per branch. |
58
59
  | `merge.timeoutMs` | `900000` (15 min) | Default `tower_merge` timeout, including hooks. A per-call `timeoutMs` wins. |
59
60
  | `merge.maxBufferBytes` | `67108864` (64 MB) | Merge output buffer. |
package/docs/zh/faq.md CHANGED
@@ -31,6 +31,11 @@
31
31
  **`tower_rebase` 返回 `alreadyMerged` 且什么都没改。**
32
32
  正确:分支已经包含在基线中。此时调用 `tower_merge` 记录已落地的合并,而不是 rebase。
33
33
 
34
+ **可以要求强制独立审查吗?**
35
+ 可以。在 profile 或仓库配置中设 `review.requireReview:true` 可开启全局审查门禁(默认 `false`,
36
+ 即审查可选)。开启后可用 mission 级 `reviewPolicy:"none"` + 理由做更窄的豁免。`tower_review`
37
+ 始终可用并记录结论。
38
+
34
39
  **reviewer 能修改文件吗?**
35
40
  不能。reviewer 使用只读的 `tower-reviewer` preset(没有 write/edit/pwsh);reviewer spawn 之后分支
36
41
  被改动,审查会被拒绝。mission 之外的问题用 `tower_finding` 记录,不要直接改文件。
@@ -26,6 +26,8 @@ mission 不是聊天线程或任务卡,而是绑定到分支与 worktree 的
26
26
 
27
27
  worker 永远不合并。reviewer 审查特定分支 tip;控制塔运行 preflight;只有之后 `tower_merge` 才执行 `--no-ff` 合并。门禁重新检查 scope、base 新鲜度、任务、审查绑定、worktree 归属、worker 状态、测试与证据。职责分离是重点:写代码的 agent 不批准,批准的 agent 也不合并。
28
28
 
29
+ 独立审查默认可选:设 `review.requireReview:true` 才会强制(此时已完成 mission 必须带有绑定 tip 的 clean/merge 审查)。对敏感仓库建议开启;全局开启时仍可用 `reviewPolicy:"none"` + 理由做单个 mission 豁免。无论开关如何,都可以提交并记录 review。
30
+
29
31
  ### 1.5 证据优先于断言
30
32
 
31
33
  "完成了"是声明;commit、diff、通过的测试回执、独立审查才是证据。Tower 全部记录:`tower_doctor` 检查环境,`tower_test` 记录发现,`tower_complete` 记录 checks,`tower_review` 把结论绑定到提交,`tower_batch` 只有在有限 mission 集合的必需证据齐全时才允许收口。
@@ -44,6 +46,18 @@ Tower 是 Host 插件,只使用本地 Git、本地文件和 DSH subagent 服
44
46
 
45
47
  ## 2. Tower 适合的场景
46
48
 
49
+ 先看速查表;下文逐项解释。
50
+
51
+ | 场景 | 具体例子 | 为什么用 Tower |
52
+ |---|---|---|
53
+ | 可拆成独立切片的特性 | 加 OAuth:`token 模型` → `callback 路由` → `UI 按钮` + 迁移,四个 scope 基本独立的 mission | 写入隔离、scope 预留、最终统一审查/合并 |
54
+ | 有顺序的迁移/重构 | monorepo 重命名 `oldApi`:codemod → import 清理 → 快照 → 文档,每步依赖前一步合并 | `deps`、分支新鲜度、合并串行 |
55
+ | 先调查再修改 | survey mission 映射已弃用 crypto API 的所有调用者;两个 build mission 迁移与补测试 | survey 不能改文件;findings 喂给 build |
56
+ | 敏感或发布绑定变更 | 支付服务改动或公共库发布,需要被审查 commit 与测试证据 | 审查绑定、checks/testRuns、人类可审计 |
57
+ | 长期工作 | 多日依赖升级,期间重启、换会话、上下文重置 | mission/roster/review/worktree 持久 |
58
+ | 硬集成边界 | monorepo 四个服务各有 owner,最后统一发布审查 | 多 mission 并行,单一合并门禁 |
59
+ | 可检查的完成定义 | 任务清单 + 必需测试 + 可选独立审查结论 | 另一个 agent 能检查证据 |
60
+
47
61
  ### 2.1 能自然拆成独立切片的特性
48
62
 
49
63
  例:OAuth 登录拆成"token 模型"、"callback 路由"、"UI 按钮"、"迁移 + 测试"。切片大多改不同文件,可以并行,最后需要集成审查。Tower 的 scope 预留与重叠自动依赖可以避免碰撞。
@@ -109,7 +123,7 @@ Tower 是 Host 插件,只使用本地 Git、本地文件和 DSH subagent 服
109
123
  | 隔离 | 每 mission 独立 worktree/分支;单写入者 | 共享工作区;靠任务归属协调 | 每轮新 child;无内置分支/合并契约 | 每步 child;无 Git 隔离 | 子会话;可能共享工作区 |
110
124
  | 持久状态 | Git 元数据 + JSON state + 活动日志 + 看板 | Team 任务板 + 会话 | 很少;每轮从零开始 | 运行记录/结果;不是合并账本 | 会话/子代理记录 |
111
125
  | 集成权限 | 仅控制塔,且需审查 + 门禁 | 人类/teammate 手动合并或编辑 | 通常由父 agent/worker 应用结果 | 脚本应用结果 | 父 agent 应用结果 |
112
- | 审查/门禁 | 强制独立审查 + preflight/merge 门禁 | 审查是协作约定,不是硬门禁 | 无内置审查门禁 | 无内置审查门禁 | 无内置审查门禁 |
126
+ | 审查/门禁 | 可选独立审查(`review.requireReview` 开启)+ preflight/merge 门禁 | 审查是协作约定,不是硬门禁 | 无内置审查门禁 | 无内置审查门禁 | 无内置审查门禁 |
113
127
  | 并行度 | 多 mission、互斥 scope、合并串行 | 多 teammate、共享任务板 | 顺序轮次(或外部扇出) | 高扇出,由脚本控制 | 高扇出 |
114
128
  | 人的角色 | 拥有模式;可检查证据与发布 | 协作者/协调者 | 重复目标的作者 | 编排脚本作者 | 委派者 |
115
129
  | 最适合 | 特性交付、迁移、发布绑定变更 | 设计、研究、横切协作 | 迭代搜索/修复,需要新鲜上下文 | 大规模审计、批量分析、确定性流水线 | 快速探索或独立子任务 |
@@ -143,6 +157,59 @@ Tower 是**仓库交付协议**,mission 数量少,不是高扇出数据平
143
157
 
144
158
  Plan mode 决定做什么;Tower 把已决定的计划执行到仓库。进入 Tower 会清除活跃 plan(`mode.planModePolicy:"refuse"` 时拒绝进入),且 Tower 会话不能使用 goal/todo/team/workflow 工具。先规划,再执行;不要指望 Tower 替你发现计划。
145
159
 
160
+ ### 4.6 各工作流的具体例子
161
+
162
+ **Tower** —— 输出是必须经过隔离与审查才能落地的仓库变更:
163
+
164
+ - **OAuth 登录**:四个 mission(`token 模型`、`callback 路由`、`接受/拒绝 API`、`UI`);API 依赖 token 与邮件。
165
+ - **Node 18 → 22 升级**:先 survey 破坏性 API,再拆 codemod、测试更新、CI 配置、release notes 为独立 mission。
166
+ - **废弃 crypto 迁移**:只读 survey 映射调用点;build mission 按包替换。
167
+ - **发布硬化**:变更、迁移指南、release notes 三个 mission;打 tag 前用 `tower_batch` 收口必需测试。
168
+ - **monorepo 服务拆分**:每个包一个 scope 不重叠的 mission;最后一个审查 mission 检查集成。
169
+
170
+ **Agent Teams** —— 输出是决策、设计或横切协作,而不是单个可合并分支:
171
+
172
+ - 后端、前端、安全三个 teammate 做架构评审,把发现汇总到共享任务板。
173
+ - 事故复盘:一人重建时间线,一人查日志,一人起草行动项。
174
+ - 产品需求发现:多视角收敛成规格,由人类决定做什么。
175
+ - 没有单一仓库可隔离/合并的跨仓库调查。
176
+
177
+ **Ralph 循环** —— 输出是对*同一目标*的新鲜尝试:
178
+
179
+ - flaky 测试需要多轮独立复现与修复。
180
+ - 性能优化每轮换一个假设,对 eval 反复尝试。
181
+ - 父 agent 不知道路径的"找到任意可行方案"探索。
182
+ - 反复调 prompt/skill 直到 eval 阈值达标。
183
+
184
+ **Workflow 编排** —— 输出是大规模程序化扇出或流水线:
185
+
186
+ - 审计 200 个文件的不安全 API 用法并生成结构化报告。
187
+ - 对多包/多版本并行跑依赖升级矩阵。
188
+ - 多角度研究或对提案做对抗性验证。
189
+ - 批量生成/翻译/测试独立产物并聚合结果。
190
+
191
+ **普通并行子代理** —— 输出是快速的只读并行或独立探索:
192
+
193
+ - 并行读五个候选文件并分别总结。
194
+ - 同一函数写三种实现并比较。
195
+ - 扫描仓库中的风险模式但不修改。
196
+ - 父 agent 写答案前做独立的文档查找。
197
+
198
+ **混合阶段(推荐)** —— 用 Workflow/Teams 分析,用 Tower 交付:
199
+
200
+ 1. Workflow 审计 200 个文件 → 结构化 findings。
201
+ 2. Agent Teams 评审 findings,决定前六个改动。
202
+ 3. Tower mission 实现这六个改动,经审查与合并落地。
203
+ 4. 合并后仍有一个顽固 flaky 测试、且不需要新 mission 契约时,再用 Ralph。
204
+
205
+ ### 4.7 审查默认可选
206
+
207
+ `review.requireReview:false` 是默认值,因此低风险仓库、临时工作或人类逐轮监督的会话可以在没有
208
+ reviewer 时合并已完成 mission。设为 `true` 才启用强制独立审查门禁;此时检查 `no-review`、
209
+ `not-clean`、`review-hold`、`review-not-approved`、`tip-moved`、`review-mission-mismatch`。
210
+ `tower_review` 始终可用并记录结论。只豁免单个 mission 时,在全局开启的前提下用
211
+ `reviewPolicy:"none"` + 理由。
212
+
146
213
  ## 5. 具体场景示例
147
214
 
148
215
  ### 场景 A:四切片特性
@@ -9,6 +9,9 @@ Tower 提供的是**协作层面的保证**,不是沙箱。需要理解哪些
9
9
  - **审查绑定。** `tower_review` 会记录它检查的分支 tip;tip 变化后门禁会拒绝(`tip-moved`),除非
10
10
  一次干净且无冲突的 rebase 给予了豁免。reviewer 在 spawn 之后修改分支会被拒绝
11
11
  (`reviewer must not modify the mission branch`)。
12
+ - **审查默认可选,可配置强制。** `review.requireReview:false` 是默认值;设为 `true` 才启用独立审查
13
+ 门禁。全局开启时,mission 级 `reviewPolicy:"none"` + 理由是更窄的豁免。关闭门禁时插件不强制职责
14
+ 分离;只应用于可信仓库或有人类监督的会话。
12
15
  - **角色强制。** 调用方会根据 roster 解析。worker 的 mission 更新仅限于 task/blocker/note;
13
16
  `completed`、`abandoned`、扩大 scope 与清除 blocker 仅限控制塔,完成(连同未读消息/提交门禁)必须
14
17
  走 `tower_complete`。仅限控制塔的工具会以 `[tower:not-authorized]` 拒绝 roster 中的 worker。
@@ -53,6 +53,7 @@ merge、worktree 与 spawn 策略。它使用与 profile 配置相同的 JSON
53
53
  | `mode.denyTools` | goal/todo/team/workflow/subagent 工具(默认 12 个) | 模式激活期间被拒绝的工具。 |
54
54
  | `mode.storePath` | `$DSH_HOME/tower-mode` | `modes.json` 所在目录。 |
55
55
  | `mode.maxEntries` | `200` | 最多持久化的模式条目数(1–2000)。 |
56
+ | `review.requireReview` | `false` | 合并前是否强制独立 clean 审查。默认 `false`(审查可选);设为 `true` 则要求 `no-review`/`not-clean`/`review-hold`/`review-not-approved`/`tip-moved`/`review-mission-mismatch` 全部通过。`tower_review` 始终可用。 |
56
57
  | `review.maxRoundsPerReviewer` | `5` | 每个 reviewer 对每条分支的审查轮数上限。 |
57
58
  | `merge.timeoutMs` | `900000`(15 分钟) | `tower_merge` 默认超时,包含钩子;单次调用的 `timeoutMs` 优先。 |
58
59
  | `merge.maxBufferBytes` | `67108864`(64 MB) | 合并输出缓冲区。 |
package/lib/config.js CHANGED
@@ -88,6 +88,9 @@ export const Config = Schema.object({
88
88
  .default({})
89
89
  .description('Tower-mode behavior and persistence.'),
90
90
  review: Schema.object({
91
+ requireReview: Schema.boolean()
92
+ .default(false)
93
+ .description('Require an independent clean review before merge. Default false: review is optional; set true to enforce the review gate globally.'),
91
94
  maxRoundsPerReviewer: Schema.natural().min(1).default(5).description('Review-round cap per reviewer per mission branch.'),
92
95
  })
93
96
  .default({})
package/lib/tower.js CHANGED
@@ -2103,16 +2103,18 @@ export class Tower {
2103
2103
  const branch = worktree ? worktree.branch : null
2104
2104
  const reviews = branch ? (state.reviews ?? []).filter((review) => review.branch === branch) : []
2105
2105
  const latest = reviews.length > 0 ? reviews.reduce((a, b) => (a.round >= b.round ? a : b)) : null
2106
+ const requireReview = this.config.review?.requireReview !== false
2106
2107
  const exempt =
2107
- mission.reviewPolicy === 'none' &&
2108
- this.config.gates.allowReviewExemption === true &&
2109
- String(mission.reviewExemptionReason ?? '').trim().length > 0
2110
- if (mission.reviewPolicy === 'none' && this.config.gates.allowReviewExemption !== true) {
2108
+ !requireReview ||
2109
+ (mission.reviewPolicy === 'none' &&
2110
+ this.config.gates.allowReviewExemption === true &&
2111
+ String(mission.reviewExemptionReason ?? '').trim().length > 0)
2112
+ if (requireReview && mission.reviewPolicy === 'none' && this.config.gates.allowReviewExemption !== true) {
2111
2113
  push('review-exemption-invalid', `mission ${mission.id} requests no review but gates.allowReviewExemption is disabled`)
2112
2114
  }
2113
- if (!exempt && !latest) {
2114
- push('no-review', `branch ${branch ?? '(none)'} has no review; assign a reviewer first`)
2115
- } else if (!exempt) {
2115
+ if (requireReview && !exempt && !latest) {
2116
+ push('no-review', `branch ${branch ?? '(none)'} has no review; assign a reviewer first (or set review.requireReview:false)`)
2117
+ } else if (requireReview && !exempt) {
2116
2118
  const waived = this.rebaseWaived(mission, latest)
2117
2119
  if (latest.missionId !== mission.id) {
2118
2120
  push('review-mission-mismatch', `latest review belongs to mission ${latest.missionId}`)
@@ -2252,9 +2254,10 @@ export class Tower {
2252
2254
  const branch = mission.worktree.branch
2253
2255
  const reviews = (state.reviews ?? []).filter((review) => review.branch === branch)
2254
2256
  const exempt =
2255
- mission.reviewPolicy === 'none' &&
2256
- this.config.gates.allowReviewExemption === true &&
2257
- String(mission.reviewExemptionReason ?? '').trim().length > 0
2257
+ this.config.review?.requireReview === false ||
2258
+ (mission.reviewPolicy === 'none' &&
2259
+ this.config.gates.allowReviewExemption === true &&
2260
+ String(mission.reviewExemptionReason ?? '').trim().length > 0)
2258
2261
  if (reviews.length === 0 && !exempt) return null
2259
2262
  const latest = reviews.length > 0 ? reviews.reduce((a, b) => (a.round >= b.round ? a : b)) : null
2260
2263
  if (latest && !exempt && (latest.status !== 'clean' || latest.mergeVerdict !== 'merge')) return null
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-tower",
3
- "version": "2.0.2",
3
+ "version": "2.0.3",
4
4
  "type": "module",
5
5
  "description": "DSH-native Tower: mission planning, worktree isolation, review-gated merges, and a human-owned Tower mode.",
6
6
  "license": "MIT",