pi-claude-supervisor 0.5.2 → 0.5.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,13 @@
2
2
 
3
3
  All notable changes to this project will be documented here.
4
4
 
5
+ ## [0.5.3](https://github.com/btnalit/pi-claude-supervisor/compare/v0.5.2...v0.5.3) (2026-09-15)
6
+
7
+
8
+ ### Bug Fixes
9
+
10
+ * harden unattended local lifecycle ([#27](https://github.com/btnalit/pi-claude-supervisor/issues/27)) ([2bb29d3](https://github.com/btnalit/pi-claude-supervisor/commit/2bb29d3c31f5196f208716723d89b6b538777939))
11
+
5
12
  ## [0.5.2](https://github.com/btnalit/pi-claude-supervisor/compare/v0.5.1...v0.5.2) (2026-09-14)
6
13
 
7
14
 
@@ -32,10 +39,14 @@ All notable changes to this project will be documented here.
32
39
  - Pause and rebase the no-output watchdog clock across pause/resume while retaining the cumulative deadline.
33
40
  - Include staged, unstaged and bounded untracked evidence in independent Review, with symlink/path safety and fail-closed completeness.
34
41
  - Harden assistant-message output framing, startup/runtime preflight, permission gates, bounded acceptance buffers and lifecycle progress reporting.
42
+ - Close automatic startup baseline/worktree/branch validation gaps, including persisted recovery baselines and the final pre-spawn boundary recheck.
43
+ - Replace shell-policy lexical bypasses with quote-aware parsing, nested-shell inspection and protected Git-ref checks; deny dynamic shell expansions while preserving literal argv values, and reject arbitrary non-Claude automatic executables.
44
+ - Normalize malformed custom Reviewer values to blocking reports, persist recovery baselines and the resolved Claude executable identity, filter automatic environment variables with a deny-by-default allowlist, and compare the exact startup HEAD at the adapter spawn boundary.
45
+ - Keep protected CI checks on the exact checked-out commit while giving automatic-mode fixtures a local validation branch and an owned deterministic Claude executable.
35
46
 
36
47
  ### Remaining hardening gate
37
48
 
38
- - Complete the exact-head independent read-only Review; the real editable Claude `2.1.270` repair/reacceptance drill and cleanup/lease evidence are recorded in `docs/automation-hardening-plan.md`.
49
+ - Open the protected pull request and complete independent CI/integration review; the exact-head read-only review, real editable Claude `2.1.270` repair/reacceptance drill and cleanup/lease evidence are recorded in `docs/automation-hardening-plan.md`.
39
50
 
40
51
  ### Added
41
52
 
package/README.cn.md CHANGED
@@ -8,24 +8,31 @@
8
8
 
9
9
  用于 Pi 的 Claude Code Worker 监督扩展。MVP 中 Pi 负责生命周期、状态机、策略门和独立验收;Worker 只是被显式启动的子进程。
10
10
 
11
- > `v0.5.1` 已发布为单 Worker recovery 基线。默认手动 transport 是无额外依赖的
12
- > process pipe,不是 PTY;自动模式只使用 Claude JSONL 或 tmux。当前工作树已实现
11
+ > `v0.5.2` 已发布为单 Worker recovery 基线。默认手动 transport 是无额外依赖的
12
+ > process pipe,不是 PTY;自动模式只使用 Claude JSONL,tmux 保留为手动交互。当前工作树已实现
13
13
  > repairable/persistent 能力拆分、可取消验收/Reviewer、证据完整性门禁、启动前
14
14
  > preflight 和阶段进度通知;真实 Claude Code `2.1.270` 允许编辑的
15
- > repair/reacceptance 演练已在隔离临时 worktree 通过,剩余发布门禁是 exact-head
16
- > 独立只读 Review。低权限用户、OS sandbox 与网络隔离继续延期。
15
+ > repair/reacceptance 演练已在隔离临时 worktree 通过。确认的产品目标是本地开发
16
+ > 完全无人值守;详见 [自动化目标](docs/autonomy-target.md)。代码进入远程仓库或
17
+ > main/integration 分支必须经过独立边界,Worker 不拥有 push/merge 权限;自动模式仅使用
18
+ > JSONL,tmux 保留为手动交互 transport。
19
+ >
20
+ > **无人值守状态:** 自动模式会自主完成本地修改、测试、有限修复、验收、独立 Review
21
+ > 和本地提交检查;无法形成候选时自动挂起为不可发布候选。可选出站通知不授予权限,
22
+ > push 和 main/integration merge 仍必须经过独立边界。
17
23
 
18
24
  ## 关键安全边界
19
25
 
20
26
  - 不会在扩展加载时自动启动 Worker。
21
27
  - 不经过 shell 启动子进程。
22
- - Worker 只继承最小环境;凭据必须由调用方显式传入。
23
- - 破坏性命令和绕过权限的 Worker 参数默认拒绝;需要复核的启动命令会请求用户批准,不会一律拒绝。
28
+ - Worker 只继承最小环境;自动模式采用默认拒绝的环境变量 allowlist,过滤远程凭据并禁用 Git/包管理器 credential helper。自动模式只能选择文档列出的 Claude provider 变量;任意自定义变量仅限手动集成。
29
+ - 本地命令和权限行为按任务/运行时授权策略处理;超出授权的动作自动拒绝或挂起,不要求同步人工响应。
24
30
  - Linux 上优先使用可写的 cgroup v2 清理后代进程,包括 `setsid()` 后代;不可用时回退到进程组清理。需要强制失败闭环时,embedding 集成可使用 `cgroupMode: "required"`,并会在 Claude 启动前执行 preflight。
25
- - 普通联网查询不因联网本身被拒绝;下载后直接交给 shell 等高风险模式仍需人工复核。
31
+ - 自动模式只接受裸的 `claude`/`claude.exe` 命令名,并从 Supervisor 的 PATH 解析、固定由操作者拥有的可执行文件(或使用 `PI_CLAUDE_SUPERVISOR_TRUSTED_CLAUDE` 固定路径);显式路径和可写/不可信位置会被拒绝。它请求 fail-closed 的 Claude Code Bash sandbox,禁止 Bash 子进程出站联网;命令策略仍是第二道门。手动/自定义集成必须自行提供等效 host/network 边界。
26
32
  - Worker 声称完成只会进入 `verifying`,不能作为成功证据。
27
33
  - 默认独立验收命令为 `git diff --check`。
28
- - 扩展运行时不执行 merge、deploy、release 或 publish;仓库 Release 只会在维护者合并 Release Please PR 且 CI 门禁全部通过后自动发布。
34
+ - 目标是任务启动后本地开发无人值守:Worker 可以修改、测试、修复和本地提交;Worker 必须没有远程 push 或合并到 `main`/integration 分支的权限。
35
+ - 扩展运行时不执行 merge、deploy、release 或 publish;远程/main 集成和仓库 Release 必须经过独立受保护边界。
29
36
  - 默认 4 小时总时限、20 分钟无输出 watchdog 超时即停止 Worker;paused 期间不消耗无输出预算,resume 会重建基准但不会重置总时限。嵌入调用方可将对应选项设为 `0` 关闭。
30
37
  - 验收命令、仓库证据收集和独立 Reviewer 共用 abort signal,人工 stop/shutdown 不必等待完整超时。
31
38
 
@@ -42,14 +49,14 @@ pi install npm:pi-claude-supervisor
42
49
  ```bash
43
50
  export PI_CLAUDE_SUPERVISOR_MODE=auto
44
51
  export PI_CLAUDE_SUPERVISOR_WORKER='claude --safe-mode --tools Bash'
45
- # 可选:人工升级通知;generic 或 wecom
52
+ # 可选:候选/失败通知;generic 或 wecom
46
53
  export PI_CLAUDE_SUPERVISOR_HUMAN_WEBHOOK_URL='https://example.invalid/webhook'
47
54
  export PI_CLAUDE_SUPERVISOR_HUMAN_WEBHOOK_FORMAT=generic
48
55
  # export PI_CLAUDE_SUPERVISOR_HUMAN_WEBHOOK_SECRET='shared-secret'
49
56
  ```
50
57
 
51
- 自动模式默认使用 `claude-jsonl`,通过 `result`、`control_request` 和进程
52
- `exit` 事件唤醒 Decision Worker;显式选择 tmux 时仍使用屏幕交互,不使用 JSONL 权限协议,也不会依赖 `/supervise poll` 轮询。本版本固定按已验证设备的
58
+ 自动模式默认并且只能使用 `claude-jsonl`,通过 `result`、`control_request` 和进程
59
+ `exit` 事件唤醒 Decision Worker;tmux 仅用于手动屏幕交互,不使用 JSONL 权限协议,也不会依赖 `/supervise poll` 轮询。本版本固定按已验证设备的
53
60
  Claude CLI `2.1.270` 运行,跨版本兼容性不在本轮范围内。
54
61
 
55
62
  然后在 Pi 中使用:
@@ -79,44 +86,47 @@ Claude CLI `2.1.270` 运行,跨版本兼容性不在本轮范围内。
79
86
  "acceptance": [
80
87
  { "id": "tests", "name": "tests", "command": "npm", "args": ["test"], "required": true }
81
88
  ],
82
- "maxRepairRounds": 3
89
+ "maxRepairRounds": 3,
90
+ "autonomy": {
91
+ "unattended": true,
92
+ "requireLocalCommit": true,
93
+ "maxDecisionRetries": 2
94
+ }
83
95
  }
84
96
  ```
85
97
 
86
- 人工升级通知的 generic JSON 格式为:
98
+ 候选/失败通知的 generic JSON 格式为(旧 human-intervention webhook 名称保持兼容):
87
99
 
88
100
  ```json
89
101
  {
90
- "schema": "pi-claude-supervisor/human-intervention/v1",
91
- "event": "human_intervention_required",
102
+ "schema": "pi-claude-supervisor/candidate/v1",
103
+ "event": "candidate_status",
92
104
  "task": { "id": "...", "goal": "...", "cwd": "..." },
93
105
  "worker": { "id": "..." },
94
106
  "reason": "...",
95
- "question": "...",
96
- "permission": { "requestId": "...", "toolUseId": "...", "toolName": "Bash", "input": {} },
97
- "actions": ["approve_or_deny_permission", "send_instruction", "stop_worker", "takeover"]
107
+ "status": "ready|blocked|failed",
108
+ "deliverable": false,
109
+ "note": "This notification does not grant remote push or main/integration merge permission."
98
110
  }
99
111
  ```
100
112
 
101
- 当前 webhook 是出站通知,不直接接受批准命令;批准或接管仍通过 Pi。
113
+ 当前 webhook 只是出站候选通知,不直接接受批准命令;显式 stop、takeover 等兼容控制仍通过 Pi。
102
114
  自动模式会将 Decision Worker 会话持久化到状态目录。Pi 非正常重启后,`/supervise sessions`
103
115
  会显示 `recoverable` 任务;显式执行 `/supervise recover [--takeover] <task-id>` 会恢复 Decision Worker 上下文并
104
116
  重新启动 Claude Worker,不会静默恢复或重复执行任务。旧 Pi 进程已退出且租约确认旧 Worker
105
117
  进程组已消失且 cgroup 仍是真实、可读取的空边界时,才可显式添加 `--takeover`;缺失、仍存活或无法确认的 Worker 会被拒绝。持久 tmux
106
118
  Worker 应使用 `adopt-tmux`,而不是 takeover。
107
- 自动模式下,Decision Worker 可以安全拒绝 `AskUserQuestion`,让 Claude 将问题转成普通文本,
108
- 再根据任务和仓库证据自动回答;无法确定时才升级人工。如需微信内闭环,需要另建带签名验证、
109
- 一次性 action token 和重放保护的入站 callback 服务。
119
+ 自动模式下,Decision Worker 在任务授权范围内自动处理普通问题、测试失败和修复轮次,记录假设和证据;无法形成可交付候选时自动挂起并保留证据,而不是要求人工必须在线。可通过 `PI_CLAUDE_SUPERVISOR_REQUIRE_LOCAL_COMMIT=0` 或 task `autonomy.requireLocalCommit` 关闭本地 commit 要求,但自动模式仍要求有效 Git baseline 和非保护 worktree;远程 push 和 main/integration merge 仍由独立边界控制。
110
120
 
111
121
  `v0.5.0` 已完成并发布“多命令验收—独立只读 Reviewer—结构化修复轮次—再次验收”闭环。
112
- 任务可通过 API 或 JSON spec 提供 `goal`、`scope`、`constraints`、`forbidden` 和多个
113
- `acceptance` 命令;旧的纯文本任务继续使用默认 `git diff --check`。Reviewer 只能使用
114
- `read`、`grep`、`find`、`ls`,不会修改工作树或批准权限。当前加固要求 HEAD-relative
115
- tracked diff 和受限 untracked evidence 完整,P0/P1 或重复 finding 必须人工处理;自动模式
116
- 拒绝显式 process-pipe,并在模型执行前检查目录、可执行文件、依赖和 cgroup。剩余门禁是
117
- 固定 Claude Code `2.1.270` 隔离 worktree 的真实 repair/reacceptance 已通过,当前只剩
118
- exact-head 独立只读 Review;协同多 Worker 属于后续独立开发阶段,暂不把 sandbox、低权限
119
- 和网络隔离作为本阶段门禁。
122
+ 任务可通过 API 或 JSON spec 提供 `goal`、`scope`、`constraints`、`forbidden`、多个
123
+ `acceptance` 命令和 `autonomy` 控制;旧的纯文本任务继续使用默认 `git diff --check`。
124
+ Reviewer 只能使用 `read`、`grep`、`find`、`ls`,不会修改工作树或批准权限。自动模式在
125
+ Worker 启动前捕获 git baseline,要求完整的 baseline-relative tracked/commit/untracked evidence,
126
+ 并在默认情况下要求 Worker 在非保护分支本地 commit;无效输出、证据不完整、重复 finding、P0/P1 或预算耗尽
127
+ 会自动挂起候选。自动模式拒绝 process-pipe 和 tmux,并在模型执行前检查目录、可执行文件、依赖
128
+ 和 cgroup;Worker 环境会过滤远程仓库凭据并禁用 Git 全局凭据 helper。详见 [自动化目标](docs/autonomy-target.md)。协同多 Worker 属于后续独立开发阶段,
129
+ 自动模式只接受裸的直接 Claude 命令名,会固定解析后的操作者拥有的可执行文件,并请求 fail-closed 的 Claude Code Bash sandbox;任意自定义可执行文件和显式可执行路径会在自动模式拒绝。需要固定路径时设置 `PI_CLAUDE_SUPERVISOR_TRUSTED_CLAUDE`。手动/自定义 Worker 的完整 host-level sandbox 仍需由集成方提供。
120
130
 
121
131
  ### tmux/PTY 交互模式
122
132
 
@@ -125,8 +135,7 @@ exact-head 独立只读 Review;协同多 Worker 属于后续独立开发阶段
125
135
  ```bash
126
136
  export PI_CLAUDE_SUPERVISOR_TRANSPORT=tmux
127
137
  export PI_CLAUDE_SUPERVISOR_WORKER='claude --permission-mode plan'
128
- # 可选自动 Decision Worker(默认仍是人工模式):
129
- # export PI_CLAUDE_SUPERVISOR_MODE=auto
138
+ # tmux 仅为手动交互;无人值守 Decision Worker 必须使用 JSONL。
130
139
  # 接管非默认 tmux server 时可选:
131
140
  # export PI_CLAUDE_SUPERVISOR_TMUX_SOCKET=/path/to/tmux.sock
132
141
  ```
@@ -134,7 +143,8 @@ export PI_CLAUDE_SUPERVISOR_WORKER='claude --permission-mode plan'
134
143
  `/supervise start <task>` 会在私有 tmux server 中启动 Claude,并返回可复制的 attach 命令。
135
144
  可以在另一个终端 attach 到同一个 PTY,观察或人工输入。多行消息通过 tmux buffer 和 Enter
136
145
  发送,不会把消息拼接进 shell 命令;`pipe-pane` 记录原始输出,`capture-pane` 检测稳定的 Claude
137
- 输入提示,并复用 watchdog、Decision Worker、审计和独立验收流程。
146
+ 输入提示,并复用 watchdog、审计和独立验收流程;由于 tmux 没有结构化权限边界,
147
+ 不会在 tmux 中启用自动 Decision Worker 或无人值守远程边界策略。
138
148
 
139
149
  如果 Claude 已由你在 tmux 中启动,可以显式接管且不会重放原始任务:
140
150
 
@@ -149,8 +159,7 @@ export PI_CLAUDE_SUPERVISOR_WORKER='claude --permission-mode plan'
149
159
  `tmux kill-session`。`/supervise takeover <task-id>` 会暂停 Decision Worker 自动发送,只有
150
160
  `/supervise resume-auto <task-id>` 才恢复。
151
161
 
152
- PTY 屏幕文字不是 Claude JSONL。权限/信任对话框和无法确定的 TUI 状态必须升级人工,不能把
153
- 屏幕文字当作结构化权限证据。普通终端里已经运行的 Claude 不能安全迁移进 tmux;`--resume`
162
+ PTY 屏幕文字不是 Claude JSONL,不能把屏幕文字当作结构化权限证据。TUI 决策应按任务授权策略处理并记录;无法形成候选时可以自动挂起,不要求人工持续在线。普通终端里已经运行的 Claude 不能安全迁移进 tmux;`--resume`
154
163
  是读取历史的新进程,不是实时 attach。实时测试请使用 plan/read-only 参数。
155
164
 
156
165
  可以从不同工作目录启动多个任务会话;活动会话不能共享同一 cwd,建议每个任务使用独立 worktree:
@@ -169,4 +178,4 @@ PTY 屏幕文字不是 Claude JSONL。权限/信任对话框和无法确定的 T
169
178
 
170
179
  Pull Request 必须通过聚合的 `CI / Quality gate`。Release Please 根据 Conventional Commits 创建版本 PR;维护者合并后,Release workflow 会针对精确 tag commit 重新验证,并通过受保护的 `npm` environment 使用 npm provenance 发布。
171
180
 
172
- 详细内容见 [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)。
181
+ 详细内容见 [engineering-plan.md](docs/engineering-plan.md)、[autonomy-target.md](docs/autonomy-target.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
@@ -10,26 +10,33 @@ A policy-gated [Pi](https://pi.dev) extension for supervising a Claude Code work
10
10
  The MVP keeps Pi in control of lifecycle, state, policy and verification while the
11
11
  worker remains an explicitly started child process.
12
12
 
13
- > **Release status:** `v0.5.1` is the released single-Worker recovery baseline. The
13
+ > **Release status:** `v0.5.2` is the released single-Worker recovery baseline. The
14
14
  > default manual transport is dependency-free process pipes, not PTY. Automatic
15
- > supervision uses Claude JSONL or tmux, and the current working-tree hardening
16
- > adds repairable-vs-persistent capabilities, cancellable verification, evidence
17
- > completeness gates, startup preflight and phase progress reporting. A real
18
- > edit-capable Claude Code `2.1.270` repair/reacceptance drill has passed in an
19
- > isolated temporary worktree; the exact-head independent review is the remaining
20
- > release gate. OS sandbox, low-privilege execution and network isolation remain
21
- > deferred.
15
+ > supervision uses Claude JSONL only; tmux is manual-only because it has no structured
16
+ > permission boundary. Repairable-vs-persistent capabilities,
17
+ > cancellable verification, evidence completeness gates, startup preflight and phase
18
+ > progress reporting. A real edit-capable Claude Code `2.1.270` repair/reacceptance
19
+ > drill passed in an isolated temporary worktree. The confirmed product target is
20
+ > unattended local development; see [the autonomy target](docs/autonomy-target.md).
21
+ > Remote push and merge into the main/integration branch remain outside Worker authority
22
+ > and must cross an independent boundary.
23
+ >
24
+ > **Autonomy status:** automatic mode continues local editing, testing, bounded repair,
25
+ > acceptance, independent Review and local-commit enforcement without a synchronous human
26
+ > callback. Unresolvable work is parked as a non-publishable candidate; optional outbound
27
+ > notifications do not approve actions.
22
28
 
23
29
  ## Safety boundary
24
30
 
25
31
  - The extension never starts a worker automatically.
26
32
  - Worker commands are launched without a shell.
27
- - Workers receive a minimal environment; credentials must be explicitly supplied by the caller.
28
- - Destructive command patterns and permission-bypass worker flags are denied; review-level patterns request explicit user approval instead of being blanket-denied.
29
- - Ordinary network use is not denied merely because it is network use; download-to-shell patterns still require review.
33
+ - Workers receive a minimal environment; automatic mode uses a deny-by-default variable allowlist, strips remote credentials and disables Git/package credential helpers. Only documented Claude provider variables may be selected for automatic mode; arbitrary custom variables remain manual-only.
34
+ - Local command and permission behavior follows the configured task/runtime policy; actions outside that authority are rejected or parked without requiring a synchronous human response.
35
+ - Automatic mode admits only the bare `claude`/`claude.exe` command name, resolves and pins an operator-owned executable from the supervisor PATH (or `PI_CLAUDE_SUPERVISOR_TRUSTED_CLAUDE`), and rejects explicit paths or writable/untrusted locations. It requests a fail-closed Claude Code Bash sandbox with no outbound domains; command policy remains a second guard. Manual/custom integrations must provide their own equivalent host/network boundary.
30
36
  - A worker completion is only a transition to `verifying`; it is not evidence of success.
31
37
  - Verification is an independent host command (default: `git diff --check`).
32
- - The extension never performs merge, deploy, release, or publish at runtime. Repository releases are automated only after a maintainer merges a Release Please PR and the full CI gate passes.
38
+ - Target local development runs unattended after a task starts: the Worker may edit, test, repair and commit locally. The Worker must have no authority or credentials to push remotely or merge into `main`/an integration branch.
39
+ - The extension never performs merge, deploy, release, or publish at runtime. Remote/main integration and repository releases cross independent protected boundaries.
33
40
  - A 4-hour wall-clock and 20-minute no-output watchdog stop a worker by default for long development tasks; embedding callers can set either to `0` to disable.
34
41
  - On Linux, the adapter automatically uses a writable cgroup v2 for descendant cleanup, including `setsid()` descendants; it falls back to process-group cleanup when unavailable. Use `cgroupMode: "required"` for a fail-closed integration; required mode is preflighted before Claude starts.
35
42
  - Acceptance commands, repository evidence collection and independent Review share an abort signal, so operator stop/shutdown does not wait for a full command or model timeout.
@@ -86,7 +93,12 @@ a shell), for example:
86
93
  "acceptance": [
87
94
  { "id": "tests", "name": "tests", "command": "npm", "args": ["test"], "required": true }
88
95
  ],
89
- "maxRepairRounds": 3
96
+ "maxRepairRounds": 3,
97
+ "autonomy": {
98
+ "unattended": true,
99
+ "requireLocalCommit": true,
100
+ "maxDecisionRetries": 2
101
+ }
90
102
  }
91
103
  ```
92
104
 
@@ -109,25 +121,37 @@ worktrees; same-directory starts are rejected even when concurrent, and
109
121
  parallelism, not coordinated multi-worker collaboration. A future multi-worker
110
122
  milestone will add explicit parent/child task graphs, dependencies, bounded
111
123
  scheduling, structured handoffs, aggregate acceptance and graph-aware recovery;
112
- it will not relax the one-writer-per-worktree rule or enable automatic
113
- merge/publish. Unattended use still requires the remaining lifecycle, signal and
114
- recovery checks. Host permissions and network access follow explicit caller
115
- authorization and host policy; there is no automatic merge, deploy, release or
116
- publish.
124
+ it will not grant any Worker remote push or main/integration merge authority.
125
+ Unattended local development is the target operating mode; a blocked or failed
126
+ candidate is parked with its evidence rather than made dependent on a human being
127
+ online. Automatic mode accepts only the bare direct Claude command name, pins its
128
+ operator-owned resolved executable path, and uses a fail-closed Bash sandbox with no
129
+ outbound domains; arbitrary custom executables and explicit executable paths are rejected
130
+ in automatic mode. Set `PI_CLAUDE_SUPERVISOR_TRUSTED_CLAUDE` when the resolved path must
131
+ be pinned explicitly. Manual/custom integrations must provide an equivalent host/network
132
+ boundary.
133
+ Set `PI_CLAUDE_SUPERVISOR_REQUIRE_LOCAL_COMMIT=0` only for a task that intentionally
134
+ produces no local commit candidate, or set `autonomy.requireLocalCommit` in its spec;
135
+ automatic mode still requires a valid Git baseline and non-protected worktree.
136
+ `PI_CLAUDE_SUPERVISOR_UNATTENDED=0` opts a task out of automatic Decision Worker control;
137
+ a required local commit is checked on a non-protected task branch;
138
+ `PI_CLAUDE_SUPERVISOR_MAX_DECISION_RETRIES` bounds transient Decision Worker retries.
117
139
 
118
140
  The `v0.5.0` automation milestone adds a structured acceptance pipeline:
119
141
  multiple argv-based checks, an independent read-only Reviewer, bounded structured
120
142
  findings and repair rounds. Legacy text tasks keep the default `git diff --check`.
121
143
  The Reviewer only has `read`, `grep`, `find` and `ls`; it cannot edit files or grant
122
- permissions. The current hardening also requires complete HEAD-relative tracked and
123
- bounded untracked evidence, rejects P0/P1 or repeated findings, and only repairs a
124
- live `repairableSession` Worker. Automatic mode rejects explicit `process-pipe` and
125
- preflights runtime prerequisites. The real pinned Claude Code `2.1.270` disposable repair/reacceptance run has passed;
126
- the remaining gate is the exact-head independent review.
144
+ permissions. Automatic mode requires complete baseline-relative tracked, commit and
145
+ bounded untracked evidence, repairs a live `repairableSession` Worker within a
146
+ bounded budget, enforces a local commit when enabled, and prevents a non-publishable
147
+ candidate from crossing the remote/main boundary. Automatic mode rejects explicit
148
+ `process-pipe` and preflights runtime prerequisites. Invalid output, unavailable
149
+ evidence, duplicate findings, P0/P1 findings and exhausted repair budgets park the
150
+ candidate without waiting for a human; see [the autonomy target](docs/autonomy-target.md).
127
151
  Coordinated multi-worker scheduling is a later milestone; CI uses deterministic fake
128
152
  Workers/replay fixtures, and real multi-worker Claude tests remain authenticated
129
- manual Spikes. CLI multi-version compatibility, sandboxing, low-privilege execution
130
- and network isolation are not part of this milestone.
153
+ manual Spikes. Full host-level sandboxing and low-privilege execution for custom
154
+ integrations remain separate hardening work.
131
155
 
132
156
  Automatic mode persists the Pi Decision Worker session under the configured state
133
157
  directory. After an unclean Pi restart, `/supervise sessions` lists recoverable
@@ -138,9 +162,12 @@ the old Worker's process group is gone and its cgroup is a real, readable empty
138
162
  boundary; missing or unverifiable Worker evidence is refused.
139
163
  For a persistent tmux Worker, use explicit `adopt-tmux` instead of takeover.
140
164
  The adapter intentionally does not inherit arbitrary host environment variables.
141
- Pass credentials through an explicit `WorkerStartInput.env` in an embedding
142
- integration. For the built-in command, opt in to named variables, for example
143
- `PI_CLAUDE_SUPERVISOR_WORKER_ENV=ANTHROPIC_API_KEY`.
165
+ Manual embedding integrations may pass credentials through an explicit
166
+ `WorkerStartInput.env`; automatic mode accepts only documented Claude provider
167
+ variables, for example `PI_CLAUDE_SUPERVISOR_WORKER_ENV=ANTHROPIC_API_KEY`, and
168
+ filters remote credentials and configuration-injection variables. The host-side
169
+ `PI_CLAUDE_SUPERVISOR_TRUSTED_CLAUDE` setting pins the executable identity and is not
170
+ passed into the Worker environment.
144
171
 
145
172
  ### tmux/PTY transport
146
173
 
@@ -150,19 +177,20 @@ For an interactive Claude Code window, opt in to the tmux transport:
150
177
  export PI_CLAUDE_SUPERVISOR_TRANSPORT=tmux
151
178
  export PI_CLAUDE_SUPERVISOR_WORKER='claude --permission-mode plan'
152
179
  # tmux does not support cgroup required mode; use cgroup mode auto/off.
153
- # Optional automatic Decision Worker (manual mode is the default):
154
- # export PI_CLAUDE_SUPERVISOR_MODE=auto
180
+ # tmux is manual-only; automatic Decision Worker supervision requires JSONL.
155
181
  # Optional, only when adopting a non-default tmux server:
156
182
  # export PI_CLAUDE_SUPERVISOR_TMUX_SOCKET=/path/to/tmux.sock
157
183
  ```
158
184
 
159
185
  `/supervise start <task>` starts Claude in a private tmux server and reports a
160
186
  literal attach command. Use that command in another terminal to watch or
161
- manually interact with the same PTY. The adapter sends multi-line input through
187
+ manually interact with the same PTY; attaching is optional for unattended local
188
+ development. The adapter sends multi-line input through
162
189
  tmux buffers and Enter, never by interpolating the message into a shell command.
163
- It records the PTY stream with `pipe-pane`, uses `capture-pane` to detect a
164
- stable Claude input prompt, and feeds turn-completion events into the same
165
- watchdog, Decision Worker, audit and verification paths as JSONL.
190
+ It records the PTY stream with `pipe-pane` and uses `capture-pane` to detect a
191
+ stable Claude input prompt. Because tmux has no structured permission boundary,
192
+ automatic Decision Worker supervision is disabled for this transport; use JSONL for
193
+ unattended decisions, repair and protected command enforcement.
166
194
 
167
195
  A session that you started yourself can be explicitly adopted without replaying
168
196
  the task:
@@ -183,12 +211,13 @@ kill-session` yourself when the adopted window should be closed.
183
211
  `/supervise takeover <task-id>` disables automatic Decision Worker messages;
184
212
  resume them only with `/supervise resume-auto <task-id>`.
185
213
 
186
- PTY screen text is not Claude JSONL. Permission dialogs, trust prompts and
187
- ambiguous TUI states are escalated to a human; tmux mode must not be treated as
188
- structured permission evidence. A normal terminal Claude process cannot be
189
- migrated into tmux, and `--resume` is historical recovery rather than live PTY
190
- attach. Owned tmux sessions survive a Pi disconnect and require an explicit
191
- `adopt-tmux` after restart. Use plan/read-only flags for live testing.
214
+ PTY screen text is not Claude JSONL and must not be treated as structured
215
+ permission evidence. TUI decisions follow the configured autonomy policy and are
216
+ recorded; an unresolved task may be parked without requiring a human to remain
217
+ online. A normal terminal Claude process cannot be migrated into tmux, and
218
+ `--resume` is historical recovery rather than live PTY attach. Owned tmux sessions
219
+ survive a Pi disconnect and require an explicit `adopt-tmux` after restart. Use
220
+ plan/read-only flags for live testing.
192
221
 
193
222
  ## Development
194
223
 
@@ -202,7 +231,7 @@ npm run check:workflows
202
231
  npm run build
203
232
  ```
204
233
 
205
- See [the engineering plan](docs/engineering-plan.md), [the independent review](docs/independent-review.md),
234
+ See [the engineering plan](docs/engineering-plan.md), [the confirmed autonomy target](docs/autonomy-target.md), [the independent review](docs/independent-review.md),
206
235
  [architecture](docs/architecture.md), [testing](docs/testing.md), and [releasing](docs/releasing.md).
207
236
 
208
237
  Pull requests are gated by the aggregated `CI / Quality gate`. Release Please
@@ -1,5 +1,7 @@
1
1
  # Architecture
2
2
 
3
+ > The confirmed target is fully unattended local development with an independent remote/main boundary. Automatic mode implements the local editing, testing, repair, acceptance, Review and local-commit loop; unresolved work becomes a parked candidate. Legacy human/takeover APIs remain compatibility controls only. See [autonomy-target.md](autonomy-target.md).
4
+
3
5
  ## Control boundary
4
6
 
5
7
  Pi owns the `Supervisor`. The supervisor owns the task state machine, event log,
@@ -17,12 +19,16 @@ Supervisor -> Policy Gate -> WorkerAdapter -> child process
17
19
  ```
18
20
 
19
21
  The Worker cannot advance a task directly to `completed`. A clean worker exit
20
- moves the supervisor to `verifying`; only a successful verifier moves it to
21
- `completed`.
22
+ moves the supervisor to `verifying`; only successful acceptance, independent Review,
23
+ complete evidence and the configured local-commit boundary move it to `completed`.
24
+ An unresolvable automatic path moves it to `blocked`, never to a publishable result.
22
25
 
23
26
  The extension keeps a registry of independent task sessions. Each session has
24
27
  its own Supervisor, watchdog, state machine and Worker handle, while the event
25
- log is shared and protected by an inter-process lock. Concurrent active sessions must use non-overlapping canonical working
28
+ log is shared and protected by an inter-process lock. Once a task starts, the
29
+ local development loop is intended to run unattended: the Worker may edit, test,
30
+ repair and commit locally. Remote push and merge into `main`/an integration branch
31
+ are outside Worker authority and cross an independent boundary. Concurrent active sessions must use non-overlapping canonical working
26
32
  directories/worktrees; same-cwd and parent/child cwd starts are rejected before
27
33
  spawn, including concurrent starts, to prevent uncoordinated edits. Pending starts
28
34
  are also awaited during Pi shutdown.
@@ -40,8 +46,11 @@ graph, roles, dependencies, bounded concurrency and structured handoff
40
46
  artifacts. Child Workers must communicate through validated evidence and event
41
47
  references rather than another Worker's control channel. Each child is accepted
42
48
  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.
49
+ independent Review. Integration and conflict resolution remain separate from the local development
50
+ loop. The Worker cannot push remotely or merge into `main`/an integration branch;
51
+ the independent integration boundary may combine read-only review, CI and an
52
+ authorized integration action in a separate integration worktree. Rejection or
53
+ shutdown leaves the candidate local.
45
54
 
46
55
  Recovery and shutdown must be graph-aware: a parent with an unknown child state
47
56
  cannot complete, cancellation must propagate within a bounded budget, and Pi
@@ -119,9 +128,11 @@ For an owned initial turn, the adapter emits a synthetic `turn_completed` only
119
128
  after output activity and two stable input-prompt observations. Adopting an idle
120
129
  prompt remains inactive and emits no synthetic completion. This is a liveness
121
130
  signal, not proof that the task succeeded; the independent verifier remains
122
- mandatory. Interactive dialogs,
123
- trust prompts and ambiguous screens are not auto-approved. Human takeover sets a
124
- Supervisor gate that stops automatic messages until `resume-auto`.
131
+ mandatory. Interactive dialogs, trust prompts and ambiguous screens are interpreted by
132
+ the configured autonomy policy and recorded as evidence. An unresolved task is
133
+ parked or failed as a non-publishable candidate rather than requiring a human to
134
+ remain online. Human takeover remains an explicit kill/control path and stops
135
+ automatic messages until `resume-auto`.
125
136
 
126
137
  `/supervise adopt-tmux` is explicit and validates the pinned pane's cwd and
127
138
  process identity before attaching. Every later input, capture and signal uses
@@ -165,7 +176,9 @@ unconfirmed lease left by a crashed Pi is intentionally retained. Ordinary
165
176
  recovery refuses it; an operator may use `recover --takeover` only when the old
166
177
  owner is dead, the Worker process group is gone, and the lease independently
167
178
  reads a real empty cgroup boundary for the old Worker. Missing or unverifiable
168
- Worker evidence still requires manual cleanup rather than unsafe reclamation.
179
+ Worker evidence retains the lease and parks the task rather than performing unsafe
180
+ reclamation; later recovery can inspect or clean it without requiring an operator to
181
+ be online.
169
182
  An explicitly adopted tmux session may hand off an existing lease only after
170
183
  its owner identity is no longer live and its canonical cwd, tmux session/socket,
171
184
  pane id, pane PID/start time, and pane command all match; ordinary starts
@@ -178,13 +191,20 @@ is alive; the extension periodically rechecks released sessions and removes the
178
191
  lease only after the pane is confirmed gone. If that check fails, the lease is
179
192
  retained rather than allowing a cwd overlap.
180
193
 
181
- Before model or Worker execution, automatic starts preflight the validated cwd,
182
- worker executable, transport dependencies, runtime state/lease directories and,
183
- when requested, the real writable cgroup-v2 boundary. A failed preflight is
184
- fail-closed and does not start Claude. Long acceptance commands and Reviewer
194
+ Before model or Worker execution, automatic starts validate a full existing Git
195
+ baseline, a non-bare worktree, a readable non-protected branch, the direct bare
196
+ `claude`/`claude.exe` command name, JSONL transport, runtime state/lease directories
197
+ and, when requested, the real writable cgroup-v2 boundary. The resolved Claude
198
+ executable is checked for an operator-owned, non-writable path and then pinned by
199
+ absolute path; `PI_CLAUDE_SUPERVISOR_TRUSTED_CLAUDE` can pin the expected identity. The initial repository HEAD is captured, and the repository boundary immediately
200
+ before the Worker adapter starts must report that exact same HEAD (recovery captures
201
+ and compares its current HEAD separately while retaining the persisted baseline).
202
+ The built-in process adapter invokes the same assertion through `preSpawnCheck`
203
+ after cgroup/executable setup and immediately before `spawn`; a failed preflight
204
+ is fail-closed and does not start Claude. Long acceptance commands and Reviewer
185
205
  sessions share an abort signal with the Supervisor, so operator stop/shutdown
186
206
  wins without waiting for a full check timeout. Progress hooks expose starting,
187
- Worker heartbeat, acceptance, review, repair and human-gate phases in the Pi UI.
207
+ Worker heartbeat, acceptance, review, repair and candidate/decision phases in the Pi UI.
188
208
 
189
209
  Startup owns an `AbortController` and passes its signal to the adapter. A stop
190
210
  or shutdown request aborts the controller and calls the adapter's out-of-band
@@ -221,20 +241,22 @@ unclean Pi restart, recovery is explicit: `/supervise recover [--takeover]
221
241
  <task-id>` restores
222
242
  the Decision Worker context and starts a new Claude Worker. It does not silently
223
243
  resume or duplicate a task. It does not poll to detect turn completion. A watchdog timer remains only as a deadlock safety
224
- fallback. Permission actions pass through `evaluatePermission` and can be
225
- approved or denied manually with `/supervise approve`; human escalation is sent
226
- to an outbound webhook when configured. If the Decision Worker API/model call
227
- fails, the system records `decision_worker_failed` and directly alerts the
228
- human operator; it does not attempt a second LLM fallback. Alert delivery is
229
- kept independent from event-log persistence so an audit write failure cannot
230
- suppress the alert.
244
+ fallback. Permission and other actions pass through the configured autonomy policy and
245
+ are recorded. The local development loop must not require synchronous human
246
+ approval for ordinary actions; a task that cannot safely produce a candidate is
247
+ parked or failed without granting remote/main authority. If the Decision Worker
248
+ API/model call fails, the system records `decision_worker_failed`, applies the
249
+ bounded retry/park policy and preserves the candidate evidence. Optional alert
250
+ delivery remains independent from event-log persistence, but notification is not
251
+ the control boundary.
231
252
 
232
253
  ## Acceptance, review and repair loop
233
254
 
234
255
  A task may provide a structured `TaskSpec` with `goal`, `scope`, `constraints`,
235
- `forbidden` and an ordered list of required or optional acceptance checks. A
256
+ `forbidden`, an ordered list of required or optional acceptance checks, and
257
+ `autonomy` (`unattended`, `requireLocalCommit`, `maxDecisionRetries`). A
236
258
  legacy plain-text task is normalized to a goal with the default `git diff
237
- --check` acceptance check. The verifier runs every configured check with argv,
259
+ --check` acceptance check and unattended defaults. The verifier runs every configured check with argv,
238
260
  bounded output and the same deterministic command policy; a Worker completion
239
261
  claim never substitutes for these results.
240
262
 
@@ -243,35 +265,40 @@ fresh read-only Reviewer session. The Reviewer receives the task specification,
243
265
  check results and bounded Worker completion evidence, but not the Decision Worker
244
266
  conversation or control channel. It can inspect only `read`, `grep`, `find` and `ls`, and must return
245
267
  `pass`, `revise` or `human` with bounded structured findings. Invalid Reviewer
246
- output or a Reviewer API failure is a human-required condition.
268
+ output, incomplete evidence or a Reviewer API failure must prevent a candidate
269
+ from crossing the remote/main boundary; the local system may retry, repair or
270
+ park it without requiring a human to be online.
247
271
 
248
272
  A `revise` result produces an audited repair round and sends a bounded corrective
249
273
  instruction to a still-live `repairableSession` Worker. Checks and review then run again.
250
274
  The repair budget defaults to three rounds; repeated findings and P0/P1 findings
251
- stop automation and escalate. A Worker that has already exited cannot be silently recreated
275
+ stop automation and park a non-publishable candidate. A Worker that has already exited cannot be silently recreated
252
276
  for repair; it remains failed/recoverable rather than replaying the original task. If a repair
253
- or human-review branch cannot continue, a single idempotent terminalizer records
277
+ or candidate branch cannot continue, a single idempotent terminalizer records
254
278
  `verification_failed`, closes the Decision Worker and reports cleanup evidence; it never performs
255
279
  a second `failed -> failed` transition.
256
280
 
257
- Repository evidence is HEAD-relative: tracked staged and unstaged changes are collected together,
258
- and untracked regular files are included through bounded, component-safe, no-symlink reads. Incomplete or
259
- truncated evidence is not sufficient for an independent `pass` verdict. Acceptance
281
+ Repository evidence is baseline-relative: the Supervisor records the initial HEAD,
282
+ then collects tracked committed/staged/unstaged changes, commit summaries after that
283
+ baseline and untracked regular files through bounded, component-safe, no-symlink reads.
284
+ Incomplete or truncated evidence is not sufficient for an independent `pass` verdict;
285
+ automatic mode parks a task when the required git baseline or local commit is unavailable. Acceptance
260
286
  process output uses a bounded execution buffer before the smaller persisted evidence
261
287
  limit, so a normal large test report is not misclassified as a failed command.
262
288
 
263
289
  ## Deliberate non-goals
264
290
 
265
- - automatic merge/deploy/release;
266
- - unauthenticated inbound webhook commands; outbound notifications do not grant
267
- permission and do not replace Pi human takeover;
268
- - treating an unknown Claude interactive question as safe to answer automatically;
269
- - bypassing Claude Code permissions;
291
+ - giving the Worker remote push or main/integration merge authority;
292
+ - unauthenticated inbound webhook commands; outbound notifications are optional,
293
+ do not grant permission and do not replace the remote/main independent boundary;
294
+ - treating an unknown Claude interactive question as safe without task evidence or configured authorization;
295
+ - bypassing the configured Claude Code/task permissions;
270
296
  - accepting model text as verification;
271
297
  - shell command interpolation;
272
- - automatic network denial or a fake domain allowlist. Network access follows
273
- Claude's own permission model and the command policy; suspicious download-to-
274
- shell patterns require human review rather than blanket network rejection;
298
+ - a host-level network sandbox for manual integrations. Automatic mode does not admit
299
+ arbitrary custom executables: its supported Worker is direct Claude, which requests a
300
+ fail-closed Claude Code Bash sandbox with no outbound domains; command policy and
301
+ credential filtering remain defense in depth;
275
302
  - Claude CLI multi-version compatibility in the current stability milestone;
276
- - OS sandbox, low-privilege execution and network isolation in the current
303
+ - full OS sandbox and low-privilege execution for custom Worker integrations in the current
277
304
  lifecycle milestone.