@heihei0299/matt-skills 1.6.4-test.0 → 1.6.4-test.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/skills/tdd-implement/SKILL.md +8 -9
- package/.agents/skills/tdd-implement/references/orchestration.md +3 -3
- package/.agents/skills/tdd-implement/references/stages.md +32 -31
- package/README.md +20 -1
- package/package.json +3 -1
- package/scripts/codex-smoke.js +140 -0
- package/template/.agents/skills/tdd-implement/SKILL.md +8 -9
- package/template/.agents/skills/tdd-implement/references/orchestration.md +3 -3
- package/template/.agents/skills/tdd-implement/references/stages.md +32 -31
|
@@ -22,15 +22,14 @@ description: "Multi-task orchestrator: use when the user provides a spec/ticket
|
|
|
22
22
|
|
|
23
23
|
| Step | 做什么 | 完成条件(可验证) | 详规 |
|
|
24
24
|
|------|--------|-------------------|------|
|
|
25
|
-
| ① 理解需求 |
|
|
26
|
-
| ② 确认 Seams |
|
|
27
|
-
| ③ TDD 开发循环 | 逐 seam 红-绿循环(红→绿→typecheck
|
|
28
|
-
| ④
|
|
29
|
-
| ⑤ Code Review |
|
|
30
|
-
| ⑥ Commit |
|
|
31
|
-
| ⑦ 收尾 |
|
|
32
|
-
|
|
33
|
-
主代理串行时每 `task` 仍走上表 ①→⑦(每 issue 单独 `commit`,`code-review` + `commit-check` 双门禁逐 issue,全量由 A4 收敛)。
|
|
25
|
+
| ① 理解需求 | 读取入口并建立验证矩阵 | 需求无待决歧义,验证命令已确定 | [stages.md#阶段-①](references/stages.md#阶段-①理解需求) |
|
|
26
|
+
| ② 确认 Seams | 从明确 spec/ticket 生成 seams 与 Todo;详规列出的确认门槛例外(含破坏性操作) | seams/Todo 已生成且无待决歧义 | [stages.md#阶段-②](references/stages.md#阶段-②确认-seams测试接缝) |
|
|
27
|
+
| ③ TDD 开发循环 | 逐 seam 红-绿循环(红→绿→typecheck)串行推进 | 所有 seams 红-绿完成 + typecheck 通过 | [stages.md#阶段-③](references/stages.md#阶段-③tdd-开发循环) |
|
|
28
|
+
| ④ 最终全量测试 | 所有 issue 完成后按验证矩阵只运行一次全量命令;多 issue 由 A4 执行,单 spec 在 issue 收尾后执行 | 全量测试通过 | [stages.md#阶段-④](references/stages.md#阶段-④完整测试套件) |
|
|
29
|
+
| ⑤ Code Review | 每个 issue 恰好执行一次 Standards + Spec 双轴 review;findings 只做 targeted 修复,不再次 review | 每个 issue 的一次 review 已完成 | [stages.md#阶段-⑤](references/stages.md#阶段-⑤code-review) |
|
|
30
|
+
| ⑥ Commit | 运行一次最终 commit-check 门禁并提交 | commit 完成且历史校验通过 | [stages.md#阶段-⑥](references/stages.md#阶段-⑥commit) |
|
|
31
|
+
| ⑦ 收尾 | 复核门禁证据,处理 issue 总结与目录卫生 | 总结完成、工作区干净 | [stages.md#阶段-⑦](references/stages.md#阶段-⑦收尾文档对齐--issue-状态--实施总结) |
|
|
32
|
+
主代理串行时每个 `task` 先走 `①→②→③→⑤→⑥→⑦` 并单独 commit;所有 issue 完成后再执行阶段④全量收敛(单 spec 只有一个 issue,也在其收尾后执行一次)。
|
|
34
33
|
|
|
35
34
|
### 阶段间流转
|
|
36
35
|
|
|
@@ -45,8 +45,8 @@ Ln = 最后一层
|
|
|
45
45
|
```
|
|
46
46
|
for each 层 Li in L1..Ln:
|
|
47
47
|
for each issue in Li(按编号顺序):
|
|
48
|
-
主代理直接执行该 issue
|
|
49
|
-
①理解需求 →
|
|
48
|
+
主代理直接执行该 issue 的 issue 闭环:
|
|
49
|
+
①理解需求 → ②生成 seams/Todo → ③红-绿循环(每 cycle 后 typecheck)→ ⑤一次 code-review → ⑥commit-check + 单独 commit → ⑦收尾(Status: resolved + ## 实施总结 + map.md 指针如为 wayfinder 产物 + 目录卫生);④全量测试不在 issue 闭环内执行
|
|
50
50
|
产回执卡片(改动文件/测试结果/commit hash)并回写该 issue 文件后**强制更新 `progress.md` 该行**(`Status`/`Commit`/`Review`/`Tests`)后再取下一 issue
|
|
51
51
|
层收敛:该层全部 issue `Status: resolved` 且 `progress.md` 同步为 `done`、各自独立 commit 已落盘、相关测试通过、`git status` 卫生、历史校验通过,才进下一层
|
|
52
52
|
全部层串行完成后进入 A4
|
|
@@ -69,7 +69,7 @@ for each 层 Li in L1..Ln:
|
|
|
69
69
|
### A4. 全量收敛
|
|
70
70
|
|
|
71
71
|
全部层串行完成且各自层收敛通过后,执行:
|
|
72
|
-
1.
|
|
72
|
+
1. **全量测试套件**:这是多 issue 流程中唯一的全量回归点;全部层、全部 issue 串行完成后仅执行一次(失败修复后才允许必要重跑)
|
|
73
73
|
2. **历史校验**:`git merge-base --is-ancestor $BASE_HEAD HEAD`,失败即 `reflog` 恢复后重跑
|
|
74
74
|
3. **目录卫生**:`git status` 无 `[DEBUG-...]` 残留、无未跟踪临时文件
|
|
75
75
|
4. **汇总总结**:在会话输出汇总各 issue 的回执卡片关键信息(提交 hash / seams / 验收 checkbox / 测试结果 / 文档对齐);不另写汇总文件
|
|
@@ -24,13 +24,16 @@
|
|
|
24
24
|
### 操作
|
|
25
25
|
|
|
26
26
|
1. 完整读取入口(`spec` 或 `issue`)内容
|
|
27
|
-
2.
|
|
28
|
-
3.
|
|
27
|
+
2. 使用读取预算:按需读取 `CONTEXT.md` 的相关术语;ADR 只读与 spec、触及符号或失败证据相关的条目,不批量读取无关文档
|
|
28
|
+
3. 使用仓库规定的代码探索入口;探索结果包含完整源码时视为已读,不再次 `read` 同一文件,除非文件发生漂移或只返回调用路径
|
|
29
|
+
4. 如有歧义,先向用户澄清再继续;无歧义时直接进入阶段②
|
|
30
|
+
5. 建立一次验证矩阵:列出 targeted tests、typecheck、全量测试以及 spec 要求的 smoke、package 或 security checks,后续复用证据,避免等价命令重复执行
|
|
29
31
|
|
|
30
32
|
### 出口条件
|
|
31
33
|
|
|
32
34
|
- 能用自己的话复述需求
|
|
33
35
|
- 无未澄清的歧义
|
|
36
|
+
- 验证矩阵已建立,且每项命令/检查已有明确触发条件
|
|
34
37
|
|
|
35
38
|
### 边界
|
|
36
39
|
|
|
@@ -46,14 +49,14 @@
|
|
|
46
49
|
### 操作
|
|
47
50
|
|
|
48
51
|
1. 列出所有将要测试的公共接口(seams)
|
|
49
|
-
2. 每个 seam
|
|
50
|
-
3.
|
|
51
|
-
4.
|
|
52
|
-
5. seams
|
|
52
|
+
2. 每个 seam 包含:名称、输入、预期输出,以及对应的最小验证命令
|
|
53
|
+
3. spec/ticket 已给出明确验收标准时,直接生成 Todo 并展示精简 seam 卡片;不等待用户确认
|
|
54
|
+
4. 仅在歧义、验收缺口、范围变化、破坏性操作或互斥方案时暂停确认
|
|
55
|
+
5. seams 确认门槛满足后生成 todo 清单(每 seam 一个 todo,格式与状态机见 [Todo 规定](#todo-规定))
|
|
53
56
|
|
|
54
57
|
### 出口条件
|
|
55
58
|
|
|
56
|
-
-
|
|
59
|
+
- seams/Todo 已生成,且没有待决的歧义、验收缺口或需要用户选择的方案
|
|
57
60
|
|
|
58
61
|
### 边界
|
|
59
62
|
|
|
@@ -76,7 +79,7 @@
|
|
|
76
79
|
|
|
77
80
|
#### TDD 编排
|
|
78
81
|
|
|
79
|
-
|
|
82
|
+
**读取预算(TDD Reference Cache)**:在阶段③入口加载 tdd 技能的相关规则一次;每个 cycle 仅按当前 seam 定位需要的 [`tdd/tests.md`](.agents/skills/tdd/tests.md) 与 [`tdd/mocking.md`](.agents/skills/tdd/mocking.md) reference,不重复阅读全文。TDD 语义与测试规则以 [tdd 技能](.agents/skills/tdd/SKILL.md) 为唯一事实源,不再在此重写。
|
|
80
83
|
|
|
81
84
|
本阶段只执行编排:按阶段②生成的 todo 清单逐条推进(大小任务层次与 Subtodo 格式见 [Todo 规定](#todo-规定)),每完成一个 todo(红-绿 cycle + typecheck)立即更新其状态为 `done`,再进入下一个 todo。
|
|
82
85
|
|
|
@@ -135,19 +138,18 @@
|
|
|
135
138
|
|
|
136
139
|
### 入口条件
|
|
137
140
|
|
|
138
|
-
-
|
|
139
|
-
|
|
141
|
+
- 所有 issue 已完成其实现、targeted tests、typecheck、一次 code-review、commit 和收尾;多 issue 从 orchestration A4 进入,单 spec 在唯一 issue 收尾后进入
|
|
142
|
+
- 阶段④不是 issue 闭环步骤,不得在任一 issue 完成时提前执行
|
|
140
143
|
### 操作
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
144
|
+
1. 按阶段①建立的验证矩阵,运行仓库规范的唯一全量测试命令;正常路径只执行一次
|
|
145
|
+
2. 若失败,先运行失败测试或最小相关子集定位原因;修复对应 issue 后才重跑全量命令
|
|
146
|
+
3. 记录最终全量结果,不同时运行等价命令(例如 `npm test` 与其展开命令),除非本次改动了 package script 本身
|
|
147
|
+
4. 检查所有测试是否通过
|
|
145
148
|
### 出口条件
|
|
146
|
-
|
|
147
|
-
- 全部测试通过
|
|
148
|
-
|
|
149
|
+
- 全量测试通过
|
|
149
150
|
### 边界
|
|
150
|
-
-
|
|
151
|
+
- 多 issue 仅由 A4 在所有 issue 完成后执行;单 spec 在唯一 issue 收尾后执行
|
|
152
|
+
- 全量测试失败时回到失败 issue 的修复路径;修复后只做必要的定向诊断和全量重跑
|
|
151
153
|
|
|
152
154
|
---
|
|
153
155
|
|
|
@@ -155,16 +157,14 @@
|
|
|
155
157
|
|
|
156
158
|
### 入口条件
|
|
157
159
|
|
|
158
|
-
-
|
|
159
|
-
|
|
160
|
+
- 阶段③ targeted tests 和 typecheck 通过;阶段④全量测试尚未执行也不构成此阶段入口条件
|
|
160
161
|
### 操作
|
|
161
|
-
|
|
162
|
-
1. 调用 [code-review 技能](.agents/skills/code-review/SKILL.md) 按**双轴**审查当前 issue 的改动:
|
|
162
|
+
1. 每个 issue 恰好调用一次 [code-review 技能](.agents/skills/code-review/SKILL.md),按**双轴**审查当前 issue 的改动:
|
|
163
163
|
- **Standards 轴**:改动是否符合仓库文档化的编码标准(含 smell baseline 判断)
|
|
164
164
|
- **Spec 轴**:改动是否忠实实现来源 spec/issue(逐条对照验收要求)
|
|
165
|
-
-
|
|
166
|
-
2.
|
|
167
|
-
3.
|
|
165
|
+
- 两轴独立报告、**互不掩盖**;该 issue 不再次调用 code-review
|
|
166
|
+
2. 审查发现的问题按 [回退路由](#回退路由) 处理,并只重跑受影响的 targeted checks;修复不触发第二次 review
|
|
167
|
+
3. 记录该 issue 的一次 review 结果,通过后进入 commit 和收尾
|
|
168
168
|
|
|
169
169
|
### 出口条件
|
|
170
170
|
|
|
@@ -184,9 +184,10 @@
|
|
|
184
184
|
|
|
185
185
|
### 操作
|
|
186
186
|
|
|
187
|
-
1.
|
|
187
|
+
1. 在一次最终门禁中调用 [commit-check 技能](.agents/skills/commit-check/SKILL.md):完成三项检查——文档一致性、目录卫生、commit message;目录卫生包含敏感扫描,spec 要求时再执行 package dry-run 等必要检查
|
|
188
188
|
2. **历史校验**:commit 前执行 `git merge-base --is-ancestor $BASE_HEAD HEAD`,若为 false 说明历史被改写,立即经 `git reflog` 恢复 `BASE_HEAD` 后的提交,校验通过才继续
|
|
189
|
-
3.
|
|
189
|
+
3. 三项门禁、历史校验和必要检查全部通过才 commit;门禁证据保持为最终基线,未改文件不在 commit 后重复扫描或打包
|
|
190
|
+
4. 将工作提交到当前分支,附清晰的 commit message(单 issue 单提交,如 `feat(<feature>): <issue title> (#NN)`);多 issue 时每 issue 独立提交后才取下一 issue
|
|
190
191
|
|
|
191
192
|
### 出口条件
|
|
192
193
|
|
|
@@ -194,7 +195,7 @@
|
|
|
194
195
|
|
|
195
196
|
### 边界
|
|
196
197
|
|
|
197
|
-
- Commit message 格式与内容由 commit-check
|
|
198
|
+
- Commit message 格式与内容由 commit-check ③ 把关(描述变更内容而非过程)
|
|
198
199
|
- 每 issue 独立提交,主代理串行时一 issue 一 commit 后再进入下一 issue 的 ①
|
|
199
200
|
|
|
200
201
|
## 阶段 ⑦:收尾(文档对齐 + issue 状态 + 实施总结)
|
|
@@ -205,7 +206,7 @@
|
|
|
205
206
|
|
|
206
207
|
### 操作
|
|
207
208
|
|
|
208
|
-
1.
|
|
209
|
+
1. **复核文档对齐**:以阶段⑥ commit-check 已记录的 README/docs/config/package 对齐证据为准;本阶段只复核并记录“无需更新”或已更新文件,不重复读取、编辑或追加 commit。若证据缺失或不一致,标记阶段⑥门禁失败并停止收尾,不将 issue 标为 resolved。
|
|
209
210
|
2. 若本次实现有关联 issue/ticket(`.scratch/<feature-slug>/issues/`):先审查该 issue——从 issue 提取验收标准(无显式验收标准节时以其正文行为要求为准),逐条转写为 checkbox 清单并逐条验证:通过标 `- [x]`,未通过保留 `- [ ]` 并注明缺口(证据:文件:行号 / 测试名)。全部打勾后才允许下一步:
|
|
210
211
|
3. 将 `Status:` 行改为 `resolved`(无该行则追加),不改动 spec 与既有 Comments
|
|
211
212
|
4. 在 issue 文件底部追加实施总结(`## 实施总结` 标题):
|
|
@@ -246,7 +247,7 @@
|
|
|
246
247
|
### 拆分层级(大小任务层次)
|
|
247
248
|
|
|
248
249
|
1. **大任务**:Goal/Ticket——整个实现单元,对应一次完整的 tdd-implement 流程
|
|
249
|
-
2. **中任务**:Seam
|
|
250
|
+
2. **中任务**:Seam(阶段②生成)——一个红-绿循环单元,每 seam 一个 Todo
|
|
250
251
|
3. **小任务**:Todo——seam 内可独立验证、可勾选的执行单元(T1/T2/T3…)
|
|
251
252
|
4. **执行步**:Subtodo——Todo 内的串行步骤(红 → 绿 → typecheck),回合内逐步勾选推进
|
|
252
253
|
|
|
@@ -254,7 +255,7 @@
|
|
|
254
255
|
|
|
255
256
|
### Todo 清单格式
|
|
256
257
|
|
|
257
|
-
阶段② seams
|
|
258
|
+
阶段② seams 生成且确认门槛满足后立即生成 todo 清单,每个 seam 一个 todo:
|
|
258
259
|
|
|
259
260
|
- 编号:`T1`、`T2`、`T3`…
|
|
260
261
|
- 描述:seam 名称 + 输入 + 预期输出
|
package/README.md
CHANGED
|
@@ -92,6 +92,25 @@ git clone --depth 1 https://github.com/mattpocock/skills.git /tmp/mattpocock-ski
|
|
|
92
92
|
|
|
93
93
|
pi 下对应能力以内置工具或已装扩展为准(`AGENTS.md`「能力边界」已按此表述)。
|
|
94
94
|
|
|
95
|
+
## Codex CLI 支持
|
|
96
|
+
|
|
97
|
+
本仓库将 Codex CLI 作为一等本地 harness 支持。Codex 与 pi、opencode、Claude 共用项目级 `.agents/skills/`,项目级 `AGENTS.md` 继续作为通用行为路由和约束入口。
|
|
98
|
+
|
|
99
|
+
- **项目级技能**:`.agents/skills/`(唯一共享源)
|
|
100
|
+
- **全局技能**:`~/.codex/skills/`
|
|
101
|
+
- **不创建**:项目级 `.codex/skills/` 副本;Codex 技能不单独分叉
|
|
102
|
+
- **安装映射**:`--tools codex` 使用 `.agents/skills/`,`--global --tools codex` 使用 `~/.codex/skills/`
|
|
103
|
+
|
|
104
|
+
使用真实 Codex CLI 验证支持:
|
|
105
|
+
|
|
106
|
+
```sh
|
|
107
|
+
npm run codex:smoke # 默认 SKIP,不需要 Codex 凭证
|
|
108
|
+
CODEX_E2E=1 npm run codex:smoke # 显式运行真实 smoke test
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
真实 smoke test 使用临时 fixture、ephemeral 会话、read-only sandbox 和 JSONL 输出,验证 `AGENTS.md` 与最小 `codex-probe` skill 的 sentinel。结果分为 `PASS`、`SKIP`、`FAIL_ENV` 和 `FAIL_CONTRACT`;环境问题与契约失败分别返回非零退出码。运行结果会记录 `codex --version`,但不绑定最低 CLI 版本。
|
|
112
|
+
|
|
113
|
+
本期不包含 Codex Cloud、Codex-specific commands、plugins 或 MCP 配置。
|
|
95
114
|
## harness 目录结构
|
|
96
115
|
|
|
97
116
|
两个 harness 的技能加载目录结构如下(本项目只分发项目级目录,全局目录由用户自备):
|
|
@@ -174,7 +193,7 @@ npm publish
|
|
|
174
193
|
```
|
|
175
194
|
|
|
176
195
|
- `prepublishOnly` 自动跑全量测试(`node --test test/*.test.js`)
|
|
177
|
-
- 发布内容 = `bin/` + `template/` + `.agents/skills/` + `README.md`,由 `package.json` 的 `files` 白名单控制,`npm pack` 可预览
|
|
196
|
+
- 发布内容 = `bin/` + `template/` + `.agents/skills/` + `scripts/` + `config/` + `README.md`,由 `package.json` 的 `files` 白名单控制,`npm pack` 可预览
|
|
178
197
|
- `template/` 与 `.agents/skills/` 是包内容:改动后需重新发版才对目标仓库生效
|
|
179
198
|
|
|
180
199
|
## 开发
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@heihei0299/matt-skills",
|
|
3
|
-
"version": "1.6.4-test.
|
|
3
|
+
"version": "1.6.4-test.1",
|
|
4
4
|
"description": "Agent skills + 项目配置模板:一条命令初始化 opencode / pi-agent 项目(含 mattpocock/skills 上游技能)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"template/",
|
|
12
12
|
".agents/skills/",
|
|
13
13
|
"scripts/sync-upstream.js",
|
|
14
|
+
"scripts/codex-smoke.js",
|
|
14
15
|
"config/proprietary.json",
|
|
15
16
|
"config/engineering.json",
|
|
16
17
|
"README.md"
|
|
@@ -18,6 +19,7 @@
|
|
|
18
19
|
"scripts": {
|
|
19
20
|
"test": "node --test test/*.test.js",
|
|
20
21
|
"prepublishOnly": "node --test test/*.test.js",
|
|
22
|
+
"codex:smoke": "node scripts/codex-smoke.js",
|
|
21
23
|
"build:template": "node scripts/build-template.js"
|
|
22
24
|
},
|
|
23
25
|
"dependencies": {
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import os from 'node:os';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
import { spawnSync } from 'node:child_process';
|
|
7
|
+
|
|
8
|
+
const AGENTS_SENTINEL = 'MATT_CODEX_AGENTS_SENTINEL=agents-loaded';
|
|
9
|
+
const SKILL_SENTINEL = 'MATT_CODEX_SKILL_SENTINEL=skill-loaded';
|
|
10
|
+
|
|
11
|
+
function printResult(kind, message = '') {
|
|
12
|
+
process.stdout.write(`${kind}${message ? `: ${message}` : ''}\n`);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function commandOutput(result) {
|
|
16
|
+
return [result.stdout, result.stderr, result.error?.message]
|
|
17
|
+
.filter(Boolean)
|
|
18
|
+
.join('\n')
|
|
19
|
+
.trim();
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function detectCodex() {
|
|
23
|
+
const result = spawnSync('codex', ['--version'], { encoding: 'utf8' });
|
|
24
|
+
if (result.error || result.status !== 0) {
|
|
25
|
+
return { ok: false, reason: `Codex CLI unavailable: ${commandOutput(result) || 'codex was not found'}` };
|
|
26
|
+
}
|
|
27
|
+
return { ok: true, version: commandOutput(result).split(/\r?\n/, 1)[0] };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function createFixture() {
|
|
31
|
+
const root = fs.mkdtempSync(path.join(os.tmpdir(), 'matt-skills-codex-smoke-'));
|
|
32
|
+
const skillDir = path.join(root, '.agents', 'skills', 'codex-probe');
|
|
33
|
+
fs.mkdirSync(path.join(skillDir, 'agents'), { recursive: true });
|
|
34
|
+
fs.writeFileSync(path.join(root, 'AGENTS.md'), [
|
|
35
|
+
'# Codex smoke fixture',
|
|
36
|
+
'',
|
|
37
|
+
`When responding to the smoke probe, include the exact marker ${AGENTS_SENTINEL}.`,
|
|
38
|
+
].join('\n') + '\n');
|
|
39
|
+
fs.writeFileSync(path.join(skillDir, 'SKILL.md'), [
|
|
40
|
+
'---',
|
|
41
|
+
'name: codex-probe',
|
|
42
|
+
'description: Use when validating Codex project skill discovery.',
|
|
43
|
+
'---',
|
|
44
|
+
'',
|
|
45
|
+
`When the probe asks you to use this skill, include the exact marker ${SKILL_SENTINEL}.`,
|
|
46
|
+
].join('\n') + '\n');
|
|
47
|
+
fs.writeFileSync(path.join(skillDir, 'agents', 'openai.yaml'), [
|
|
48
|
+
'interface:',
|
|
49
|
+
' display_name: Codex Probe',
|
|
50
|
+
' short_description: Validate Codex skill discovery',
|
|
51
|
+
].join('\n') + '\n');
|
|
52
|
+
return root;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function finalAgentMessage(stdout) {
|
|
56
|
+
const events = [];
|
|
57
|
+
let malformed = false;
|
|
58
|
+
for (const line of stdout.split(/\r?\n/)) {
|
|
59
|
+
if (!line.trim()) continue;
|
|
60
|
+
try {
|
|
61
|
+
events.push(JSON.parse(line));
|
|
62
|
+
} catch {
|
|
63
|
+
malformed = true;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
const turnCompleted = events.at(-1)?.type === 'turn.completed';
|
|
67
|
+
let text = '';
|
|
68
|
+
let agentMessageIndex = -1;
|
|
69
|
+
events.forEach((event, index) => {
|
|
70
|
+
if (event?.item?.type === 'agent_message' && typeof event.item.text === 'string') {
|
|
71
|
+
text = event.item.text;
|
|
72
|
+
agentMessageIndex = index;
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
return {
|
|
76
|
+
text,
|
|
77
|
+
completed: turnCompleted && agentMessageIndex >= 0 && agentMessageIndex < events.length - 1,
|
|
78
|
+
malformed,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function runCodex(fixture) {
|
|
83
|
+
const prompt = [
|
|
84
|
+
'Run the Codex support probe.',
|
|
85
|
+
'Use the codex-probe skill explicitly if it is available.',
|
|
86
|
+
'Follow the project AGENTS.md instructions.',
|
|
87
|
+
'In the final response state the exact markers required by the discovered project instructions, and do not modify files.',
|
|
88
|
+
].join(' ');
|
|
89
|
+
return spawnSync('codex', [
|
|
90
|
+
'exec', '--ephemeral', '--sandbox', 'read-only', '--json',
|
|
91
|
+
'--skip-git-repo-check', prompt,
|
|
92
|
+
], { cwd: fixture, encoding: 'utf8', maxBuffer: 10 * 1024 * 1024 });
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
function run() {
|
|
96
|
+
if (process.env.CODEX_E2E !== '1') {
|
|
97
|
+
printResult('SKIP', 'set CODEX_E2E=1 to run the real Codex smoke test');
|
|
98
|
+
return 0;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const detected = detectCodex();
|
|
102
|
+
if (!detected.ok) {
|
|
103
|
+
printResult('FAIL_ENV', detected.reason);
|
|
104
|
+
return 1;
|
|
105
|
+
}
|
|
106
|
+
process.stdout.write(`Codex version: ${detected.version}\n`);
|
|
107
|
+
|
|
108
|
+
let fixture;
|
|
109
|
+
try {
|
|
110
|
+
fixture = createFixture();
|
|
111
|
+
const result = runCodex(fixture);
|
|
112
|
+
const final = finalAgentMessage(result.stdout || '');
|
|
113
|
+
if (final.malformed) {
|
|
114
|
+
printResult('FAIL_ENV', 'malformed JSONL event');
|
|
115
|
+
return 1;
|
|
116
|
+
}
|
|
117
|
+
if (!final.completed) {
|
|
118
|
+
printResult('FAIL_ENV', commandOutput(result) || 'Codex response did not contain a completed final response event');
|
|
119
|
+
return 1;
|
|
120
|
+
}
|
|
121
|
+
const missing = [
|
|
122
|
+
!final.text.includes(AGENTS_SENTINEL) && 'AGENTS.md sentinel',
|
|
123
|
+
!final.text.includes(SKILL_SENTINEL) && 'skill sentinel',
|
|
124
|
+
].filter(Boolean);
|
|
125
|
+
if (missing.length) {
|
|
126
|
+
printResult('FAIL_CONTRACT', `missing ${missing.join(' and ')}`);
|
|
127
|
+
return 1;
|
|
128
|
+
}
|
|
129
|
+
if (result.error || result.status !== 0) {
|
|
130
|
+
printResult('FAIL_ENV', commandOutput(result) || 'Codex execution failed');
|
|
131
|
+
return 1;
|
|
132
|
+
}
|
|
133
|
+
printResult('PASS', 'AGENTS.md and codex-probe skill sentinels verified');
|
|
134
|
+
return 0;
|
|
135
|
+
} finally {
|
|
136
|
+
if (fixture) fs.rmSync(fixture, { recursive: true, force: true });
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
process.exitCode = run();
|
|
@@ -22,15 +22,14 @@ description: "Multi-task orchestrator: use when the user provides a spec/ticket
|
|
|
22
22
|
|
|
23
23
|
| Step | 做什么 | 完成条件(可验证) | 详规 |
|
|
24
24
|
|------|--------|-------------------|------|
|
|
25
|
-
| ① 理解需求 |
|
|
26
|
-
| ② 确认 Seams |
|
|
27
|
-
| ③ TDD 开发循环 | 逐 seam 红-绿循环(红→绿→typecheck
|
|
28
|
-
| ④
|
|
29
|
-
| ⑤ Code Review |
|
|
30
|
-
| ⑥ Commit |
|
|
31
|
-
| ⑦ 收尾 |
|
|
32
|
-
|
|
33
|
-
主代理串行时每 `task` 仍走上表 ①→⑦(每 issue 单独 `commit`,`code-review` + `commit-check` 双门禁逐 issue,全量由 A4 收敛)。
|
|
25
|
+
| ① 理解需求 | 读取入口并建立验证矩阵 | 需求无待决歧义,验证命令已确定 | [stages.md#阶段-①](references/stages.md#阶段-①理解需求) |
|
|
26
|
+
| ② 确认 Seams | 从明确 spec/ticket 生成 seams 与 Todo;详规列出的确认门槛例外(含破坏性操作) | seams/Todo 已生成且无待决歧义 | [stages.md#阶段-②](references/stages.md#阶段-②确认-seams测试接缝) |
|
|
27
|
+
| ③ TDD 开发循环 | 逐 seam 红-绿循环(红→绿→typecheck)串行推进 | 所有 seams 红-绿完成 + typecheck 通过 | [stages.md#阶段-③](references/stages.md#阶段-③tdd-开发循环) |
|
|
28
|
+
| ④ 最终全量测试 | 所有 issue 完成后按验证矩阵只运行一次全量命令;多 issue 由 A4 执行,单 spec 在 issue 收尾后执行 | 全量测试通过 | [stages.md#阶段-④](references/stages.md#阶段-④完整测试套件) |
|
|
29
|
+
| ⑤ Code Review | 每个 issue 恰好执行一次 Standards + Spec 双轴 review;findings 只做 targeted 修复,不再次 review | 每个 issue 的一次 review 已完成 | [stages.md#阶段-⑤](references/stages.md#阶段-⑤code-review) |
|
|
30
|
+
| ⑥ Commit | 运行一次最终 commit-check 门禁并提交 | commit 完成且历史校验通过 | [stages.md#阶段-⑥](references/stages.md#阶段-⑥commit) |
|
|
31
|
+
| ⑦ 收尾 | 复核门禁证据,处理 issue 总结与目录卫生 | 总结完成、工作区干净 | [stages.md#阶段-⑦](references/stages.md#阶段-⑦收尾文档对齐--issue-状态--实施总结) |
|
|
32
|
+
主代理串行时每个 `task` 先走 `①→②→③→⑤→⑥→⑦` 并单独 commit;所有 issue 完成后再执行阶段④全量收敛(单 spec 只有一个 issue,也在其收尾后执行一次)。
|
|
34
33
|
|
|
35
34
|
### 阶段间流转
|
|
36
35
|
|
|
@@ -45,8 +45,8 @@ Ln = 最后一层
|
|
|
45
45
|
```
|
|
46
46
|
for each 层 Li in L1..Ln:
|
|
47
47
|
for each issue in Li(按编号顺序):
|
|
48
|
-
主代理直接执行该 issue
|
|
49
|
-
①理解需求 →
|
|
48
|
+
主代理直接执行该 issue 的 issue 闭环:
|
|
49
|
+
①理解需求 → ②生成 seams/Todo → ③红-绿循环(每 cycle 后 typecheck)→ ⑤一次 code-review → ⑥commit-check + 单独 commit → ⑦收尾(Status: resolved + ## 实施总结 + map.md 指针如为 wayfinder 产物 + 目录卫生);④全量测试不在 issue 闭环内执行
|
|
50
50
|
产回执卡片(改动文件/测试结果/commit hash)并回写该 issue 文件后**强制更新 `progress.md` 该行**(`Status`/`Commit`/`Review`/`Tests`)后再取下一 issue
|
|
51
51
|
层收敛:该层全部 issue `Status: resolved` 且 `progress.md` 同步为 `done`、各自独立 commit 已落盘、相关测试通过、`git status` 卫生、历史校验通过,才进下一层
|
|
52
52
|
全部层串行完成后进入 A4
|
|
@@ -69,7 +69,7 @@ for each 层 Li in L1..Ln:
|
|
|
69
69
|
### A4. 全量收敛
|
|
70
70
|
|
|
71
71
|
全部层串行完成且各自层收敛通过后,执行:
|
|
72
|
-
1.
|
|
72
|
+
1. **全量测试套件**:这是多 issue 流程中唯一的全量回归点;全部层、全部 issue 串行完成后仅执行一次(失败修复后才允许必要重跑)
|
|
73
73
|
2. **历史校验**:`git merge-base --is-ancestor $BASE_HEAD HEAD`,失败即 `reflog` 恢复后重跑
|
|
74
74
|
3. **目录卫生**:`git status` 无 `[DEBUG-...]` 残留、无未跟踪临时文件
|
|
75
75
|
4. **汇总总结**:在会话输出汇总各 issue 的回执卡片关键信息(提交 hash / seams / 验收 checkbox / 测试结果 / 文档对齐);不另写汇总文件
|
|
@@ -24,13 +24,16 @@
|
|
|
24
24
|
### 操作
|
|
25
25
|
|
|
26
26
|
1. 完整读取入口(`spec` 或 `issue`)内容
|
|
27
|
-
2.
|
|
28
|
-
3.
|
|
27
|
+
2. 使用读取预算:按需读取 `CONTEXT.md` 的相关术语;ADR 只读与 spec、触及符号或失败证据相关的条目,不批量读取无关文档
|
|
28
|
+
3. 使用仓库规定的代码探索入口;探索结果包含完整源码时视为已读,不再次 `read` 同一文件,除非文件发生漂移或只返回调用路径
|
|
29
|
+
4. 如有歧义,先向用户澄清再继续;无歧义时直接进入阶段②
|
|
30
|
+
5. 建立一次验证矩阵:列出 targeted tests、typecheck、全量测试以及 spec 要求的 smoke、package 或 security checks,后续复用证据,避免等价命令重复执行
|
|
29
31
|
|
|
30
32
|
### 出口条件
|
|
31
33
|
|
|
32
34
|
- 能用自己的话复述需求
|
|
33
35
|
- 无未澄清的歧义
|
|
36
|
+
- 验证矩阵已建立,且每项命令/检查已有明确触发条件
|
|
34
37
|
|
|
35
38
|
### 边界
|
|
36
39
|
|
|
@@ -46,14 +49,14 @@
|
|
|
46
49
|
### 操作
|
|
47
50
|
|
|
48
51
|
1. 列出所有将要测试的公共接口(seams)
|
|
49
|
-
2. 每个 seam
|
|
50
|
-
3.
|
|
51
|
-
4.
|
|
52
|
-
5. seams
|
|
52
|
+
2. 每个 seam 包含:名称、输入、预期输出,以及对应的最小验证命令
|
|
53
|
+
3. spec/ticket 已给出明确验收标准时,直接生成 Todo 并展示精简 seam 卡片;不等待用户确认
|
|
54
|
+
4. 仅在歧义、验收缺口、范围变化、破坏性操作或互斥方案时暂停确认
|
|
55
|
+
5. seams 确认门槛满足后生成 todo 清单(每 seam 一个 todo,格式与状态机见 [Todo 规定](#todo-规定))
|
|
53
56
|
|
|
54
57
|
### 出口条件
|
|
55
58
|
|
|
56
|
-
-
|
|
59
|
+
- seams/Todo 已生成,且没有待决的歧义、验收缺口或需要用户选择的方案
|
|
57
60
|
|
|
58
61
|
### 边界
|
|
59
62
|
|
|
@@ -76,7 +79,7 @@
|
|
|
76
79
|
|
|
77
80
|
#### TDD 编排
|
|
78
81
|
|
|
79
|
-
|
|
82
|
+
**读取预算(TDD Reference Cache)**:在阶段③入口加载 tdd 技能的相关规则一次;每个 cycle 仅按当前 seam 定位需要的 [`tdd/tests.md`](.agents/skills/tdd/tests.md) 与 [`tdd/mocking.md`](.agents/skills/tdd/mocking.md) reference,不重复阅读全文。TDD 语义与测试规则以 [tdd 技能](.agents/skills/tdd/SKILL.md) 为唯一事实源,不再在此重写。
|
|
80
83
|
|
|
81
84
|
本阶段只执行编排:按阶段②生成的 todo 清单逐条推进(大小任务层次与 Subtodo 格式见 [Todo 规定](#todo-规定)),每完成一个 todo(红-绿 cycle + typecheck)立即更新其状态为 `done`,再进入下一个 todo。
|
|
82
85
|
|
|
@@ -135,19 +138,18 @@
|
|
|
135
138
|
|
|
136
139
|
### 入口条件
|
|
137
140
|
|
|
138
|
-
-
|
|
139
|
-
|
|
141
|
+
- 所有 issue 已完成其实现、targeted tests、typecheck、一次 code-review、commit 和收尾;多 issue 从 orchestration A4 进入,单 spec 在唯一 issue 收尾后进入
|
|
142
|
+
- 阶段④不是 issue 闭环步骤,不得在任一 issue 完成时提前执行
|
|
140
143
|
### 操作
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
144
|
+
1. 按阶段①建立的验证矩阵,运行仓库规范的唯一全量测试命令;正常路径只执行一次
|
|
145
|
+
2. 若失败,先运行失败测试或最小相关子集定位原因;修复对应 issue 后才重跑全量命令
|
|
146
|
+
3. 记录最终全量结果,不同时运行等价命令(例如 `npm test` 与其展开命令),除非本次改动了 package script 本身
|
|
147
|
+
4. 检查所有测试是否通过
|
|
145
148
|
### 出口条件
|
|
146
|
-
|
|
147
|
-
- 全部测试通过
|
|
148
|
-
|
|
149
|
+
- 全量测试通过
|
|
149
150
|
### 边界
|
|
150
|
-
-
|
|
151
|
+
- 多 issue 仅由 A4 在所有 issue 完成后执行;单 spec 在唯一 issue 收尾后执行
|
|
152
|
+
- 全量测试失败时回到失败 issue 的修复路径;修复后只做必要的定向诊断和全量重跑
|
|
151
153
|
|
|
152
154
|
---
|
|
153
155
|
|
|
@@ -155,16 +157,14 @@
|
|
|
155
157
|
|
|
156
158
|
### 入口条件
|
|
157
159
|
|
|
158
|
-
-
|
|
159
|
-
|
|
160
|
+
- 阶段③ targeted tests 和 typecheck 通过;阶段④全量测试尚未执行也不构成此阶段入口条件
|
|
160
161
|
### 操作
|
|
161
|
-
|
|
162
|
-
1. 调用 [code-review 技能](.agents/skills/code-review/SKILL.md) 按**双轴**审查当前 issue 的改动:
|
|
162
|
+
1. 每个 issue 恰好调用一次 [code-review 技能](.agents/skills/code-review/SKILL.md),按**双轴**审查当前 issue 的改动:
|
|
163
163
|
- **Standards 轴**:改动是否符合仓库文档化的编码标准(含 smell baseline 判断)
|
|
164
164
|
- **Spec 轴**:改动是否忠实实现来源 spec/issue(逐条对照验收要求)
|
|
165
|
-
-
|
|
166
|
-
2.
|
|
167
|
-
3.
|
|
165
|
+
- 两轴独立报告、**互不掩盖**;该 issue 不再次调用 code-review
|
|
166
|
+
2. 审查发现的问题按 [回退路由](#回退路由) 处理,并只重跑受影响的 targeted checks;修复不触发第二次 review
|
|
167
|
+
3. 记录该 issue 的一次 review 结果,通过后进入 commit 和收尾
|
|
168
168
|
|
|
169
169
|
### 出口条件
|
|
170
170
|
|
|
@@ -184,9 +184,10 @@
|
|
|
184
184
|
|
|
185
185
|
### 操作
|
|
186
186
|
|
|
187
|
-
1.
|
|
187
|
+
1. 在一次最终门禁中调用 [commit-check 技能](.agents/skills/commit-check/SKILL.md):完成三项检查——文档一致性、目录卫生、commit message;目录卫生包含敏感扫描,spec 要求时再执行 package dry-run 等必要检查
|
|
188
188
|
2. **历史校验**:commit 前执行 `git merge-base --is-ancestor $BASE_HEAD HEAD`,若为 false 说明历史被改写,立即经 `git reflog` 恢复 `BASE_HEAD` 后的提交,校验通过才继续
|
|
189
|
-
3.
|
|
189
|
+
3. 三项门禁、历史校验和必要检查全部通过才 commit;门禁证据保持为最终基线,未改文件不在 commit 后重复扫描或打包
|
|
190
|
+
4. 将工作提交到当前分支,附清晰的 commit message(单 issue 单提交,如 `feat(<feature>): <issue title> (#NN)`);多 issue 时每 issue 独立提交后才取下一 issue
|
|
190
191
|
|
|
191
192
|
### 出口条件
|
|
192
193
|
|
|
@@ -194,7 +195,7 @@
|
|
|
194
195
|
|
|
195
196
|
### 边界
|
|
196
197
|
|
|
197
|
-
- Commit message 格式与内容由 commit-check
|
|
198
|
+
- Commit message 格式与内容由 commit-check ③ 把关(描述变更内容而非过程)
|
|
198
199
|
- 每 issue 独立提交,主代理串行时一 issue 一 commit 后再进入下一 issue 的 ①
|
|
199
200
|
|
|
200
201
|
## 阶段 ⑦:收尾(文档对齐 + issue 状态 + 实施总结)
|
|
@@ -205,7 +206,7 @@
|
|
|
205
206
|
|
|
206
207
|
### 操作
|
|
207
208
|
|
|
208
|
-
1.
|
|
209
|
+
1. **复核文档对齐**:以阶段⑥ commit-check 已记录的 README/docs/config/package 对齐证据为准;本阶段只复核并记录“无需更新”或已更新文件,不重复读取、编辑或追加 commit。若证据缺失或不一致,标记阶段⑥门禁失败并停止收尾,不将 issue 标为 resolved。
|
|
209
210
|
2. 若本次实现有关联 issue/ticket(`.scratch/<feature-slug>/issues/`):先审查该 issue——从 issue 提取验收标准(无显式验收标准节时以其正文行为要求为准),逐条转写为 checkbox 清单并逐条验证:通过标 `- [x]`,未通过保留 `- [ ]` 并注明缺口(证据:文件:行号 / 测试名)。全部打勾后才允许下一步:
|
|
210
211
|
3. 将 `Status:` 行改为 `resolved`(无该行则追加),不改动 spec 与既有 Comments
|
|
211
212
|
4. 在 issue 文件底部追加实施总结(`## 实施总结` 标题):
|
|
@@ -246,7 +247,7 @@
|
|
|
246
247
|
### 拆分层级(大小任务层次)
|
|
247
248
|
|
|
248
249
|
1. **大任务**:Goal/Ticket——整个实现单元,对应一次完整的 tdd-implement 流程
|
|
249
|
-
2. **中任务**:Seam
|
|
250
|
+
2. **中任务**:Seam(阶段②生成)——一个红-绿循环单元,每 seam 一个 Todo
|
|
250
251
|
3. **小任务**:Todo——seam 内可独立验证、可勾选的执行单元(T1/T2/T3…)
|
|
251
252
|
4. **执行步**:Subtodo——Todo 内的串行步骤(红 → 绿 → typecheck),回合内逐步勾选推进
|
|
252
253
|
|
|
@@ -254,7 +255,7 @@
|
|
|
254
255
|
|
|
255
256
|
### Todo 清单格式
|
|
256
257
|
|
|
257
|
-
阶段② seams
|
|
258
|
+
阶段② seams 生成且确认门槛满足后立即生成 todo 清单,每个 seam 一个 todo:
|
|
258
259
|
|
|
259
260
|
- 编号:`T1`、`T2`、`T3`…
|
|
260
261
|
- 描述:seam 名称 + 输入 + 预期输出
|