pi-claude-supervisor 0.4.1 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -1
- package/README.cn.md +33 -3
- package/README.md +44 -7
- package/docs/architecture.md +57 -5
- package/docs/engineering-plan.md +117 -3
- package/docs/recovery-review.md +24 -0
- package/docs/stability-matrix-2.1.270.md +32 -0
- package/docs/testing.md +80 -6
- package/package.json +1 -1
- package/src/acceptance.ts +84 -0
- package/src/cwd-lease.ts +95 -6
- package/src/decision-session-store.ts +356 -38
- package/src/decision-worker.ts +85 -10
- package/src/index.ts +191 -82
- package/src/reviewer.ts +205 -0
- package/src/supervisor.ts +241 -47
- package/src/types.ts +60 -0
- package/src/verifier.ts +102 -10
- package/src/worker/process-adapter.ts +103 -34
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,32 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented here.
|
|
4
4
|
|
|
5
|
+
## [0.5.1](https://github.com/btnalit/pi-claude-supervisor/compare/v0.5.0...v0.5.1) (2026-09-14)
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* harden single-worker recovery lifecycle ([14c01ec](https://github.com/btnalit/pi-claude-supervisor/commit/14c01ec610b1210eda1ea2d60269fad25b8b3575))
|
|
11
|
+
|
|
12
|
+
## [0.5.0](https://github.com/btnalit/pi-claude-supervisor/compare/v0.4.1...v0.5.0) (2026-09-14)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
### Features
|
|
16
|
+
|
|
17
|
+
* add acceptance review repair loop ([fe29c78](https://github.com/btnalit/pi-claude-supervisor/commit/fe29c78a228494768aa52b03ee1bf1545b079119))
|
|
18
|
+
|
|
19
|
+
## [Unreleased]
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- Structured task specifications with Goal, scope, constraints, forbidden actions and multiple argv-based acceptance checks.
|
|
24
|
+
- Independent read-only Reviewer results with bounded findings and automatic repair rounds.
|
|
25
|
+
- JSONL malformed-record handling and duplicate result/permission suppression fixtures.
|
|
26
|
+
- Active JSONL request shutdown coverage and deterministic acceptance/review tests.
|
|
27
|
+
- Durable Decision Worker recovery claims with stale-owner reconciliation and explicit fail-closed takeover.
|
|
28
|
+
- Identity-bound tmux handoff cleanup and recovery/lease lifecycle coverage.
|
|
29
|
+
- Claude Code 2.1.270 bounded stability matrix evidence in `docs/stability-matrix-2.1.270.md`.
|
|
30
|
+
|
|
5
31
|
## [0.4.1](https://github.com/btnalit/pi-claude-supervisor/compare/v0.4.0...v0.4.1) (2026-09-14)
|
|
6
32
|
|
|
7
33
|
|
|
@@ -69,7 +95,7 @@ All notable changes to this project will be documented here.
|
|
|
69
95
|
- Historical Claude CLI 2.1.268 permission allow/deny and SIGTERM/SIGINT transport spike evidence; current release validation uses Claude CLI 2.1.270.
|
|
70
96
|
- Event-driven JSONL `control_request`/`result`/exit events, permission responses, persistent Pi Decision Worker automation, bounded duplicate/turn handling, and outbound human-intervention webhooks.
|
|
71
97
|
- Long-task defaults are now 100 automatic turns, 4 hours wall time and 20 minutes without output; Decision Worker API failures alert human operators directly instead of attempting an LLM fallback.
|
|
72
|
-
- Automatic Decision Worker sessions now persist as Pi JSONL with a 0600 task registry. Unclean Pi restarts expose explicit `/supervise recover <task-id>` recovery; Claude work is not silently duplicated.
|
|
98
|
+
- Automatic Decision Worker sessions now persist as Pi JSONL with a 0600 task registry. Unclean Pi restarts expose explicit `/supervise recover [--takeover] <task-id>` recovery; Claude work is not silently duplicated.
|
|
73
99
|
- Local tests and package-content checks.
|
|
74
100
|
|
|
75
101
|
### Limitations
|
package/README.cn.md
CHANGED
|
@@ -51,9 +51,10 @@ Claude CLI `2.1.270` 运行,跨版本兼容性不在本轮范围内。
|
|
|
51
51
|
```text
|
|
52
52
|
/supervise capabilities
|
|
53
53
|
/supervise start inspect the current repository
|
|
54
|
+
/supervise start --spec ./task.json
|
|
54
55
|
/supervise poll
|
|
55
56
|
/supervise sessions
|
|
56
|
-
/supervise recover <task-id>
|
|
57
|
+
/supervise recover [--takeover] <task-id>
|
|
57
58
|
/supervise stop human requested stop
|
|
58
59
|
/supervise verify
|
|
59
60
|
/supervise approve <task-id> allow|deny [request-id]
|
|
@@ -61,6 +62,21 @@ Claude CLI `2.1.270` 运行,跨版本兼容性不在本轮范围内。
|
|
|
61
62
|
/supervise resume-auto <task-id>
|
|
62
63
|
```
|
|
63
64
|
|
|
65
|
+
`--spec` 接受 JSON 文件;验收命令始终使用 argv 执行,不经过 shell。例如:
|
|
66
|
+
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"goal": "实现请求的修改",
|
|
70
|
+
"scope": ["src/"],
|
|
71
|
+
"constraints": ["保持公共 API 兼容"],
|
|
72
|
+
"forbidden": ["不要发布构建产物"],
|
|
73
|
+
"acceptance": [
|
|
74
|
+
{ "id": "tests", "name": "tests", "command": "npm", "args": ["test"], "required": true }
|
|
75
|
+
],
|
|
76
|
+
"maxRepairRounds": 3
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
64
80
|
人工升级通知的 generic JSON 格式为:
|
|
65
81
|
|
|
66
82
|
```json
|
|
@@ -78,12 +94,21 @@ Claude CLI `2.1.270` 运行,跨版本兼容性不在本轮范围内。
|
|
|
78
94
|
|
|
79
95
|
当前 webhook 是出站通知,不直接接受批准命令;批准或接管仍通过 Pi。
|
|
80
96
|
自动模式会将 Decision Worker 会话持久化到状态目录。Pi 非正常重启后,`/supervise sessions`
|
|
81
|
-
会显示 `recoverable` 任务;显式执行 `/supervise recover <task-id>` 会恢复 Decision Worker 上下文并
|
|
82
|
-
重新启动 Claude Worker
|
|
97
|
+
会显示 `recoverable` 任务;显式执行 `/supervise recover [--takeover] <task-id>` 会恢复 Decision Worker 上下文并
|
|
98
|
+
重新启动 Claude Worker,不会静默恢复或重复执行任务。旧 Pi 进程已退出且租约确认旧 Worker
|
|
99
|
+
进程组已消失且 cgroup 仍是真实、可读取的空边界时,才可显式添加 `--takeover`;缺失、仍存活或无法确认的 Worker 会被拒绝。持久 tmux
|
|
100
|
+
Worker 应使用 `adopt-tmux`,而不是 takeover。
|
|
83
101
|
自动模式下,Decision Worker 可以安全拒绝 `AskUserQuestion`,让 Claude 将问题转成普通文本,
|
|
84
102
|
再根据任务和仓库证据自动回答;无法确定时才升级人工。如需微信内闭环,需要另建带签名验证、
|
|
85
103
|
一次性 action token 和重放保护的入站 callback 服务。
|
|
86
104
|
|
|
105
|
+
`v0.5.0` 已完成并发布“多命令验收—独立只读 Reviewer—结构化修复轮次—再次验收”闭环。
|
|
106
|
+
任务可通过 API 或 JSON spec 提供 `goal`、`scope`、`constraints`、`forbidden` 和多个
|
|
107
|
+
`acceptance` 命令;旧的纯文本任务继续使用默认 `git diff --check`。Reviewer 只能使用
|
|
108
|
+
`read`、`grep`、`find`、`ls`,不会修改工作树或批准权限。短期剩余门禁是固定 Claude Code
|
|
109
|
+
`2.1.270` 的重复稳定性统计和 recovery 测试;协同多 Worker 属于后续独立开发阶段,
|
|
110
|
+
暂不把多版本兼容、sandbox、低权限和网络隔离作为本阶段门禁。
|
|
111
|
+
|
|
87
112
|
### tmux/PTY 交互模式
|
|
88
113
|
|
|
89
114
|
如果希望在可见的 Claude Code 终端中工作,可显式启用 tmux transport:
|
|
@@ -128,6 +153,11 @@ PTY 屏幕文字不是 Claude JSONL。权限/信任对话框和无法确定的 T
|
|
|
128
153
|
/supervise send <task-id> continue after checking the test failure
|
|
129
154
|
```
|
|
130
155
|
|
|
156
|
+
当前支持的是**独立任务会话并行**,不是共享工作树的协同多 Worker。后续多 Worker
|
|
157
|
+
开发任务会引入 parent/child 任务图、依赖、并发上限、结构化 handoff、汇总验收和
|
|
158
|
+
跨进程恢复,但不会放宽“一个 worktree 一个写入者”的边界,也不会自动 merge 或 publish。
|
|
159
|
+
该阶段应安排在固定 Claude `2.1.270` 稳定性统计和单 Worker recovery 语义完成之后。
|
|
160
|
+
|
|
131
161
|
Pull Request 必须通过聚合的 `CI / Quality gate`。Release Please 根据 Conventional Commits 创建版本 PR;维护者合并后,Release workflow 会针对精确 tag commit 重新验证,并通过受保护的 `npm` environment 使用 npm provenance 发布。
|
|
132
162
|
|
|
133
163
|
详细内容见 [engineering-plan.md](docs/engineering-plan.md)、[independent-review.md](docs/independent-review.md)、[architecture.md](docs/architecture.md)、[testing.md](docs/testing.md) 和 [releasing.md](docs/releasing.md)。
|
package/README.md
CHANGED
|
@@ -57,8 +57,9 @@ export PI_CLAUDE_SUPERVISOR_WORKER=claude
|
|
|
57
57
|
```text
|
|
58
58
|
/supervise capabilities
|
|
59
59
|
/supervise start inspect the current repository and report what should be changed
|
|
60
|
+
/supervise start --spec ./task.json
|
|
60
61
|
/supervise sessions
|
|
61
|
-
/supervise recover <task-id>
|
|
62
|
+
/supervise recover [--takeover] <task-id>
|
|
62
63
|
/supervise poll
|
|
63
64
|
/supervise poll all
|
|
64
65
|
/supervise send continue with read-only inspection
|
|
@@ -68,6 +69,22 @@ export PI_CLAUDE_SUPERVISOR_WORKER=claude
|
|
|
68
69
|
/supervise verify
|
|
69
70
|
```
|
|
70
71
|
|
|
72
|
+
`--spec` accepts a JSON file; checks are always executed with argv (never through
|
|
73
|
+
a shell), for example:
|
|
74
|
+
|
|
75
|
+
```json
|
|
76
|
+
{
|
|
77
|
+
"goal": "Implement the requested change",
|
|
78
|
+
"scope": ["src/"],
|
|
79
|
+
"constraints": ["Keep the public API compatible"],
|
|
80
|
+
"forbidden": ["Do not publish artifacts"],
|
|
81
|
+
"acceptance": [
|
|
82
|
+
{ "id": "tests", "name": "tests", "command": "npm", "args": ["test"], "required": true }
|
|
83
|
+
],
|
|
84
|
+
"maxRepairRounds": 3
|
|
85
|
+
}
|
|
86
|
+
```
|
|
87
|
+
|
|
71
88
|
The default MVP writes the task to the worker's stdin as plain process-pipe
|
|
72
89
|
text. After running the transport spike for the target CLI, JSONL framing can
|
|
73
90
|
be selected explicitly:
|
|
@@ -83,16 +100,36 @@ The supervisor allows only one active JSONL request per session: poll until its
|
|
|
83
100
|
yet exposed by the adapter. Multiple independent task sessions can run
|
|
84
101
|
concurrently when they use different canonical working directories or
|
|
85
102
|
worktrees; same-directory starts are rejected even when concurrent, and
|
|
86
|
-
`/supervise sessions` lists the sessions.
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
103
|
+
`/supervise sessions` lists the sessions. This is independent-session
|
|
104
|
+
parallelism, not coordinated multi-worker collaboration. A future multi-worker
|
|
105
|
+
milestone will add explicit parent/child task graphs, dependencies, bounded
|
|
106
|
+
scheduling, structured handoffs, aggregate acceptance and graph-aware recovery;
|
|
107
|
+
it will not relax the one-writer-per-worktree rule or enable automatic
|
|
108
|
+
merge/publish. Unattended use still requires the remaining lifecycle, signal and
|
|
109
|
+
recovery checks. Host permissions and network access follow explicit caller
|
|
110
|
+
authorization and host policy; there is no automatic merge, deploy, release or
|
|
111
|
+
publish.
|
|
112
|
+
|
|
113
|
+
The `v0.5.0` automation milestone adds a structured acceptance pipeline:
|
|
114
|
+
multiple argv-based checks, an independent read-only Reviewer, bounded structured
|
|
115
|
+
findings and repair rounds. Legacy text tasks keep the default `git diff --check`.
|
|
116
|
+
The Reviewer only has `read`, `grep`, `find` and `ls`; it cannot edit files or grant
|
|
117
|
+
permissions. The next gates are pinned Claude Code `2.1.270` stability statistics
|
|
118
|
+
and explicit session recovery. Coordinated multi-worker scheduling is a later
|
|
119
|
+
milestone; CI will use deterministic fake Workers/replay fixtures, and real
|
|
120
|
+
multi-worker Claude tests will remain authenticated manual Spikes. CLI
|
|
121
|
+
multi-version compatibility, sandboxing, low-privilege execution and network
|
|
122
|
+
isolation are not part of this milestone.
|
|
90
123
|
|
|
91
124
|
Automatic mode persists the Pi Decision Worker session under the configured state
|
|
92
125
|
directory. After an unclean Pi restart, `/supervise sessions` lists recoverable
|
|
93
|
-
tasks; `/supervise recover <task-id>` explicitly restores the Decision Worker
|
|
126
|
+
tasks; `/supervise recover [--takeover] <task-id>` explicitly restores the Decision Worker
|
|
94
127
|
context and starts a new Claude Worker. It never silently resumes or duplicates
|
|
95
|
-
work.
|
|
128
|
+
work. If the old Pi owner is dead, add `--takeover` only after the lease proves
|
|
129
|
+
the old Worker's process group is gone and its cgroup is a real, readable empty
|
|
130
|
+
boundary; missing or unverifiable Worker evidence is refused.
|
|
131
|
+
For a persistent tmux Worker, use explicit `adopt-tmux` instead of takeover.
|
|
132
|
+
The adapter intentionally does not inherit arbitrary host environment variables.
|
|
96
133
|
Pass credentials through an explicit `WorkerStartInput.env` in an embedding
|
|
97
134
|
integration. For the built-in command, opt in to named variables, for example
|
|
98
135
|
`PI_CLAUDE_SUPERVISOR_WORKER_ENV=ANTHROPIC_API_KEY`.
|
package/docs/architecture.md
CHANGED
|
@@ -27,6 +27,28 @@ directories/worktrees; same-cwd and parent/child cwd starts are rejected before
|
|
|
27
27
|
spawn, including concurrent starts, to prevent uncoordinated edits. Pending starts
|
|
28
28
|
are also awaited during Pi shutdown.
|
|
29
29
|
|
|
30
|
+
### Multi-worker boundary and roadmap
|
|
31
|
+
|
|
32
|
+
The current implementation supports multiple **independent** task sessions, not
|
|
33
|
+
coordinated shared-worktree editing. Every active session must own a
|
|
34
|
+
non-overlapping canonical cwd/worktree and has an isolated Supervisor,
|
|
35
|
+
watchdog, Worker handle and acceptance/review loop. The shared EventLog is only
|
|
36
|
+
an audit stream; it is not a collaboration or authorization channel.
|
|
37
|
+
|
|
38
|
+
A future multi-worker scheduler must introduce an explicit parent/child task
|
|
39
|
+
graph, roles, dependencies, bounded concurrency and structured handoff
|
|
40
|
+
artifacts. Child Workers must communicate through validated evidence and event
|
|
41
|
+
references rather than another Worker's control channel. Each child is accepted
|
|
42
|
+
independently; the parent can complete only after aggregate acceptance and
|
|
43
|
+
independent Review. Integration, conflict resolution, merge and publication
|
|
44
|
+
remain explicit human-controlled operations in a separate integration worktree.
|
|
45
|
+
|
|
46
|
+
Recovery and shutdown must be graph-aware: a parent with an unknown child state
|
|
47
|
+
cannot complete, cancellation must propagate within a bounded budget, and Pi
|
|
48
|
+
shutdown must leave every child either cleanup-verified or explicitly
|
|
49
|
+
recoverable. This work is scheduled after single-worker stability and session
|
|
50
|
+
recovery, not by relaxing the current cwd lease rule.
|
|
51
|
+
|
|
30
52
|
## MVP transport
|
|
31
53
|
|
|
32
54
|
`ProcessWorkerAdapter` uses `node:child_process.spawn` with:
|
|
@@ -126,9 +148,12 @@ registry before spawning Claude. The default registry is
|
|
|
126
148
|
may point all Pi processes at an alternate shared directory. Canonical paths
|
|
127
149
|
conflict with both their parents and descendants, and the registry lock
|
|
128
150
|
serializes acquisition across independent Pi processes. A lease is released
|
|
129
|
-
only after the adapter confirms the worker and its descendant cleanup
|
|
130
|
-
unconfirmed lease left by a crashed Pi is intentionally retained
|
|
131
|
-
operator
|
|
151
|
+
only after the adapter confirms the worker and its descendant cleanup. An
|
|
152
|
+
unconfirmed lease left by a crashed Pi is intentionally retained. Ordinary
|
|
153
|
+
recovery refuses it; an operator may use `recover --takeover` only when the old
|
|
154
|
+
owner is dead, the Worker process group is gone, and the lease independently
|
|
155
|
+
reads a real empty cgroup boundary for the old Worker. Missing or unverifiable
|
|
156
|
+
Worker evidence still requires manual cleanup rather than unsafe reclamation.
|
|
132
157
|
An explicitly adopted tmux session may hand off an existing lease only after
|
|
133
158
|
its owner identity is no longer live and its canonical cwd, tmux session/socket,
|
|
134
159
|
pane id, pane PID/start time, and pane command all match; ordinary starts
|
|
@@ -170,7 +195,8 @@ duplicate turns. The adapter also exposes event subscriptions for `result`,
|
|
|
170
195
|
`control_request`, permission requests and process exit. Automatic mode routes
|
|
171
196
|
those events to a persistent, read-only Pi Decision Worker; its Pi session JSONL
|
|
172
197
|
and task mapping are persisted under the supervisor state directory. After an
|
|
173
|
-
unclean Pi restart, recovery is explicit: `/supervise recover
|
|
198
|
+
unclean Pi restart, recovery is explicit: `/supervise recover [--takeover]
|
|
199
|
+
<task-id>` restores
|
|
174
200
|
the Decision Worker context and starts a new Claude Worker. It does not silently
|
|
175
201
|
resume or duplicate a task. It does not poll to detect turn completion. A watchdog timer remains only as a deadlock safety
|
|
176
202
|
fallback. Permission actions pass through `evaluatePermission` and can be
|
|
@@ -181,6 +207,29 @@ human operator; it does not attempt a second LLM fallback. Alert delivery is
|
|
|
181
207
|
kept independent from event-log persistence so an audit write failure cannot
|
|
182
208
|
suppress the alert.
|
|
183
209
|
|
|
210
|
+
## Acceptance, review and repair loop
|
|
211
|
+
|
|
212
|
+
A task may provide a structured `TaskSpec` with `goal`, `scope`, `constraints`,
|
|
213
|
+
`forbidden` and an ordered list of required or optional acceptance checks. A
|
|
214
|
+
legacy plain-text task is normalized to a goal with the default `git diff
|
|
215
|
+
--check` acceptance check. The verifier runs every configured check with argv,
|
|
216
|
+
bounded output and the same deterministic command policy; a Worker completion
|
|
217
|
+
claim never substitutes for these results.
|
|
218
|
+
|
|
219
|
+
When automatic supervision is enabled, a successful check set is passed to a
|
|
220
|
+
fresh read-only Reviewer session. The Reviewer receives the task specification, repository status/diff evidence,
|
|
221
|
+
check results and bounded Worker completion evidence, but not the Decision Worker
|
|
222
|
+
conversation or control channel. It can inspect only `read`, `grep`, `find` and `ls`, and must return
|
|
223
|
+
`pass`, `revise` or `human` with bounded structured findings. Invalid Reviewer
|
|
224
|
+
output or a Reviewer API failure is a human-required condition.
|
|
225
|
+
|
|
226
|
+
A `revise` result produces an audited repair round and sends a bounded corrective
|
|
227
|
+
instruction to a still-live JSONL/tmux Worker. Checks and review then run again.
|
|
228
|
+
The repair budget defaults to three rounds; repeated findings and P0/P1 findings
|
|
229
|
+
stop automation and escalate. A non-persistent Worker that has already exited
|
|
230
|
+
cannot be silently recreated for repair; it remains failed/recoverable rather
|
|
231
|
+
than replaying the original task.
|
|
232
|
+
|
|
184
233
|
## Deliberate non-goals
|
|
185
234
|
|
|
186
235
|
- automatic merge/deploy/release;
|
|
@@ -192,4 +241,7 @@ suppress the alert.
|
|
|
192
241
|
- shell command interpolation;
|
|
193
242
|
- automatic network denial or a fake domain allowlist. Network access follows
|
|
194
243
|
Claude's own permission model and the command policy; suspicious download-to-
|
|
195
|
-
shell patterns require human review rather than blanket network rejection
|
|
244
|
+
shell patterns require human review rather than blanket network rejection;
|
|
245
|
+
- Claude CLI multi-version compatibility in the current stability milestone;
|
|
246
|
+
- OS sandbox, low-privilege execution and network isolation in the current
|
|
247
|
+
lifecycle milestone.
|
package/docs/engineering-plan.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Pi Claude Supervisor 完整方案
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> 文档状态:`v0.5.0` 已发布 / 后续开发路线图
|
|
4
4
|
> 目标项目目录:`pi-claude-supervisor`
|
|
5
5
|
> 适用对象:W、项目负责人、实现人员、评审人员
|
|
6
6
|
|
|
@@ -36,7 +36,7 @@ Claude Code Worker
|
|
|
36
36
|
4. Supervisor 因误判导致无限循环、危险操作或不可审计的修改。
|
|
37
37
|
5. 人工无法随时接管或恢复任务。
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
**当前状态:`v0.5.0` 已完成“验收—独立 Review—自动修复—再验收”闭环并正式发布。下一阶段先完成固定 Claude Code `2.1.270` 的稳定性统计和恢复语义,再推进有边界的多 Worker 协作;低权限用户、OS sandbox 与网络隔离仍是后续安全加固,不作为当前主线硬性阻塞。**
|
|
40
40
|
|
|
41
41
|
---
|
|
42
42
|
|
|
@@ -74,7 +74,9 @@ Claude Code 适合作为实际开发 Worker,但在长时间任务中可能出
|
|
|
74
74
|
- 不自动 merge、deploy 或 release。
|
|
75
75
|
|
|
76
76
|
当前扩展已支持多个独立任务会话并行推进,但不允许活动会话共享同一
|
|
77
|
-
工作目录。事件日志由跨进程锁协调,状态和 watchdog
|
|
77
|
+
工作目录。事件日志由跨进程锁协调,状态和 watchdog 按会话隔离。这里要区分两种
|
|
78
|
+
“多 Worker”:**独立会话并行**已经属于当前能力;**有依赖、交接和汇总验收的协同多
|
|
79
|
+
Worker**属于后续开发任务,不能通过简单地放宽 cwd 限制来实现。
|
|
78
80
|
|
|
79
81
|
暂不支持:
|
|
80
82
|
|
|
@@ -916,3 +918,115 @@ PTY 和 headless JSONL 只能选择一个作为 MVP 的主 transport,禁止两
|
|
|
916
918
|
## 附录 B:一句话版本
|
|
917
919
|
|
|
918
920
|
> 先用最小、可审计、可接管的 Supervisor 闭环证明可靠性,再逐步开放 LLM 判断和自动化权限;不要从“自动化最多”开始,而要从“边界最清楚、证据最可靠”开始。
|
|
921
|
+
|
|
922
|
+
## 20. 近期落地与剩余门禁:稳定的自动验收闭环
|
|
923
|
+
|
|
924
|
+
本轮已落地 TaskSpec、多命令验收、独立只读 Reviewer、结构化 repair round、重复 finding/P0/P1 人工升级、JSONL 去重和确定性 replay fixture。剩余门禁是固定 CLI 的重复运行统计,而不是继续扩大安全边界。近期目标从“扩大安全边界”调整为先证明单一已验证 Claude CLI 版本上的真实功能稳定性。当前只验证固定的 Claude Code `2.1.270`,不把多版本兼容作为本阶段任务。OS sandbox、低权限用户、网络 allowlist、SBOM 和更深的供应链加固后置,不作为本阶段门禁;现有 no-shell、Policy Gate、人工接管和独立验收边界继续保留。
|
|
925
|
+
|
|
926
|
+
### 20.1 Goal / Evidence / Sign-off 模型
|
|
927
|
+
|
|
928
|
+
任务规格统一为:
|
|
929
|
+
|
|
930
|
+
```yaml
|
|
931
|
+
goal: 实现用户邀请接口
|
|
932
|
+
scope:
|
|
933
|
+
- 新增接口
|
|
934
|
+
- 添加权限校验
|
|
935
|
+
constraints:
|
|
936
|
+
- 不修改核心数据库模型
|
|
937
|
+
forbidden:
|
|
938
|
+
- 不执行生产部署
|
|
939
|
+
acceptance:
|
|
940
|
+
- id: tests
|
|
941
|
+
command: npm
|
|
942
|
+
args: [test]
|
|
943
|
+
- id: typecheck
|
|
944
|
+
command: npm
|
|
945
|
+
args: [run, typecheck]
|
|
946
|
+
- id: diff-check
|
|
947
|
+
command: git
|
|
948
|
+
args: [diff, --check]
|
|
949
|
+
maxRepairRounds: 3
|
|
950
|
+
```
|
|
951
|
+
|
|
952
|
+
兼容旧任务时,普通任务文本作为 `goal`,默认验收仍为 `git diff --check`。所有验收命令使用 argv 和确定性 Policy Gate,不经过 shell。
|
|
953
|
+
|
|
954
|
+
验收流程固定为:
|
|
955
|
+
|
|
956
|
+
```text
|
|
957
|
+
Worker result
|
|
958
|
+
→ 多命令 acceptance checks
|
|
959
|
+
→ 独立只读 Reviewer
|
|
960
|
+
├── pass → completed
|
|
961
|
+
├── revise → 结构化修复指令 → Worker → 重新验收
|
|
962
|
+
└── human → 人工接管
|
|
963
|
+
```
|
|
964
|
+
|
|
965
|
+
Reviewer 必须使用独立 Pi session,只允许 `read`、`grep`、`find`、`ls`,输出结构化 verdict 和 findings;不能修改工作树或直接批准权限。默认最多三轮修复;相同 finding 重复出现或出现 P0/P1 问题时升级人工。
|
|
966
|
+
|
|
967
|
+
### 20.2 JSONL 稳定性证据
|
|
968
|
+
|
|
969
|
+
只对 Claude Code `2.1.270` 建立证据,覆盖:
|
|
970
|
+
|
|
971
|
+
- JSONL 跨 chunk 拆分、单 chunk 多记录和 malformed 行;malformed 行不能触发完成事件;
|
|
972
|
+
- 重复 result、重复 permission request、重复 Supervisor idempotency key 不产生重复动作;
|
|
973
|
+
- active request 期间的 SIGTERM、SIGINT、stop 和 Pi shutdown;
|
|
974
|
+
- 普通完成、低风险 Bash allow、`AskUserQuestion` deny-to-text、多轮、验收失败修复和恢复回放。
|
|
975
|
+
|
|
976
|
+
真实 Claude Spike 不进入普通 CI;确定性 fake Worker/replay fixture 进入 CI。自动模式继续保持显式 opt-in,直到以下门禁通过:普通任务连续十次成功,权限和问题转文本场景各至少五次成功,无重复动作、无错误 complete、无未清理 Worker,且关键事件可以完整回放。
|
|
977
|
+
|
|
978
|
+
### 20.3 明确不属于本阶段
|
|
979
|
+
|
|
980
|
+
- Claude CLI 多版本兼容;
|
|
981
|
+
- OS sandbox、低权限执行和网络隔离;
|
|
982
|
+
- 自动 merge、deploy、release、publish;
|
|
983
|
+
- 多 Worker 在同一工作树协作。
|
|
984
|
+
|
|
985
|
+
## 21. 后续开发路线图
|
|
986
|
+
|
|
987
|
+
`v0.5.0` 的发布不代表所有自动化目标都已完成。后续任务按“稳定性 → 恢复 → 协同
|
|
988
|
+
调度 → 安全加固”推进;多 Worker 可以纳入开发任务,但应作为独立阶段,不能与当前
|
|
989
|
+
单 Worker 稳定性门禁混在一起。
|
|
990
|
+
|
|
991
|
+
### 21.1 短期:稳定性收尾
|
|
992
|
+
|
|
993
|
+
- 完成真实 Claude Code `2.1.270` 重复 Spike:普通任务连续 10 次,权限和问题回退各至少 5 次;
|
|
994
|
+
- 补齐 replay:多轮修复、验收失败修复、repair budget 耗尽、takeover、recover 和 Pi shutdown;
|
|
995
|
+
- 补齐边界测试:Reviewer 流式输出上限、`DecisionSessionStore.list()` 任务 ID 校验、跨进程恢复和超时/输出截断;
|
|
996
|
+
- 继续观察 npm `0.5.0`、GitHub Release 资产、provenance 和回滚路径;
|
|
997
|
+
- 验收标准:无重复动作、错误 complete、未清理 Worker 或未审计的自动放行。
|
|
998
|
+
|
|
999
|
+
### 21.2 中期:恢复能力
|
|
1000
|
+
|
|
1001
|
+
- 设计安全的 Claude session resume;明确 `--resume` 与实时 PTY attach 的边界;
|
|
1002
|
+
- 完善 takeover、recover、Pi shutdown、Worker 崩溃和部分完成的状态语义;
|
|
1003
|
+
- 增加跨进程恢复端到端测试,包括 cwd lease、Decision Worker session、Worker 身份和事件日志一致性;
|
|
1004
|
+
- 恢复失败必须进入 `HUMAN_REQUIRED`,不能静默重放原始任务或重复发送输入。
|
|
1005
|
+
|
|
1006
|
+
### 21.3 后续:多 Worker 协作与调度
|
|
1007
|
+
|
|
1008
|
+
第一阶段只做**独立 worktree 的多 Worker 编排**,不允许共享工作树写入。建议拆成以下
|
|
1009
|
+
开发任务:
|
|
1010
|
+
|
|
1011
|
+
1. **任务图与角色模型**:增加 `parentTaskId`、Worker role、`dependsOn`、worktree、handoff
|
|
1012
|
+
artifact 和子任务状态;明确 root task 与 child task 的审计关联。
|
|
1013
|
+
2. **受限调度器**:实现并发上限、依赖就绪、全局时间/修复预算、取消传播和失败隔离;
|
|
1014
|
+
不让任意 Worker 自行启动、停止或批准另一个 Worker。
|
|
1015
|
+
3. **结构化交接**:Worker 之间只通过受限 artifact、事件引用和验收报告交接,不直接共享
|
|
1016
|
+
控制通道;交接内容必须经过 schema 校验和大小限制。
|
|
1017
|
+
4. **汇总验收**:每个 child 先独立验收,root task 再汇总目标、diff、测试和 Reviewer 结果;
|
|
1018
|
+
冲突、缺失证据或任一 P0/P1 自动升级人工。
|
|
1019
|
+
5. **恢复与关闭**:支持单个 child、整棵任务图和 Pi shutdown 的一致性恢复;父任务不能在
|
|
1020
|
+
子任务状态未知时报告 `completed`。
|
|
1021
|
+
6. **冲突检测和人工整合**:只允许在独立 integration worktree 中进行显式整合;不自动
|
|
1022
|
+
merge/publish,冲突和整合动作必须保留人工控制权。
|
|
1023
|
+
|
|
1024
|
+
多 Worker 阶段的最小验收矩阵:两个独立 Worker 并行、依赖顺序、一个 Worker 失败、取消
|
|
1025
|
+
传播、重复交接、工作树冲突、单 child 恢复、整棵任务图恢复和 shutdown 中断。通过这些
|
|
1026
|
+
门禁后,才评估是否需要更复杂的 lead-worker 或动态任务分解。
|
|
1027
|
+
|
|
1028
|
+
### 21.4 后置:安全加固
|
|
1029
|
+
|
|
1030
|
+
- CLI 多版本兼容矩阵;
|
|
1031
|
+
- OS sandbox、低权限执行、网络隔离/allowlist;
|
|
1032
|
+
- 更深的供应链、SBOM、密钥隔离和生产监控。
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Recovery follow-up review
|
|
2
|
+
|
|
3
|
+
The independent read-only review of the recovery changes initially returned
|
|
4
|
+
`BLOCK` with three P1 findings, one P2 finding, and a coverage note. The findings
|
|
5
|
+
were addressed in this follow-up.
|
|
6
|
+
|
|
7
|
+
- Stale `starting`/`registered`/`recovered_idle` claims now persist recovery
|
|
8
|
+
owner PID/start time, are reconciled only after the old owner and Worker
|
|
9
|
+
boundary are independently gone, and return to an explicit `interrupted`
|
|
10
|
+
state.
|
|
11
|
+
- `--takeover` requires a dead owner, dead Worker/process group, and a real,
|
|
12
|
+
readable empty cgroup boundary; missing or unverifiable Worker evidence is
|
|
13
|
+
rejected.
|
|
14
|
+
- Worker registration and `recovered_idle` transitions require an active record,
|
|
15
|
+
persist atomically, and are read back and checked before the recovered session
|
|
16
|
+
is exposed.
|
|
17
|
+
- Adopted tmux handoff reports the replaced task and closes its old Decision
|
|
18
|
+
session mapping only after worker identity registration succeeds.
|
|
19
|
+
- Session closure now carries cleanup evidence and intent; uncertain cleanup
|
|
20
|
+
retains the active record and cwd lease.
|
|
21
|
+
|
|
22
|
+
Validation: `npm run check`, `npm run build`, the pinned Claude Code 2.1.270
|
|
23
|
+
question matrix (5/5 verified), and the bounded stability evidence in
|
|
24
|
+
[`stability-matrix-2.1.270.md`](stability-matrix-2.1.270.md).
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Claude Code 2.1.270 stability matrix
|
|
2
|
+
|
|
3
|
+
Run date: 2026-09-14. The executable was resolved as
|
|
4
|
+
`/home/yancao/.local/share/mise/installs/claude/2.1.270/claude` and reported
|
|
5
|
+
`2.1.270 (Claude Code)`. Runs used the authenticated local provider and
|
|
6
|
+
`scripts/spike-claude-automation.mjs`; no Claude `--resume` was used.
|
|
7
|
+
|
|
8
|
+
## Required matrix (120 s bounded run)
|
|
9
|
+
|
|
10
|
+
| Scenario | Runs | Completed + verified | Fail-closed outcomes |
|
|
11
|
+
| --- | ---: | ---: | --- |
|
|
12
|
+
| ordinary task | 10 | 9 | 1 stopped at the bounded deadline without verification |
|
|
13
|
+
| permission handling | 5 | 5 | 0 |
|
|
14
|
+
| question handling | 5 | 5 | 0 |
|
|
15
|
+
|
|
16
|
+
The ordinary outlier was not treated as success: the spike exited non-zero,
|
|
17
|
+
kept verification false, and stopped rather than retrying or replaying the task.
|
|
18
|
+
This is the intended timeout fail-closed behavior. An earlier question spike also
|
|
19
|
+
escalated after invalid Decision Worker output; it was likewise not counted as a
|
|
20
|
+
success. The five-run question matrix above was then rerun with a 180 s bound and
|
|
21
|
+
all five completed with `verified=true` and zero human interventions.
|
|
22
|
+
|
|
23
|
+
## Bounded follow-up
|
|
24
|
+
|
|
25
|
+
Three additional ordinary and three additional question runs with the same
|
|
26
|
+
pinned executable and a 180 s bound also completed with `verified=true` and zero
|
|
27
|
+
human interventions. These runs support a provider-latency explanation for the
|
|
28
|
+
120 s outliers; they do not turn an outlier into a success.
|
|
29
|
+
|
|
30
|
+
The deterministic replay, acceptance, recovery-state, lease, cleanup and
|
|
31
|
+
package checks remain the CI evidence. Authenticated Claude runs are manual
|
|
32
|
+
release evidence only.
|
package/docs/testing.md
CHANGED
|
@@ -49,9 +49,9 @@ non-sensitive prompt, and prints protocol metadata rather than raw model output.
|
|
|
49
49
|
It must not be added to the normal CI gate because authentication is an owner
|
|
50
50
|
controlled prerequisite.
|
|
51
51
|
|
|
52
|
-
The
|
|
53
|
-
permission allow/deny and SIGTERM/SIGINT behavior
|
|
54
|
-
|
|
52
|
+
The transport fixtures validate one prompt, multiple turns, session resume,
|
|
53
|
+
permission allow/deny and SIGTERM/SIGINT behavior. The current release validation
|
|
54
|
+
uses Claude Code 2.1.270 at
|
|
55
55
|
`/home/yancao/.local/share/mise/installs/claude/2.1.270/claude`, including real
|
|
56
56
|
owned tmux turns, pause/resume, and restart re-adoption.
|
|
57
57
|
The adapter regression suite also verifies event subscription, parsed
|
|
@@ -59,11 +59,18 @@ The adapter regression suite also verifies event subscription, parsed
|
|
|
59
59
|
The automation spike additionally exercises a real Pi SDK Decision Worker with
|
|
60
60
|
Claude: ordinary completion, harmless Bash permission approval, and an
|
|
61
61
|
`AskUserQuestion` denial-to-text fallback followed by automatic verification.
|
|
62
|
+
A local pinned-CLI run completed all three scenarios with `state=completed`,
|
|
63
|
+
`verified=true`, and zero human interventions. Provider/model latency can still
|
|
64
|
+
cause a later run to fail closed as human-required after the bounded Decision
|
|
65
|
+
Worker or Reviewer timeout; this is evidence for the manual spike only, not a CI
|
|
66
|
+
guarantee.
|
|
62
67
|
The extension persists each automatic Decision Worker session as Pi JSONL plus a
|
|
63
68
|
0600 task mapping. Recovery is explicit and safe: after an unclean Pi restart,
|
|
64
69
|
`/supervise sessions` shows the task as `recoverable`, and `/supervise recover
|
|
65
|
-
<task-id>` restores the Decision Worker history before starting a new
|
|
66
|
-
Worker.
|
|
70
|
+
[--takeover] <task-id>` restores the Decision Worker history before starting a new
|
|
71
|
+
Claude Worker. `--takeover` is accepted only when the old Pi owner is dead, the
|
|
72
|
+
Worker process group is gone, and its cgroup is a real readable empty boundary;
|
|
73
|
+
persistent tmux sessions use `adopt-tmux`.
|
|
67
74
|
Run the permission and signal probes explicitly when validating a CLI release:
|
|
68
75
|
|
|
69
76
|
```bash
|
|
@@ -89,7 +96,9 @@ response, and an exact result marker; it also records metadata only.
|
|
|
89
96
|
|
|
90
97
|
For each release, pin and record the validated Claude Code version, resolved
|
|
91
98
|
executable path, and model. The spikes reject an unpinned/mismatched executable
|
|
92
|
-
version. For this release the validated version is `2.1.270` with model `opus
|
|
99
|
+
version. For this release the validated version is `2.1.270` with model `opus`;
|
|
100
|
+
the bounded matrix and its fail-closed outliers are recorded in
|
|
101
|
+
[`docs/stability-matrix-2.1.270.md`](stability-matrix-2.1.270.md).
|
|
93
102
|
Record:
|
|
94
103
|
|
|
95
104
|
1. exact version and resolved executable path;
|
|
@@ -144,3 +153,68 @@ not eliminate the post-spawn attachment window. `SIGSTOP` and `SIGKILL` of the P
|
|
|
144
153
|
verify and document the resulting orphan behavior.
|
|
145
154
|
Default behavior must be fail-closed and leave no orphaned worker process within
|
|
146
155
|
the managed process group.
|
|
156
|
+
|
|
157
|
+
## Near-term automation acceptance gate
|
|
158
|
+
|
|
159
|
+
The `v0.5.0` implementation of the acceptance—independent Review—repair—reacceptance
|
|
160
|
+
loop is shipped. The remaining gate focuses on real stability for the pinned
|
|
161
|
+
Claude Code `2.1.270` CLI. It does not add a multi-version matrix or wait for
|
|
162
|
+
OS sandbox, low-privilege or network-isolation work.
|
|
163
|
+
|
|
164
|
+
### Acceptance and Reviewer fixtures
|
|
165
|
+
|
|
166
|
+
Deterministic tests must cover:
|
|
167
|
+
|
|
168
|
+
- legacy text tasks normalized to a Goal with the default `git diff --check`;
|
|
169
|
+
- multiple required/optional checks with bounded output, timeout and exit-code evidence;
|
|
170
|
+
- independent read-only Reviewer pass/revise/human results;
|
|
171
|
+
- invalid Reviewer JSON and Reviewer API failure escalating to human;
|
|
172
|
+
- repair rounds, repeated finding detection, P0/P1 escalation and repair-budget exhaustion;
|
|
173
|
+
- completion being impossible without passing all required checks and review.
|
|
174
|
+
|
|
175
|
+
Reviewer sessions use only `read`, `grep`, `find` and `ls`; they must not modify
|
|
176
|
+
the worktree or send Worker input. Decision Worker and Reviewer model calls are
|
|
177
|
+
bounded; timeout or API failure escalates instead of auto-completing. Review reports
|
|
178
|
+
are persisted as bounded event payloads and are not treated as permission grants.
|
|
179
|
+
|
|
180
|
+
### JSONL protocol and replay fixtures
|
|
181
|
+
|
|
182
|
+
The adapter/replay matrix must cover:
|
|
183
|
+
|
|
184
|
+
- JSON split across stdout chunks and multiple records in one chunk;
|
|
185
|
+
- malformed JSON between valid records without a false completion event;
|
|
186
|
+
- duplicate result and permission records without duplicate actions;
|
|
187
|
+
- duplicate Supervisor idempotency keys without duplicate input;
|
|
188
|
+
- stop, SIGTERM, SIGINT and Pi shutdown while a JSONL request is active;
|
|
189
|
+
- ordinary completion, low-risk permission allow, AskUserQuestion deny-to-text,
|
|
190
|
+
multi-turn, verifier failure/repair, takeover and explicit recovery.
|
|
191
|
+
|
|
192
|
+
Real Claude tests remain authenticated manual Spikes and are pinned to
|
|
193
|
+
`2.1.270`; they are not part of normal CI. Normal CI runs deterministic fake
|
|
194
|
+
Worker and replay fixtures. The short-term stability gate is still pending and
|
|
195
|
+
must include ten consecutive ordinary automatic runs and at least five runs each
|
|
196
|
+
for permission and question handling, with no duplicate action, false completion
|
|
197
|
+
or unreaped Worker.
|
|
198
|
+
|
|
199
|
+
## Future multi-worker test plan
|
|
200
|
+
|
|
201
|
+
Multiple independent task sessions already run concurrently when their canonical
|
|
202
|
+
cwd/worktrees do not overlap. This is not yet coordinated multi-worker
|
|
203
|
+
collaboration. The future multi-worker milestone must be tested as a task graph,
|
|
204
|
+
not as unrestricted shared-worker access.
|
|
205
|
+
|
|
206
|
+
Required deterministic and integration coverage:
|
|
207
|
+
|
|
208
|
+
- two independent Workers with separate worktrees and aggregated parent status;
|
|
209
|
+
- dependency ordering and a blocked child that must not start early;
|
|
210
|
+
- child failure, timeout, cancellation propagation and bounded global budgets;
|
|
211
|
+
- schema-validated handoff artifacts with duplicate/oversized/stale handoffs;
|
|
212
|
+
- conflicting diffs detected before integration, with no same-worktree writes;
|
|
213
|
+
- independent child acceptance followed by root-task aggregate acceptance and Review;
|
|
214
|
+
- single-child recovery, whole-graph recovery and Pi shutdown during scheduling;
|
|
215
|
+
- no child can grant permissions, send control input to another child or bypass Policy Gate;
|
|
216
|
+
- explicit human-controlled integration in a separate worktree; no automatic merge or publish.
|
|
217
|
+
|
|
218
|
+
The multi-worker gate should be added only after the pinned single-worker stability
|
|
219
|
+
and recovery gates pass. CI should use fake Workers and replay fixtures; authenticated
|
|
220
|
+
Claude multi-worker Spikes remain manual and version-pinned.
|