pi-claude-supervisor 0.2.0
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 +36 -0
- package/LICENSE +21 -0
- package/README.cn.md +98 -0
- package/README.md +122 -0
- package/docs/architecture.md +122 -0
- package/docs/engineering-plan.md +918 -0
- package/docs/implementation-review.md +62 -0
- package/docs/independent-review.md +332 -0
- package/docs/releasing.md +112 -0
- package/docs/testing.md +109 -0
- package/docs/transport-spike-2026-09-12.md +94 -0
- package/package.json +72 -0
- package/src/config.ts +35 -0
- package/src/decision-session-store.ts +170 -0
- package/src/decision-worker.ts +245 -0
- package/src/events.ts +179 -0
- package/src/index.ts +500 -0
- package/src/notifications.ts +85 -0
- package/src/policy.ts +61 -0
- package/src/state.ts +44 -0
- package/src/supervisor.ts +626 -0
- package/src/types.ts +122 -0
- package/src/verifier.ts +40 -0
- package/src/worker/environment.ts +31 -0
- package/src/worker/process-adapter.ts +604 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Implementation Review
|
|
2
|
+
|
|
3
|
+
An independent read-only reviewer examined the implementation before the final
|
|
4
|
+
hardening pass. The review found no blocker in the TypeScript/Pi registration
|
|
5
|
+
surface. The MVP intentionally does not provide OS sandboxing, low-privilege
|
|
6
|
+
execution, or network isolation; those are deferred security-hardening items,
|
|
7
|
+
not blockers for the lifecycle and recovery track.
|
|
8
|
+
|
|
9
|
+
## Findings addressed in this pass
|
|
10
|
+
|
|
11
|
+
- Policy now evaluates the executable and argv together, including Claude
|
|
12
|
+
permission-bypass flags.
|
|
13
|
+
- Worker and verifier processes use a minimal environment; explicit worker
|
|
14
|
+
variables can be selected with `PI_CLAUDE_SUPERVISOR_WORKER_ENV` or an
|
|
15
|
+
embedding caller's `WorkerStartInput.env`.
|
|
16
|
+
- Startup failures clean up a worker and do not let event-log failures hide the
|
|
17
|
+
original error.
|
|
18
|
+
- Default wall-clock and no-output watchdogs stop stalled workers.
|
|
19
|
+
- New tasks clear stale handles and verification results.
|
|
20
|
+
- Custom verifier commands pass through the same deterministic policy gate.
|
|
21
|
+
- CI runs package-install and Pi-registration smoke tests.
|
|
22
|
+
- Spawn failures have a regression test; process termination escalates to the
|
|
23
|
+
process group after a grace period.
|
|
24
|
+
|
|
25
|
+
## Residual risks and follow-up hardening
|
|
26
|
+
|
|
27
|
+
These are verified limitations and follow-up work, not reasons to stop the
|
|
28
|
+
lifecycle track:
|
|
29
|
+
|
|
30
|
+
- OS sandbox, lower-privilege execution, and network allowlisting are not
|
|
31
|
+
provided by the adapter. The caller may run with explicitly authorized host
|
|
32
|
+
permissions; the deployment owner accepts responsibility for that boundary.
|
|
33
|
+
- Event contents can contain worker output or user messages; common credential
|
|
34
|
+
patterns are now redacted and sequence recovery is persisted, but broader
|
|
35
|
+
structured-secret coverage remains follow-up work.
|
|
36
|
+
- PTY semantics, permission-event handling, and process-group behavior with the
|
|
37
|
+
target Claude Code versions still require dedicated transport evidence. Basic
|
|
38
|
+
Claude JSONL prompt, multi-turn and session-resume fixtures now pass in the
|
|
39
|
+
recorded Spike.
|
|
40
|
+
- Fault injection coverage now includes lifecycle-log failure, SIGTERM refusal,
|
|
41
|
+
blocked stdin and managed orphan descendants; shutdown cleanup under injected
|
|
42
|
+
adapter failure remains a follow-up failure-injection case.
|
|
43
|
+
- The default transport is process-pipe. Claude JSONL framing is opt-in; the
|
|
44
|
+
next priority is signal, shutdown and descendant-cleanup evidence rather than
|
|
45
|
+
network or low-privilege isolation.
|
|
46
|
+
|
|
47
|
+
## Evidence
|
|
48
|
+
|
|
49
|
+
The review was performed against `src/`, `package.json`, workflows and tests.
|
|
50
|
+
The final local evidence is recorded by:
|
|
51
|
+
|
|
52
|
+
```text
|
|
53
|
+
npm ci --ignore-scripts --include=dev
|
|
54
|
+
npm run check
|
|
55
|
+
npm run test:pi
|
|
56
|
+
npm run test:install
|
|
57
|
+
npm audit --audit-level=high
|
|
58
|
+
npm run build
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
All commands passed on Node `v26.8.1`; Node `>=22.19` remains the declared
|
|
62
|
+
runtime target and still requires validation on the minimum supported version.
|
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
# 独立子 Agent 方案评审报告
|
|
2
|
+
|
|
3
|
+
> 评审对象:`requirement.txt`、`docs/engineering-plan.md`
|
|
4
|
+
> 评审重点:复用现有扩展、减少重复开发、形成可整合架构并验证到生产
|
|
5
|
+
|
|
6
|
+
## 1. 评审结论
|
|
7
|
+
|
|
8
|
+
总体架构合理,但当前不能把候选扩展直接叠加到生产环境。推荐采用:
|
|
9
|
+
|
|
10
|
+
> **复用 Pi 扩展加载机制和 Claude Code runtime;选择一个 Worker transport;自建极薄 Adapter、Policy Gate、状态机、事件日志和独立验证器。**
|
|
11
|
+
|
|
12
|
+
核心原则:
|
|
13
|
+
|
|
14
|
+
- 不让多个扩展同时拥有 Claude 的 spawn、watchdog、resume、stop 控制权。
|
|
15
|
+
- PTY 和 headless JSONL 只选择一个作为 MVP 主传输路径。
|
|
16
|
+
- `pi-goals` 主要复用 Goal / Evidence / Sign-off 数据模型。
|
|
17
|
+
- `pi-foreground-chains` 主要复用有限循环、等待检测和 reviewer 阶段思想。
|
|
18
|
+
- `pi-interactive-shell` 如果通过版本、API、许可证和故障测试,应优先复用其 PTY 和人工接管实现。
|
|
19
|
+
- `pi-claude-code`、`pi-harness-delegate` 在完成供应链、API 和故障语义审计前,不作为核心依赖。
|
|
20
|
+
|
|
21
|
+
**结论:架构方向 GO;先完成固定版本 Spike、生命周期和故障恢复主线。低权限用户、sandbox 与网络隔离属于后续安全加固,不作为当前主线硬阻塞。**
|
|
22
|
+
|
|
23
|
+
## 2. 外部参考源审查结果
|
|
24
|
+
|
|
25
|
+
| 参考源 | 建议 | 可复用内容 | 当前判断 |
|
|
26
|
+
|---|---|---|---|
|
|
27
|
+
| `pi-interactive-shell` | 优先做 Spike | PTY、实时输出、输入、人工接管、worktree 会话 | 候选主 transport,但必须验证 |
|
|
28
|
+
| `pi-foreground-chains` | 借鉴并局部复用 | continue loop、有限轮次、reviewer 阶段、进度记录 | 不能直接复制 regex 决策;文档主要展示 Codex Worker |
|
|
29
|
+
| `@mporenta/pi-claude-code` | 暂不作为核心依赖 | headless Claude 执行、watchdog、完成/异常事件 | 版本、日期、API、许可证和稳定性待核验 |
|
|
30
|
+
| `pi-goals-extension` / 相关 pi-goals 页面 | 复用设计思想或 schema | Goal、discriminator、evidence、sign-off | 不直接作为 Claude runtime |
|
|
31
|
+
| `pi-harness-delegate` | 可作为可选 adapter | Claude delegate、review、resume | 可能与本项目生命周期和审计逻辑重复 |
|
|
32
|
+
| Claude Code hooks | 作为 Worker 内部护栏 | Stop 前测试、阻止不完整停止 | 不能替代外部 Supervisor 和独立验收 |
|
|
33
|
+
|
|
34
|
+
### 2.1 需要特别纠正的事实
|
|
35
|
+
|
|
36
|
+
- `requirement.txt` 中的“70%~85% 已完成”没有计算方法,不能作为进度依据。
|
|
37
|
+
- 相关包的版本、发布日期、API 和生产能力必须以精确版本、commit、许可证和实测结果为准。
|
|
38
|
+
- 搜索结果显示 `pi-goals-extension` 这一名称更值得核验,不能直接假设普通 `pi-goals` 包名可安装。
|
|
39
|
+
- `pi-foreground-chains` 的资料重点是 Codex Worker 的自动继续流程,不应表述为 Claude 已经完成端到端验证。
|
|
40
|
+
- `@mporenta/pi-claude-code` 的发布时间和版本信息存在时间核验问题,在 lockfile 固定前必须重新确认。
|
|
41
|
+
|
|
42
|
+
## 3. 最小整合架构
|
|
43
|
+
|
|
44
|
+
```text
|
|
45
|
+
Pi Extension Loader / UI / Human Takeover
|
|
46
|
+
│
|
|
47
|
+
▼
|
|
48
|
+
pi-claude-supervisor
|
|
49
|
+
│
|
|
50
|
+
┌──────────┼──────────┐
|
|
51
|
+
▼ ▼ ▼
|
|
52
|
+
Policy Gate State Machine Event Log
|
|
53
|
+
│
|
|
54
|
+
▼
|
|
55
|
+
Worker Adapter
|
|
56
|
+
│
|
|
57
|
+
只选择一个 transport
|
|
58
|
+
┌───────┴────────┐
|
|
59
|
+
▼ ▼
|
|
60
|
+
PTY Spike Headless Spike
|
|
61
|
+
│ │
|
|
62
|
+
└───────┬────────┘
|
|
63
|
+
▼
|
|
64
|
+
Claude Code CLI
|
|
65
|
+
│
|
|
66
|
+
▼
|
|
67
|
+
Git Worktree / Tests
|
|
68
|
+
│
|
|
69
|
+
▼
|
|
70
|
+
Independent Verifier
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### 3.1 唯一控制权原则
|
|
74
|
+
|
|
75
|
+
MVP 中以下职责只能由一个组件负责:
|
|
76
|
+
|
|
77
|
+
| 职责 | 唯一拥有者 |
|
|
78
|
+
|---|---|
|
|
79
|
+
| spawn | Worker Adapter |
|
|
80
|
+
| stop / kill process group | Worker Adapter + Policy Gate |
|
|
81
|
+
| watchdog | Supervisor |
|
|
82
|
+
| session resume | Worker Adapter,但必须由 Supervisor 授权 |
|
|
83
|
+
| 状态转换 | Supervisor State Machine |
|
|
84
|
+
| 最终完成批准 | Independent Verifier + Supervisor |
|
|
85
|
+
| 人工接管 | Human,系统必须立即让权 |
|
|
86
|
+
|
|
87
|
+
任何第三方扩展如果内部再次自动重试、自动 resume 或自动 stop,必须关闭这些能力,或者不能纳入 MVP。
|
|
88
|
+
|
|
89
|
+
### 3.2 Adapter 必须具备的能力
|
|
90
|
+
|
|
91
|
+
当前方案中的 `WorkerAdapter` 需要增加:
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
interface WorkerAdapter {
|
|
95
|
+
capabilities(): Promise<WorkerCapabilities>;
|
|
96
|
+
start(input: WorkerStartInput): Promise<WorkerHandle>;
|
|
97
|
+
getStatus(handle: WorkerHandle): Promise<WorkerStatus>;
|
|
98
|
+
readOutput(handle: WorkerHandle): Promise<WorkerOutputChunk[]>;
|
|
99
|
+
send(handle: WorkerHandle, message: string, idempotencyKey: string): Promise<void>;
|
|
100
|
+
pause(handle: WorkerHandle): Promise<void>;
|
|
101
|
+
resume(handle: WorkerHandle): Promise<void>;
|
|
102
|
+
takeover(handle: WorkerHandle): Promise<void>;
|
|
103
|
+
stop(handle: WorkerHandle, reason: string): Promise<void>;
|
|
104
|
+
killProcessGroup(handle: WorkerHandle, reason: string): Promise<void>;
|
|
105
|
+
resumeSession(sessionId: string): Promise<WorkerHandle>;
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
每个事件还必须包含:
|
|
110
|
+
|
|
111
|
+
- 单调递增 `seq`;
|
|
112
|
+
- `taskId` 和 `workerId`;
|
|
113
|
+
- `idempotencyKey`;
|
|
114
|
+
- `timestamp`;
|
|
115
|
+
- 原始输出 artifact 引用;
|
|
116
|
+
- `exitReason`;
|
|
117
|
+
- `lastHeartbeat`;
|
|
118
|
+
- 工作目录和权限声明。
|
|
119
|
+
|
|
120
|
+
## 4. 分阶段复用策略
|
|
121
|
+
|
|
122
|
+
### Phase 0:本地源码和包审计
|
|
123
|
+
|
|
124
|
+
对每个候选项目记录:
|
|
125
|
+
|
|
126
|
+
- GitHub URL;
|
|
127
|
+
- npm/package 名称;
|
|
128
|
+
- 精确版本和 commit SHA;
|
|
129
|
+
- 安装命令;
|
|
130
|
+
- 导出的 API;
|
|
131
|
+
- `LICENSE` 和 SPDX;
|
|
132
|
+
- 传递依赖;
|
|
133
|
+
- 最近 release/commit;
|
|
134
|
+
- CI 和测试状态;
|
|
135
|
+
- 是否支持当前 Pi 版本;
|
|
136
|
+
- 是否有 Claude 真实运行样例;
|
|
137
|
+
- 退出码、超时、信号和恢复语义。
|
|
138
|
+
|
|
139
|
+
没有完成这些记录,不进入生产依赖。
|
|
140
|
+
|
|
141
|
+
### Phase 1:只验证 Worker transport
|
|
142
|
+
|
|
143
|
+
优先验证 `pi-interactive-shell` 的:
|
|
144
|
+
|
|
145
|
+
- spawn Claude;
|
|
146
|
+
- 实时读取输出;
|
|
147
|
+
- 输入是否丢失;
|
|
148
|
+
- 人工 takeover;
|
|
149
|
+
- SIGTERM/SIGKILL;
|
|
150
|
+
- 窗口尺寸和提示符变化;
|
|
151
|
+
- 长时间无输出;
|
|
152
|
+
- 孤儿进程回收;
|
|
153
|
+
- session resume。
|
|
154
|
+
|
|
155
|
+
如果 PTY 可靠,MVP 复用其 transport;如果 PTY 无法提供稳定、可回放的事件,则切换为 headless JSONL,不在两个 transport 之间做混合控制。
|
|
156
|
+
|
|
157
|
+
### Phase 2:自有 Supervisor 核心
|
|
158
|
+
|
|
159
|
+
以下能力建议自建,原因是它们属于本项目的控制权和审计边界:
|
|
160
|
+
|
|
161
|
+
- Goal schema;
|
|
162
|
+
- 状态机;
|
|
163
|
+
- Policy Gate;
|
|
164
|
+
- 预算和最大轮数;
|
|
165
|
+
- 重复停顿检测;
|
|
166
|
+
- 人工升级;
|
|
167
|
+
- 事件日志;
|
|
168
|
+
- 证据收集;
|
|
169
|
+
- 独立验收;
|
|
170
|
+
- 回滚和 fail-closed。
|
|
171
|
+
|
|
172
|
+
这部分不应依赖某个第三方扩展的隐式行为。
|
|
173
|
+
|
|
174
|
+
### Phase 3:选择性接入 headless 扩展
|
|
175
|
+
|
|
176
|
+
只有在以下条件都满足时,才考虑接入 `pi-claude-code` 或 `pi-harness-delegate`:
|
|
177
|
+
|
|
178
|
+
- 许可证允许目标使用方式;
|
|
179
|
+
- 版本和 commit 已锁定;
|
|
180
|
+
- API 能映射到 Worker Adapter;
|
|
181
|
+
- 不与 Supervisor 重复管理生命周期;
|
|
182
|
+
- 事件和错误语义可记录;
|
|
183
|
+
- session resume 可回放;
|
|
184
|
+
- 故障注入测试通过;
|
|
185
|
+
- 能够随时卸载并回退到基础 Claude CLI adapter。
|
|
186
|
+
|
|
187
|
+
## 5. 生产验证路线
|
|
188
|
+
|
|
189
|
+
### 5.1 PoC 阶段
|
|
190
|
+
|
|
191
|
+
只做一条真实任务闭环:
|
|
192
|
+
|
|
193
|
+
```text
|
|
194
|
+
创建任务
|
|
195
|
+
→ 启动 Claude
|
|
196
|
+
→ 读取输出
|
|
197
|
+
→ 处理普通提问
|
|
198
|
+
→ 人工接管
|
|
199
|
+
→ 恢复执行
|
|
200
|
+
→ 测试
|
|
201
|
+
→ 独立验收
|
|
202
|
+
→ 输出报告
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
必须注入:
|
|
206
|
+
|
|
207
|
+
- 普通确认;
|
|
208
|
+
- 架构二选一;
|
|
209
|
+
- 120 秒无输出;
|
|
210
|
+
- Worker 崩溃;
|
|
211
|
+
- 输入竞争;
|
|
212
|
+
- 重复停顿;
|
|
213
|
+
- 危险命令;
|
|
214
|
+
- 验收失败;
|
|
215
|
+
- Supervisor 重启。
|
|
216
|
+
|
|
217
|
+
### 5.2 MVP 阶段
|
|
218
|
+
|
|
219
|
+
MVP 必须满足:
|
|
220
|
+
|
|
221
|
+
- 单仓库、单 worktree、单 Worker;
|
|
222
|
+
- 低风险动作才可自动继续;
|
|
223
|
+
- 架构和危险动作人工审批;
|
|
224
|
+
- 事件可以完整回放;
|
|
225
|
+
- 人工 takeover 后零自动发送;
|
|
226
|
+
- 验收失败绝不进入 `COMPLETE`;
|
|
227
|
+
- 重复停顿不会无限循环;
|
|
228
|
+
- 进程组不会泄漏;
|
|
229
|
+
- 日志不会泄露密钥;
|
|
230
|
+
- Worker 输出不能改变 Supervisor 安全规则。
|
|
231
|
+
|
|
232
|
+
### 5.3 生产候选阶段
|
|
233
|
+
|
|
234
|
+
生产候选的后续加固项包括:
|
|
235
|
+
|
|
236
|
+
- 依赖 lockfile 和 SBOM;
|
|
237
|
+
- 包来源校验;
|
|
238
|
+
- 可选最小权限和 sandbox;
|
|
239
|
+
- 可选网络白名单;
|
|
240
|
+
- 密钥隔离;
|
|
241
|
+
- 日志脱敏;
|
|
242
|
+
- 成本和时间告警;
|
|
243
|
+
- 灰度 feature flag;
|
|
244
|
+
- 可随时关闭自动化;
|
|
245
|
+
- 故障回滚和人工值守。
|
|
246
|
+
|
|
247
|
+
其中低权限用户、sandbox 和网络白名单不阻塞当前生命周期验证;运行权限由
|
|
248
|
+
调用者明确授权,危险操作仍由 Policy Gate 和人工审批控制。
|
|
249
|
+
|
|
250
|
+
### 5.4 建议 Go / No-Go 门槛
|
|
251
|
+
|
|
252
|
+
必须全部满足才允许生产灰度:
|
|
253
|
+
|
|
254
|
+
- P0 安全用例 100% 通过;
|
|
255
|
+
- 无孤儿 Worker 进程;
|
|
256
|
+
- 无密钥泄露;
|
|
257
|
+
- 人工 takeover 可重复成功;
|
|
258
|
+
- 所有失败场景 fail-closed;
|
|
259
|
+
- 关键事件可完整回放;
|
|
260
|
+
- 验收流水线可独立重跑;
|
|
261
|
+
- 依赖许可证和版本已审计;
|
|
262
|
+
- 通过一组固定任务的成功率、恢复率和费用门槛。
|
|
263
|
+
|
|
264
|
+
未满足生命周期、恢复、审计和独立验收门槛时只能称为 PoC 或生产候选;
|
|
265
|
+
安全加固项未完成时,不应称为安全加固完成或适合无人工值守部署。
|
|
266
|
+
|
|
267
|
+
## 6. 回滚方案
|
|
268
|
+
|
|
269
|
+
任何以下情况发生时,立即停止自动发送并进入 `HUMAN_REQUIRED`:
|
|
270
|
+
|
|
271
|
+
- 状态不一致;
|
|
272
|
+
- 重复发送指令;
|
|
273
|
+
- Policy Gate 解析失败;
|
|
274
|
+
- 验证器不可用;
|
|
275
|
+
- Worker 输出协议变化;
|
|
276
|
+
- 第三方扩展加载失败;
|
|
277
|
+
- 发现权限越界或密钥风险;
|
|
278
|
+
- watchdog 与 Worker 状态矛盾。
|
|
279
|
+
|
|
280
|
+
回滚动作:
|
|
281
|
+
|
|
282
|
+
1. 停止自动控制;
|
|
283
|
+
2. 保留 worktree、事件日志和原始输出;
|
|
284
|
+
3. 终止或交还 Worker 控制权;
|
|
285
|
+
4. 人工接管;
|
|
286
|
+
5. 使用锁定的旧 Adapter 或直接使用 Claude CLI;
|
|
287
|
+
6. 生成故障报告;
|
|
288
|
+
7. 未完成根因分析前,不重新打开自动化开关。
|
|
289
|
+
|
|
290
|
+
第三方包升级必须通过 lockfile、独立 worktree、回放测试和 feature flag 灰度,不能直接替换生产版本。
|
|
291
|
+
|
|
292
|
+
## 7. 对现有 engineering-plan.md 的修改建议
|
|
293
|
+
|
|
294
|
+
现有方案已经具备较好的边界,但建议补充:
|
|
295
|
+
|
|
296
|
+
1. 参考源审计表和许可证门禁;
|
|
297
|
+
2. PTY/headless transport 的明确主备选择;
|
|
298
|
+
3. 唯一控制权和职责归属;
|
|
299
|
+
4. Adapter capability negotiation、幂等、事件序号、进程组终止和 artifact 引用;
|
|
300
|
+
5. 供应链和 SBOM 要求;
|
|
301
|
+
6. prompt injection、symlink 越界、shell escape 和外部文档注入威胁模型;
|
|
302
|
+
7. 输入竞争、孤儿进程、重复事件和恢复测试;
|
|
303
|
+
8. 量化的 Go/No-Go 指标;
|
|
304
|
+
9. 扩展加载失败时的回退路径;
|
|
305
|
+
10. 明确 Stop hook 只是 Worker 内部早停护栏,不是独立验收器。
|
|
306
|
+
|
|
307
|
+
## 8. 最终技术决策建议
|
|
308
|
+
|
|
309
|
+
### 推荐直接复用
|
|
310
|
+
|
|
311
|
+
- Pi 的 extension/package loader 和人工交互机制;
|
|
312
|
+
- Claude Code CLI runtime;
|
|
313
|
+
- 通过 Spike 验证后的 `pi-interactive-shell` PTY 层;
|
|
314
|
+
- Git worktree、OS 进程组控制和项目已有测试命令。
|
|
315
|
+
|
|
316
|
+
### 推荐只借鉴
|
|
317
|
+
|
|
318
|
+
- `pi-goals` 的 Goal / Evidence / Sign-off 数据模型;
|
|
319
|
+
- `pi-foreground-chains` 的有限循环和 reviewer 阶段;
|
|
320
|
+
- Claude Stop hook 的 Worker 内部护栏思路。
|
|
321
|
+
|
|
322
|
+
### 暂不作为核心依赖
|
|
323
|
+
|
|
324
|
+
- 未审计的 `pi-claude-code`;
|
|
325
|
+
- 未审计的 `pi-harness-delegate`;
|
|
326
|
+
- 同时拥有 spawn、watchdog、resume、stop 权限的多个扩展;
|
|
327
|
+
- Reviewer 直接修改工作树;
|
|
328
|
+
- 自动 merge、deploy、release。
|
|
329
|
+
|
|
330
|
+
## 9. 给 W 的一句话结论
|
|
331
|
+
|
|
332
|
+
> 不要从零重写 Claude 控制层,也不要把多个扩展直接叠加。先验证并复用一个可靠的 Worker transport,再自建最薄的 Adapter、策略、状态机和独立验收层;所有候选包经过版本、许可证、API、故障和安全验证后,才允许进入生产灰度。
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# Releasing
|
|
2
|
+
|
|
3
|
+
## Pull request gate
|
|
4
|
+
|
|
5
|
+
All changes must enter `main` through a pull request. Use a Conventional Commit
|
|
6
|
+
PR title, for example:
|
|
7
|
+
|
|
8
|
+
```text
|
|
9
|
+
feat: persist Decision Worker sessions
|
|
10
|
+
fix: close orphaned workers during shutdown
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
The required `CI / Quality gate` aggregates every prerequisite. It fails when
|
|
14
|
+
any job fails, is cancelled, or is skipped:
|
|
15
|
+
|
|
16
|
+
- Node 22.19.0 and Node 24 checks;
|
|
17
|
+
- npm 10 and npm 12 compatibility checks;
|
|
18
|
+
- TypeScript, unit tests, package checks and documentation checks;
|
|
19
|
+
- Pi smoke and native package-install tests;
|
|
20
|
+
- npm audit at high severity;
|
|
21
|
+
- deterministic package artifact build with SHA-256 and npm integrity metadata.
|
|
22
|
+
|
|
23
|
+
Configure branch protection for `main` with:
|
|
24
|
+
|
|
25
|
+
- pull request required;
|
|
26
|
+
- `CI / Quality gate` required and up to date;
|
|
27
|
+
- conversation resolution required;
|
|
28
|
+
- force pushes and branch deletion disabled.
|
|
29
|
+
|
|
30
|
+
The workflow does not auto-merge arbitrary pull requests.
|
|
31
|
+
|
|
32
|
+
## Local release checks
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm ci --ignore-scripts --include=dev
|
|
36
|
+
npm run check
|
|
37
|
+
npm run test:pi
|
|
38
|
+
npm run test:install
|
|
39
|
+
npm run build
|
|
40
|
+
npm audit --audit-level=high
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
`npm run build` writes exactly these files to `dist/`:
|
|
44
|
+
|
|
45
|
+
```text
|
|
46
|
+
pi-claude-supervisor-X.Y.Z.tgz
|
|
47
|
+
release-manifest.json
|
|
48
|
+
SHA256SUMS
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
The manifest binds the archive to the exact source commit, SHA-256 digest and
|
|
52
|
+
npm SHA-512 integrity value. Never manually replace an artifact after CI builds
|
|
53
|
+
it.
|
|
54
|
+
|
|
55
|
+
## Versioning and automatic publication
|
|
56
|
+
|
|
57
|
+
The `Release` workflow runs on `main` and uses Release Please:
|
|
58
|
+
|
|
59
|
+
1. Release Please opens or updates a release PR from Conventional Commits.
|
|
60
|
+
2. A maintainer reviews and merges the release PR.
|
|
61
|
+
3. Release Please creates a stable `vX.Y.Z` Git tag and GitHub Release.
|
|
62
|
+
4. The workflow runs the full reusable CI against the exact tag commit.
|
|
63
|
+
5. Only after verification succeeds does the `npm` environment publish the
|
|
64
|
+
verified archive with `npm publish --provenance`.
|
|
65
|
+
6. The archive, manifest and checksum file are attached to the GitHub Release.
|
|
66
|
+
|
|
67
|
+
A failed publication must be retried from the original release workflow. Do not
|
|
68
|
+
move tags, overwrite versions, or rebuild a different artifact to bypass a
|
|
69
|
+
failed verification.
|
|
70
|
+
|
|
71
|
+
## npm authentication
|
|
72
|
+
|
|
73
|
+
Preferred mode is npm trusted publishing (OIDC):
|
|
74
|
+
|
|
75
|
+
- configure `btnalit/pi-claude-supervisor` and `.github/workflows/release.yml`
|
|
76
|
+
as a trusted publisher in npm;
|
|
77
|
+
- configure the GitHub environment named `npm`;
|
|
78
|
+
- set repository/environment variable `NPM_AUTH_MODE=oidc`;
|
|
79
|
+
- grant only the publish job `id-token: write`.
|
|
80
|
+
|
|
81
|
+
Temporary fallback mode uses the GitHub environment secret `NPM_TOKEN` and
|
|
82
|
+
variable `NPM_AUTH_MODE=token`. The token must be package-scoped, short-lived
|
|
83
|
+
and rotated. It is never committed or copied into workflow source.
|
|
84
|
+
|
|
85
|
+
For local/manual recovery only, the machine-held credential is stored in:
|
|
86
|
+
|
|
87
|
+
```text
|
|
88
|
+
/home/yancao/.config/key.conf
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Keep that file at mode `0600`. It must not be copied into the repository,
|
|
92
|
+
GitHub Actions variables, npm package contents, logs or pull requests. Local
|
|
93
|
+
publication should use a temporary `npm_config_userconfig` file and remove it
|
|
94
|
+
immediately after the command.
|
|
95
|
+
|
|
96
|
+
## Dependency and workflow updates
|
|
97
|
+
|
|
98
|
+
Dependabot is configured for both npm dependencies and GitHub Actions. Minor and
|
|
99
|
+
patch updates are grouped; every update must pass the same CI quality gate.
|
|
100
|
+
Major updates remain separate for explicit review. There is no blanket auto-merge.
|
|
101
|
+
|
|
102
|
+
## Manual retry
|
|
103
|
+
|
|
104
|
+
A maintainer can retry an existing stable release from Actions:
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
gh workflow run release.yml --ref main -f tag=v0.1.1
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
The workflow verifies that the release tag is stable and belongs to `main`, then
|
|
111
|
+
reruns CI before publication. A tag or GitHub Release alone is not evidence that
|
|
112
|
+
npm publication succeeded; verify the npm registry separately.
|
package/docs/testing.md
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Testing
|
|
2
|
+
|
|
3
|
+
## Local checks
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm ci --ignore-scripts --include=dev
|
|
7
|
+
npm run check
|
|
8
|
+
npm run test:pi
|
|
9
|
+
npm run test:install
|
|
10
|
+
npm audit --audit-level=high
|
|
11
|
+
npm run build
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
`npm run check` performs strict TypeScript checking, Node tests, and npm package
|
|
15
|
+
content assertions. `npm run build` creates an installable npm archive; Pi loads
|
|
16
|
+
the published TypeScript source directly and there is no second runtime bundle.
|
|
17
|
+
|
|
18
|
+
## Test layers
|
|
19
|
+
|
|
20
|
+
- `policy.test.ts`: deterministic allow/review/deny behavior.
|
|
21
|
+
- `state.test.ts`: legal and illegal lifecycle transitions.
|
|
22
|
+
- `events.test.ts`: ordered JSONL persistence, sequence recovery and credential-shaped redaction.
|
|
23
|
+
- `decision-session-store.test.ts`: atomic Decision Worker task mapping, permissions, restart discovery and corrupt-record isolation.
|
|
24
|
+
- `index.test.ts`: command-level cwd reservation/reuse and session-shutdown
|
|
25
|
+
cleanup for a real child process.
|
|
26
|
+
- `supervisor.test.ts`: a real local child process must reach `verifying` and
|
|
27
|
+
require a separate successful verification command before `completed`.
|
|
28
|
+
- `worker/process-adapter.test.ts`: spawn failure is observable, JSONL framing and
|
|
29
|
+
idempotent duplicate suppression work, and a child does not remain indefinitely
|
|
30
|
+
in a running state.
|
|
31
|
+
- `worker/environment.test.ts`: unrelated host credentials are excluded unless
|
|
32
|
+
explicitly supplied.
|
|
33
|
+
- `supervisor.test.ts`: the no-output watchdog stops a stalled worker, lifecycle event failures are retried, and output is restored when event persistence fails.
|
|
34
|
+
- `scripts/check-package.mjs`: verifies the Pi manifest, peer dependency policy,
|
|
35
|
+
required files and forbidden secret paths.
|
|
36
|
+
|
|
37
|
+
## Transport spike acceptance
|
|
38
|
+
|
|
39
|
+
Run `npm run spike:transport` only in an isolated test workspace after the test
|
|
40
|
+
account is authenticated with Claude Code. The script uses `spawn` with
|
|
41
|
+
`shell: false`, disables session persistence, restricts tools, sends one fixed
|
|
42
|
+
non-sensitive prompt, and prints protocol metadata rather than raw model output.
|
|
43
|
+
It must not be added to the normal CI gate because authentication is an owner
|
|
44
|
+
controlled prerequisite.
|
|
45
|
+
|
|
46
|
+
The current fixtures validate one prompt, multiple turns, session resume,
|
|
47
|
+
permission allow/deny and SIGTERM/SIGINT behavior with Claude Code 2.1.268.
|
|
48
|
+
The adapter regression suite also verifies event subscription, parsed
|
|
49
|
+
`permission_request` events, and the exact nested `control_response` envelope.
|
|
50
|
+
The automation spike additionally exercises a real Pi SDK Decision Worker with
|
|
51
|
+
Claude: ordinary completion, harmless Bash permission approval, and an
|
|
52
|
+
`AskUserQuestion` denial-to-text fallback followed by automatic verification.
|
|
53
|
+
The extension persists each automatic Decision Worker session as Pi JSONL plus a
|
|
54
|
+
0600 task mapping. Recovery is explicit and safe: after an unclean Pi restart,
|
|
55
|
+
`/supervise sessions` shows the task as `recoverable`, and `/supervise recover
|
|
56
|
+
<task-id>` restores the Decision Worker history before starting a new Claude
|
|
57
|
+
Worker.
|
|
58
|
+
Run the permission and signal probes explicitly when validating a CLI release:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
npm run spike:permissions
|
|
62
|
+
SPIKE_PERMISSION_DECISION=deny npm run spike:permissions
|
|
63
|
+
npm run spike:signals
|
|
64
|
+
npm run spike:automation
|
|
65
|
+
SPIKE_AUTOMATION_PERMISSION=1 npm run spike:automation
|
|
66
|
+
SPIKE_AUTOMATION_QUESTION=1 npm run spike:automation
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
For this release, pin and record Claude Code `2.1.268` and its resolved
|
|
70
|
+
executable path. Record:
|
|
71
|
+
|
|
72
|
+
1. exact version and resolved executable path;
|
|
73
|
+
2. license and source revision;
|
|
74
|
+
3. startup, prompt delivery and output framing;
|
|
75
|
+
4. stop, process-group cleanup and crash behavior;
|
|
76
|
+
5. timeout, duplicate-message and recovery behavior;
|
|
77
|
+
6. human takeover and session-resume semantics;
|
|
78
|
+
7. no secret leakage in event logs or npm archives.
|
|
79
|
+
|
|
80
|
+
A passing worker task is not sufficient. The independent verifier must repeat the
|
|
81
|
+
relevant checks from a clean host perspective.
|
|
82
|
+
|
|
83
|
+
Automatic mode is enabled with `PI_CLAUDE_SUPERVISOR_MODE=auto`; it forces JSONL
|
|
84
|
+
and routes `result`, permission, and process-exit events to the persistent Pi
|
|
85
|
+
Decision Worker. `process-pipe` remains the manual compatibility mode. Human
|
|
86
|
+
escalation is outbound-only through `PI_CLAUDE_SUPERVISOR_HUMAN_WEBHOOK_URL`;
|
|
87
|
+
approval callbacks are deliberately not accepted without a separately
|
|
88
|
+
authenticated endpoint.
|
|
89
|
+
|
|
90
|
+
## Failure injection
|
|
91
|
+
|
|
92
|
+
The automated adapter matrix covers external `SIGTERM`, `SIGINT`, `SIGKILL`,
|
|
93
|
+
`SIGSTOP`/`SIGCONT`, SIGTERM refusal/escalation, leader-early-exit descendant
|
|
94
|
+
cleanup, required cgroup cleanup of a `setsid()` descendant, repeated stop,
|
|
95
|
+
spawn failure, output truncation, blocked stdin write timeouts, and immediate
|
|
96
|
+
JSONL results. The Supervisor matrix also covers
|
|
97
|
+
retrying failed lifecycle events, preserving startup event order, stopping under
|
|
98
|
+
persistent timeout-event failure, and restoring output after event-log failure. The Supervisor matrix covers startup rejection, externally terminated
|
|
99
|
+
workers, lifecycle serialization and stop races.
|
|
100
|
+
|
|
101
|
+
Before release, manually test at least: immediate crash, hung process, malformed
|
|
102
|
+
output, duplicate send, send/exit race, Pi `SIGTERM`/`SIGINT` shutdown,
|
|
103
|
+
verification failure, blocked stdin writes/stop preemption, corrupt event-log
|
|
104
|
+
tails, and descendants that call `setsid()` when cgroup mode is unavailable (expected
|
|
105
|
+
fallback limitation). The cgroup test proves cleanup after attachment but does
|
|
106
|
+
not eliminate the post-spawn attachment window. `SIGSTOP` and `SIGKILL` of the Pi host cannot be handled;
|
|
107
|
+
verify and document the resulting orphan behavior.
|
|
108
|
+
Default behavior must be fail-closed and leave no orphaned worker process within
|
|
109
|
+
the managed process group.
|