@xzzpig/pi-openspec-x 0.1.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 ADDED
@@ -0,0 +1,15 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0
4
+
5
+ Initial release.
6
+
7
+ - Official-track skills extracted from the installed OpenSpec CLI, cached by
8
+ CLI version under `<agentDir>/cache/pi-openspec-x/skills/<version>/`.
9
+ - `/opsx:plan`: planner sandbox mode, append-only per-artifact instruction
10
+ injection, gap analysis, plan review gate, user approval gate.
11
+ - `/opsx:implement`: agent (opsx-agent + opsx-worker dispatches) and direct
12
+ main-session modes on a pi-goal-x execution base, with a final completion
13
+ audit pointing at the read-only opsx-reviewer.
14
+ - Runtime-registered opsx subagents and structured reporting tools.
15
+ - Versioned lifecycle bus events and a literal pi-notify bridge.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Lucas
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,203 @@
1
+ # @xzzpig/pi-openspec-x
2
+
3
+ 把 [OpenSpec](https://github.com/Fission-AI/OpenSpec) 的规范驱动流程接进 pi coding agent:从**当前安装的 openspec CLI** 现场提取官方 skill,并提供 `/opsx:plan`(深度计划 + 缺口分析 / 计划审查门)与 `/opsx:implement`(代理实现 / 主会话直实现 + 最终整体审查门)两条增强流程。
4
+
5
+ ```bash
6
+ pi install npm:@xzzpig/pi-openspec-x
7
+ ```
8
+
9
+ ## 双轨
10
+
11
+ | 轨道 | 入口 | 说明 |
12
+ | ------ | ------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
13
+ | 官方轨 | `openspec-*` 五个同名 skill | 会话启动时按已安装 CLI 的版本生成(`--version` / `schemas --json` / `templates --json`),内容与 CLI 一致,执行期再经 `openspec instructions <artifact> --change <id> --json` 现取权威指令;按 CLI 版本缓存于 `<agentDir>/cache/pi-openspec-x/skills/<version>/`,同版本不重复调用 CLI,升级在下一个会话生效。 |
14
+ | 增强轨 | `/opsx:plan`、`/opsx:implement` | 在官方轨之上叠加流程纪律:计划态写权限收敛、缺口分析、计划审查、用户审批;实现阶段以持久目标为底座,worker 派发 + 逐文件审查,最终以 goal 完成审计收口。两条轨互不干扰。 |
15
+
16
+ 官方轨的 skill 集合在一个会话内**冻结**:插件只追加消息,不改写系统提示、不中途增删 skill,以保住提示词前缀缓存。
17
+
18
+ ## 安装与静态文件迁移
19
+
20
+ 1. `pi install npm:@xzzpig/pi-openspec-x`,重启会话即可获得官方轨 skill(首次自动生成缓存)。
21
+ 2. 若项目里已有 `openspec init` 生成的静态 `.pi/skills/openspec-*`,插件会检测并提示移除它们(同名双供会互相遮蔽)。**插件不会替你删除文件**——按提示手动移除即可,之后由插件按 CLI 版本动态提供。
22
+
23
+ 可选依赖:
24
+
25
+ - `@eko24ive/pi-ask`:在场时审批走结构化提问,缺失时降级为纯文本。
26
+ - `@xzzpig/pi-agent-role`:**不需要**。受限模式的角色切换由插件自身的 `/opsx:*` 命令经 `active_agent` 条目 + pi-sandbox profile 双通道完成。
27
+
28
+ 必需 peer:`@xzzpig/pi-sandbox`(受限模式门控)、`@xzzpig/pi-subagents`(子 agent 注册与委派)、`@xzzpig/pi-goal-x`(实现底座)。
29
+
30
+ ## 沙箱 profile:无需手动配置
31
+
32
+ 插件在扩展初始化时通过 pi-sandbox 的编程注册接口(`registerSandboxProfiles`)会话级注册三个 profile,**不会写入你的 `sandbox.json`**:
33
+
34
+ | profile | 可写 | 用途 |
35
+ | --------------- | -------------------------------------------------------------------------------------------- | ------------------- |
36
+ | `opsx-planner` | `openspec/**` | `/opsx:plan` 计划态 |
37
+ | `opsx-agent` | `openspec/**` + 构建产物(`node_modules/**`、`dist/**`、`coverage/**`、`.cache/**`,可配置) | 代理实现态主 agent |
38
+ | `opsx-reviewer` | 空(只读) | 最终整体审查者 |
39
+
40
+ 解析顺序是**用户配置优先**:若你在 `sandbox.json` 里定义了同名 profile,以你的定义为准,插件注册不会覆盖。
41
+
42
+ fail-closed:pi-sandbox 缺失时,`/opsx:plan` 与代理实现态会被拒绝并说明原因;官方轨 skill 与主会话直实现模式不受影响。pi-goal-x 缺失时 `/opsx:implement` 会被拒绝;pi-sandbox 缺失时计划态与代理实现态会被拒绝。
43
+
44
+ ## `/opsx:plan <change-id>`
45
+
46
+ 1. 进入 `opsx-planner` 受限模式(写权限收敛到 `openspec/`),追加一条模式契约消息。
47
+ 2. 按 change 的 artifact 依赖顺序逐阶段追加指令块(现场取 `openspec instructions <artifact> --change <id> --json`;CLI 报错或 change 未创建时降级为内置骨架并提示)。每阶段只追加一次,均为 append-only。
48
+ 3. 可派发只读的 `opsx-gap-analysis` 做缺口分析,发现需被吸收进计划产物。
49
+ 4. 计划成品后派发只读的 `opsx-plan-review` 审查,裁决 `OKAY/ITERATE/REJECT`;非 OKAY 修订重审,`ITERATE` 连续 2 轮或 `REJECT` 重复同一 blocker 时升级用户接管。
50
+ 5. `OKAY` 后请求用户审批。**未获批准不得进入实现**。TUI 会话恒有 UI,审批走阻塞对话框并落台账;无 UI 会话降级为纯文本并记录 `pending`——此时实现仍锁死,需在有 UI 的会话重审或将批准人工写回台账(插件不监听自由文本答复)。
51
+
52
+ 计划阶段的门控事件(缺口分析发现、计划审查裁决与轮次、派发用量)以 append-only JSONL 记录在 change 目录的 `.opsx-plan-review.jsonl`,并投影为人读的 `reviews.md`(见下)。
53
+
54
+ ## `/opsx:implement [--agent|--direct] <change-id>`
55
+
56
+ 模式二选一(命令参数或结构化提问),未选定不动作;同一会话已有进行中的实现流程时拒绝二次进入并指引恢复/结束。
57
+
58
+ 计划态与代理实现态的写收敛由 pi-sandbox 的受限 profile 强制(fail-closed):越界写被沙箱层拒绝并给出原因,读取不受限;进入受限模式前插件发出的模式契约已预先指明可写范围并把写入指引收敛回 `openspec/`。
59
+
60
+ - **`--direct` 主会话直实现**:不切角色、不收紧权限;按 `tasks.md` 顺序实现、自行验证、验证通过才勾选,终点同样接最终审查门。
61
+ - **`--agent` 代理实现**:进入 `opsx-agent` 受限模式(源码只读、构建产物可写),逐任务派发全写权限的 `opsx-worker`。派发提示词固定六段(任务 / 预期产出 / 所需工具 / 必须做 / 禁止做 / 上下文);派发返回后逐文件核对 diff 与 `report_work` 声明、运行验证,**通过才勾选 tasks.md**,并同步 goal 任务树。
62
+
63
+ “未审查不得勾选”是**强制门**:插件监听 `subagent`(`agent=opsx-worker`)、`report_work` 与 `update_goal_task` 三类工具流量,在 `update_goal_task status=complete` 的 `tool_call` 阶段拦截——没有观测到派发、没有对应的 `report_work`、报告声明与窗口 delta 不一致(漏报或多报文件)、或记录的验证明显失败时,勾选被 block 并返回具体原因。因此代理模式下**必须先 `report_work`(taskId / changedFiles / 验证命令与结果)再勾选**。同一任务反复派发且既无报告也无改动会被判为空转并提示一次。门拦的是 goal 任务树镜像的 `update_goal_task`;直接以 bash/write 改 `tasks.md` 复选框本身不被硬拦,由「goal 任务树不完整 → goal-x 完成事务拒绝」兜底,最终语义一致。直实现模式不设此门(无派发可核)。
64
+
65
+ 两种模式都以持久目标为执行底座:插件把 `tasks.md` 组装成 objective(`Steps` + `Boundaries`/`Don'ts` + `Verification contract:`)交给 goal-x 的 `create_goal`(代理模式 `sisyphus`,直实现模式普通 autoContinue),任务清单经 `set_goal_tasks` 单向镜像。`tasks.md` 是任务权威源,goal 任务树上的手工改动不回流。
66
+
67
+ ### 最终整体审查门
68
+
69
+ 完成 = goal-x 完成事务内建的独立审计:插件为**该 opsx 目标**设置 per-goal auditor 覆盖,把审计执行者指向只读的 `opsx-reviewer`(审查计划符合度、代码质量、验证证据、scope 保真,审查范围为执行窗口 delta)。普通 `/goal` 目标不受影响,仍走默认审计 agent。
70
+
71
+ 任务全勾而审计 `disapproved` 时目标保持未完成 → 修复(代理模式派 worker / 直实现主会话修)→ 重审,直到 `approved` 才达成完成。完成后插件只**引导**归档,绝不代执行。
72
+
73
+ 审计 `disapproved` 只是**拒绝完成**,不会自动撤销已写下的代码。要放弃这次执行并回滚工作树,用:
74
+
75
+ ```
76
+ /opsx:rollback <change-id>
77
+ ```
78
+
79
+ 回滚严格按「先计划、备份落盘、后动工作树」三步执行,逻辑全部委托给 goal-x 的 `goal-change-rollback`(与 `/goal-clear` 同一实现,插件与底座永不漂移):
80
+
81
+ 1. 读该目标的 baseline 与执行窗口 delta,产出待处理动作清单(**不触碰任何文件**);
82
+ 2. 把将被丢弃的文件以可回放的补丁复制到 `.pi/goals/archived/rollback_<时间戳>_<goalId>/`(`.patch` 可 `git apply` 回放,另写 `manifest.json`;备份失败即中止,**仍不触碰工作树**);
83
+ 3. 才修改工作树:窗口内被修改/删除的文件用 `git checkout <baseline stash> -- <path>` 恢复到窗口前内容,窗口内新增的文件被删除,重命名按「删新路径 + 恢复旧路径」撤销。
84
+
85
+ 回滚范围**只有执行窗口 delta**——窗口开始前就已经存在的未提交改动不在 delta 内,因此永不被回滚。**不提供按任务回滚**(任务粒度的偏差由修复循环承担)。非 git 仓库、未诞生 HEAD 或无 baseline 时降级为「不可用」并**不改动任何文件**。备份目录会打印在结果里,随时可从其中还原被丢弃的内容。
86
+
87
+ 放弃执行还需你自己用 goal-x 的 `/goal-clear` 清掉底座目标(插件不会代你做这一步);只清目标不撤销工作区改动,撤销工作区改动就是上面的 `/opsx:rollback`。
88
+
89
+ ### 恢复
90
+
91
+ 实现流程跑在持久目标上:崩溃或压缩后,目标(objective、任务树、账本)仍在磁盘。新会话启动时,若底座里存在未完结的 opsx 目标,插件会给出一次性提示,指引你运行 goal-x 的 `/goal-resume` 重新接管(或 `/goal-clear` 放弃)。若底座目标被手动清除/暂停,插件检测到分叉并给出选项;诊断只读,任何修复都需要你确认。
92
+
93
+ ## `reviews.md` 格式
94
+
95
+ `reviews.md` 是 `.opsx-plan-review.jsonl` 的人读投影,由记录生成,可随时重新生成。结构:
96
+
97
+ ```markdown
98
+ # Plan review record
99
+
100
+ Projected from `.opsx-plan-review.jsonl` (append-only).
101
+
102
+ ## Gap analysis — <ISO 时间>
103
+
104
+ <summary>
105
+ - <finding>
106
+
107
+ ## Plan review verdict — round <N> — <OKAY|ITERATE|REJECT> — <ISO 时间>
108
+
109
+ <summary>
110
+ - Blocker: <blocker>
111
+ Usage: input <n>, output <n>, turns <n>
112
+
113
+ ## Plan approval — <approved|revise|rejected> — <ISO 时间>
114
+
115
+ Requested via: <pi-ask|select|text>
116
+
117
+ ## Escalation — <ISO 时间>
118
+
119
+ - <reason>
120
+
121
+ ## Delegation usage (total)
122
+
123
+ input <n>, output <n>, cacheRead <n>, cacheWrite <n>, turns <n>
124
+ ```
125
+
126
+ ## lifecycle 事件字典
127
+
128
+ 插件在关键节点向扩展总线发布版本化事件,单通道 `pi-openspec-x:lifecycle:v1`,payload 结构(TS 类型由插件导出):
129
+
130
+ ```ts
131
+ interface OpsxLifecyclePayload {
132
+ version: 1;
133
+ type:
134
+ | "plan_started"
135
+ | "phase_changed"
136
+ | "review_verdict"
137
+ | "approval_wait"
138
+ | "plan_approved"
139
+ | "implement_started"
140
+ | "task_dispatched"
141
+ | "task_completed"
142
+ | "final_verdict"
143
+ | "flow_completed"
144
+ | "mode_exited";
145
+ change: string; // 所属 openspec change
146
+ at: string; // ISO 时间
147
+ mode?: "plan" | "agent" | "direct";
148
+ phase?: string;
149
+ round?: number;
150
+ verdict?: string;
151
+ taskId?: string;
152
+ message?: string;
153
+ }
154
+ ```
155
+
156
+ 每个类型实际由谁在什么时机发出:
157
+
158
+ | type | 触发点 |
159
+ | ------------------- | ----------------------------------------------------------------------------------- |
160
+ | `plan_started` | `/opsx:plan <change-id>` 进入计划模式后 |
161
+ | `phase_changed` | 计划阶段注入某个 artifact 的 phase 块;实现流程切到 `reviewing` |
162
+ | `review_verdict` | 记录一次计划审查裁决(含轮次) |
163
+ | `approval_wait` | 打开审批对话框之前 |
164
+ | `plan_approved` | 审批决策为 approved |
165
+ | `implement_started` | `/opsx:implement` 启动实现流程 |
166
+ | `task_dispatched` | 观察到一次 `opsx-worker` 派发(`subagent` 工具,`agent=opsx-worker`) |
167
+ | `task_completed` | 观察到 `update_goal_task status=complete` 成功 |
168
+ | `final_verdict` | 观察到 `update_goal status=complete`:成功为 `approved`,被审计拒绝为 `disapproved` |
169
+ | `flow_completed` | 底座目标被 goal-x 归档(完成或清除)时结束流程 |
170
+ | `mode_exited` | 同上结束实现流程时;以及 `/opsx:implement` 接管时结束计划模式 |
171
+
172
+ `task_dispatched` / `task_completed` / `final_verdict` 是插件对主代理工具流量的观察,不是 goal-x 的推送;goal-x 缺失或流程未启动时不会发出。`final_verdict` 的 approved/disapproved 由该工具结果的 `isError` 推断(显示层启发式;权威裁决以 goal-x 的审计结果为准)。子代理内部的 `report_*` 调用不产生主会话事件,进度投影只覆盖主会话可见的上报。
173
+
174
+ pi-sentinel 可直接以 `event:` 触发器订阅:
175
+
176
+ ```jsonc
177
+ // .pi/sentinel.json(示意)
178
+ {
179
+ "rules": [
180
+ {
181
+ "id": "opsx-audit",
182
+ "event": "pi-openspec-x:lifecycle:v1",
183
+ "prompt": "当事件 type 为 final_verdict 且 verdict 为 disapproved 时,提醒我查看 findings。",
184
+ },
185
+ ],
186
+ }
187
+ ```
188
+
189
+ ### pi-notify 桥接
190
+
191
+ 按**字面 channel 名**发送,不 import pi-notify;pi-notify 不在场时零影响:
192
+
193
+ - 打开阻塞式 UI(模式选择、审批)前:`pi-notify:ui_span_silent`(`{ reason }`)。
194
+ - 审批等待:`pi-notify:publish` `{ eventId: "input-required", source: "pi-openspec-x" }`。
195
+ - 流程完成:`task-completed`;门控异常:`integration-error`。
196
+
197
+ ## 与 `/role` 的关系
198
+
199
+ pi-subagents 的运行时 agent 注册表按 **owner ExtensionAPI 键控**,pi-agent-role 的 `/role` 枚举视图**看不到**本插件运行时注册的 `opsx-*` agent(实现期已验证)。因此本插件**不宣传** `/role` 互操作;受限模式的切换完全由 `/opsx:*` 命令经 `active_agent` 条目 + pi-sandbox profile 完成,不依赖 pi-agent-role。
200
+
201
+ ## 许可
202
+
203
+ MIT。
package/index.ts ADDED
@@ -0,0 +1 @@
1
+ export { default } from "./src/index.ts";
package/package.json ADDED
@@ -0,0 +1,55 @@
1
+ {
2
+ "name": "@xzzpig/pi-openspec-x",
3
+ "version": "0.1.0",
4
+ "description": "OpenSpec workflow for the pi coding agent: spec-driven planning and implementation via dedicated subagents, sandboxed /opsx:plan and /opsx:implement commands.",
5
+ "keywords": [
6
+ "pi-package",
7
+ "pi",
8
+ "pi-extension",
9
+ "pi-coding-agent",
10
+ "openspec",
11
+ "spec-driven-development",
12
+ "subagents"
13
+ ],
14
+ "license": "MIT",
15
+ "type": "module",
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git+https://github.com/xzzpig/pi-extensions.git",
19
+ "directory": "packages/pi-openspec-x"
20
+ },
21
+ "homepage": "https://github.com/xzzpig/pi-extensions/tree/main/packages/pi-openspec-x#readme",
22
+ "publishConfig": {
23
+ "access": "public"
24
+ },
25
+ "files": [
26
+ "index.ts",
27
+ "src",
28
+ "README.md",
29
+ "CHANGELOG.md",
30
+ "LICENSE",
31
+ "package.json"
32
+ ],
33
+ "pi": {
34
+ "extensions": [
35
+ "./index.ts"
36
+ ]
37
+ },
38
+ "peerDependencies": {
39
+ "@earendil-works/pi-ai": ">=0.86.1 <0.88.0",
40
+ "@earendil-works/pi-coding-agent": ">=0.87.1 <0.88.0",
41
+ "@xzzpig/pi-goal-x": "*",
42
+ "@xzzpig/pi-sandbox": "*",
43
+ "@xzzpig/pi-subagents": "*"
44
+ },
45
+ "devDependencies": {
46
+ "@earendil-works/pi-coding-agent": "0.87.1",
47
+ "@types/node": "24.12.4",
48
+ "typescript": "5.9.3",
49
+ "vitest": "4.1.8"
50
+ },
51
+ "scripts": {
52
+ "test": "vitest run",
53
+ "typecheck": "tsc --noEmit"
54
+ }
55
+ }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Agent directory resolution for pi-openspec-x.
3
+ *
4
+ * Mirrors the semantics pi-goal-x established for this monorepo: the
5
+ * `PI_CODING_AGENT_DIR` environment variable overrides the default
6
+ * `<homeDir>/.pi/agent` location. Absolute overrides are normalized;
7
+ * relative overrides resolve against `homeDir`. Nothing in this package may
8
+ * hardcode the default path — always go through `resolveAgentDir`.
9
+ */
10
+ import * as os from "node:os";
11
+ import * as path from "node:path";
12
+
13
+ /** Environment variable overriding the pi agent directory. */
14
+ const PI_CODING_AGENT_DIR_ENV = "PI_CODING_AGENT_DIR";
15
+
16
+ function asNonEmptyString(value: unknown): string | undefined {
17
+ return typeof value === "string" && value.trim() ? value.trim() : undefined;
18
+ }
19
+
20
+ /** Resolve the pi agent dir honoring PI_CODING_AGENT_DIR (absolute or ~-relative to homeDir). */
21
+ export function resolveAgentDir(
22
+ env: NodeJS.ProcessEnv = process.env,
23
+ homeDir: string = os.homedir(),
24
+ ): string {
25
+ const override = asNonEmptyString(env[PI_CODING_AGENT_DIR_ENV]);
26
+ if (override) {
27
+ return path.isAbsolute(override)
28
+ ? path.normalize(override)
29
+ : path.resolve(homeDir, override);
30
+ }
31
+ return path.join(homeDir, ".pi", "agent");
32
+ }
33
+
34
+ /** Cache root for this extension under the agent dir. */
35
+ function openspecXCacheRoot(agentDir: string): string {
36
+ return path.join(agentDir, "cache", "pi-openspec-x");
37
+ }
38
+
39
+ /**
40
+ * Versioned skills cache directory: the CLI version is the cache key, so a
41
+ * CLI upgrade regenerates instead of reusing stale skills.
42
+ */
43
+ export function openspecXSkillsDir(
44
+ agentDir: string,
45
+ cliVersion: string,
46
+ ): string {
47
+ return path.join(openspecXCacheRoot(agentDir), "skills", cliVersion);
48
+ }
@@ -0,0 +1,115 @@
1
+ /**
2
+ * System prompts for the four opsx runtime subagents (design D3/D5).
3
+ *
4
+ * The discipline slices are original English wording distilled from the OmO
5
+ * Prometheus-style rules (design Non-Goals: no OmO code is
6
+ * copied). Each prompt states: the role's single job, the exact checks it is
7
+ * allowed to make, its reporting channel, and its hard boundaries (read-only
8
+ * vs write, plan-file read-only for the worker, zero user intervention).
9
+ *
10
+ * Prompts are intentionally self-contained: subagents run with a fresh
11
+ * context (`defaultContext: "fresh"`) and only what the dispatch injects.
12
+ */
13
+
14
+ /**
15
+ * opsx-gap-analysis — pre-planning gap analyst. Read-only; reports through
16
+ * `report_gap_analysis`.
17
+ */
18
+ export const GAP_ANALYSIS_SYSTEM_PROMPT = `You are the pre-planning gap analyst for the OpenSpec planning flow (opsx). You analyze the user's request and the draft planning material before the plan is finalized. You find the gaps a confident planner walks past. You are a read-only analyst: you NEVER modify, create, or delete any file, and you never run state-changing commands — the bash tool, when available, is for non-mutating inspection only (reading files, listing directories, checking versions).
19
+
20
+ Your single deliverable is a gap analysis, submitted through the report_gap_analysis tool. Submit it once you have a complete picture, and submit again (superseding the previous call) whenever your analysis materially changes.
21
+
22
+ Classify the user's intent into exactly one of: refactor, build-from-scratch, mid-sized, collaborative, architecture, research. Report your confidence (0 to 1). The classification drives how much process the plan deserves — say why you chose it in the summary.
23
+
24
+ Hunt for five kinds of gaps, each reported as concrete findings with locations:
25
+ 1. Contradictions — requirements, constraints, or statements that conflict with each other.
26
+ 2. Missing constraints — things the request implies but never states: platform, runtime versions, compatibility, performance budgets, security, data ownership, failure behavior.
27
+ 3. Scope risks — where the request invites building too much: scope inflation, premature abstraction, speculative generality, over-validation (testing infrastructure for code that has not earned it). Flag this AI-slop pattern explicitly: an over-engineered plan is a failure mode, not thoroughness.
28
+ 4. Unvalidated assumptions — claims the plan relies on without evidence: "the API supports X", "the dependency is installed", "tests currently pass". Anything verifiable that nobody verified.
29
+ 5. Missing acceptance criteria — outcomes with no way to check them.
30
+
31
+ Apply the ZERO USER INTERVENTION principle without exception: every acceptance criterion must be executable by an agent inside the workspace — a command, a file inspection, a test run. Any criterion of the form "the user manually tests", "the user confirms visually", or "ask the user whether it works" is a missing acceptance criterion. Report it as such; do not soften it.
32
+
33
+ Analyze; do not design. You do not propose the solution and you do not rewrite the plan — you make the gaps impossible to ignore so the planner fixes them. Findings must be specific (quote the conflicting statements, name the unstated constraint) and located (file, artifact section, or requirement number). Empty lists are honest answers: a clean request with high confidence is a valid result.`;
34
+
35
+ /**
36
+ * opsx-plan-review — practical work-plan reviewer. Read-only; reports through
37
+ * `report_plan_review`.
38
+ */
39
+ export const PLAN_REVIEW_SYSTEM_PROMPT = `You are the practical work-plan reviewer for the OpenSpec planning flow (opsx). You review a finished implementation plan. You answer exactly one question: can a competent developer execute this plan without getting stuck? Not "is the plan optimal" — can it be executed.
40
+
41
+ You are a read-only reviewer: you NEVER modify, create, or delete files. You are conservative and literal by discipline: you check what the plan actually says, not what a charitable reader could infer from it, and you never invent context the plan does not contain. Precision over volume — this is a verdict, not an essay.
42
+
43
+ Check ONLY these four things:
44
+ 1. Reference validity — every file path, symbol, and line number the plan cites must actually exist in the workspace. Verify with read/grep/find; a plan citing imaginary code strands its executor.
45
+ 2. Task startability — every task must have a starting point: enough stated context (files to touch, current behavior, intended behavior) that the executor can begin without guessing. A task that says "improve the code" with zero context is a blocker.
46
+ 3. Critical blockers — contradictions between tasks or artifacts, ordering that cannot work, dependencies on things that do not exist.
47
+ 4. Acceptance scenario executability — each task's acceptance scenario must name the tool to run, the steps, and the expected result. "It should work" is not a scenario. "Run pnpm test; all tests pass" is.
48
+
49
+ APPROVAL BIAS: 80% clear is enough. If the plan is workable, approve it. You are a blocker-only reviewer, not a perfectionist: do NOT review optimality, architecture taste, performance, style, naming, or what you would have done differently. If execution will not actually stall, it is not your issue.
50
+
51
+ Verdicts, submitted through the report_plan_review tool:
52
+ - OKAY: executable as written. Issues list may note minor nits, none blocking.
53
+ - ITERATE: workable, but targeted revisions are needed first. List the specific non-blocking issues.
54
+ - REJECT: not executable as written. At most 3 blocking issues, each specific and actionable (what is wrong, where, what would fix it). Never block on anything you have not verified.
55
+
56
+ Every REJECT must be new news: your dispatch context includes the previous verdicts and how the plan changed. Re-read it. If a blocker you raised earlier was fixed, do not raise it again; if you raise a blocker a previous round already raised, you are wrong — either it was not actually fixed (say precisely why the fix is insufficient) or it should never have been a blocker. Quote the earlier verdict you are comparing against in the summary. A REJECT that repeats a satisfied blocker burns a review cycle for nothing.
57
+
58
+ The parent gates purely on the verdict field. Approve workable plans; reject only what genuinely strands the executor.`;
59
+
60
+ /**
61
+ * opsx-worker — focused single-task executor. Full write; reports through
62
+ * `report_work`.
63
+ */
64
+ export const WORKER_SYSTEM_PROMPT = `You are the opsx worker: a focused task executor for the OpenSpec implementation flow. You execute exactly ONE dispatched task. You do not delegate further, you do not spawn subagents, you do not pick up neighboring tasks, and you do not refactor beyond the task.
65
+
66
+ Execute the task description exactly as dispatched, against its acceptance criteria. The dispatch context is your specification: if it is ambiguous, make the smallest reasonable interpretation that satisfies the acceptance criteria and say so in your report — do not expand the task to resolve the ambiguity.
67
+
68
+ Change discipline:
69
+ - Make the minimum changes that complete the task. No drive-by fixes, no reformatting untouched code, no dependency bumps, no "while I'm here" improvements. Every changed file must be justified by the task.
70
+ - Never touch files outside the scope the dispatch states.
71
+ - Plan files are READ-ONLY for you: everything under openspec/ — tasks.md, proposal.md, specs/, design.md — must never be modified by you. In particular, you do NOT tick checkboxes in tasks.md; checking off completed tasks belongs to the parent agent after it reviews your work.
72
+
73
+ Self-verification is mandatory, not optional. Before reporting completion: run the relevant verification (build, tests, typecheck — whatever the dispatch or the project conventions define for the code you touched) yourself, and capture the real output. A task is not done because it looks done.
74
+
75
+ Report through the report_work tool with:
76
+ - taskId: the dispatched task identifier;
77
+ - changedFiles: every file you created or modified — the parent reviews your diff against this list, so an incomplete list is a false report;
78
+ - claims: what you did and the result, precisely;
79
+ - selfVerification: the command you ran and its actual result (exit status, pass/fail counts). Subagents lie — not you: your evidence must be real command output you personally observed. If verification failed and you could not fix it, report that honestly; a truthful failure is recoverable, an invented success is not.
80
+
81
+ If the task cannot be completed as specified (missing prerequisite, contradictory requirements), stop early, change nothing you cannot justify, and report exactly what is blocking.`;
82
+
83
+ /**
84
+ * opsx-reviewer — final holistic reviewer (the goal-x completion-audit
85
+ * executor). Read-only; progress through `report_auditor_progress`, final
86
+ * ruling through the audit's structured_output channel.
87
+ */
88
+ export const OPSX_REVIEWER_SYSTEM_PROMPT = `You are the final holistic reviewer for the OpenSpec implementation flow (opsx), executing the completion audit. A goal claims to be complete; you decide whether the evidence deserves that claim. The executor's completion summary is untrusted input — never proof. Be skeptical and semantic: do not approve from intentions, file counts, plausible summaries, or a single passing command.
89
+
90
+ Review the change across four dimensions:
91
+ 1. Plan compliance — go through tasks.md and the design item by item. Every task and every Must/Should requirement is either verifiably satisfied or a finding. Do not sample; enumerate.
92
+ 2. Code quality — the change is coherent, follows the project's conventions, and does not introduce obvious defects (error handling, edge cases, dead code).
93
+ 3. Verification evidence — the claims are backed by real command output (test runs, builds, typechecks) that you can reproduce or at least confirm from the artifacts. "Should pass" and "I verified it" without observable evidence are findings.
94
+ 4. Scope fidelity — every changed file belongs to the plan. Unrequested refactors, unrelated fixes, or touched files the plan never mentions are findings, even if harmless.
95
+
96
+ Your review scope is the window delta injected in your dispatch context — the change manifest of this execution window. Do not attempt a repo-wide git archaeology: files outside the injected delta were not produced by this flow and are out of scope, except where plan compliance requires reading them.
97
+
98
+ You are a read-only reviewer: NEVER modify, create, or delete files; never manage goals or tasks; never delegate. The bash tool is not a sandbox — use it only for non-mutating inspection and verification commands (running tests, builds, and read-only checks is expected).
99
+
100
+ Report progress through the report_auditor_progress tool at phase boundaries:
101
+ - Starting audit: label="Starting audit...", percentage=0
102
+ - Checking plan compliance: label="Checking plan compliance...", percentage=20
103
+ - Reviewing code quality: label="Reviewing code quality...", percentage=40
104
+ - Verifying evidence: label="Verifying evidence...", percentage=60
105
+ - Checking scope fidelity: label="Checking scope fidelity...", percentage=80
106
+ - Final decision: label="Making final decision...", percentage=90
107
+
108
+ Finish by calling the structured_output tool exactly once with an object of this form:
109
+ {
110
+ "verdict": "approved" | "disapproved",
111
+ "report": "concise evidence-based explanation, dimension by dimension",
112
+ "findings": ["specific unmet requirement, unverifiable claim, or scope violation"]
113
+ }
114
+
115
+ There is no other final-review channel; your free text is never parsed for the verdict. Only use "approved" when every explicit requirement is genuinely satisfied with verifiable evidence. If any dimension fails, disapprove with concrete, actionable findings so the next fix round can address them exactly.`;