@ai-content-space/loopx 0.1.5 → 0.1.7
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/README.md +24 -14
- package/README.zh-CN.md +24 -14
- package/package.json +1 -1
- package/plugins/loopx/.codex-plugin/plugin.json +1 -1
- package/plugins/loopx/skills/archive/SKILL.md +7 -4
- package/plugins/loopx/skills/autopilot/SKILL.md +1 -1
- package/plugins/loopx/skills/build/SKILL.md +3 -1
- package/plugins/loopx/skills/clarify/SKILL.md +6 -3
- package/plugins/loopx/skills/debug/SKILL.md +1 -1
- package/plugins/loopx/skills/go-style/SKILL.md +1 -1
- package/plugins/loopx/skills/kratos/SKILL.md +1 -1
- package/plugins/loopx/skills/plan/SKILL.md +34 -1
- package/plugins/loopx/skills/review/SKILL.md +4 -1
- package/plugins/loopx/skills/tdd/SKILL.md +1 -1
- package/plugins/loopx/skills/verify/SKILL.md +1 -1
- package/skills/archive/SKILL.md +7 -4
- package/skills/autopilot/SKILL.md +1 -1
- package/skills/build/SKILL.md +3 -1
- package/skills/clarify/SKILL.md +6 -3
- package/skills/debug/SKILL.md +1 -1
- package/skills/go-style/SKILL.md +1 -1
- package/skills/kratos/SKILL.md +1 -1
- package/skills/plan/SKILL.md +34 -1
- package/skills/review/SKILL.md +4 -1
- package/skills/tdd/SKILL.md +1 -1
- package/skills/verify/SKILL.md +1 -1
- package/src/cli.mjs +2 -0
- package/src/context-manifest.mjs +4 -0
- package/src/plan-runtime.mjs +1 -0
- package/src/workflow.mjs +292 -3
package/README.md
CHANGED
|
@@ -121,18 +121,14 @@ loopx approve my-task --from build --to review
|
|
|
121
121
|
loopx review my-task
|
|
122
122
|
```
|
|
123
123
|
|
|
124
|
-
Complete an approved review:
|
|
125
|
-
|
|
126
|
-
```bash
|
|
127
|
-
loopx approve my-task --from review --to done
|
|
128
|
-
```
|
|
129
|
-
|
|
130
124
|
Archive accepted behavior into long-lived specs:
|
|
131
125
|
|
|
132
126
|
```text
|
|
133
127
|
$archive my-task
|
|
134
128
|
```
|
|
135
129
|
|
|
130
|
+
When review has approved the workflow and routed it to `done`, `$archive` consumes the pending `review -> done` completion transition before syncing specs. CLI-only operators can still run `loopx approve my-task --from review --to done` followed by `loopx archive my-task` explicitly.
|
|
131
|
+
|
|
136
132
|
Check status:
|
|
137
133
|
|
|
138
134
|
```bash
|
|
@@ -140,7 +136,15 @@ loopx status my-task
|
|
|
140
136
|
loopx status my-task --json
|
|
141
137
|
```
|
|
142
138
|
|
|
143
|
-
|
|
139
|
+
Planning also writes derived HTML reading views so the plan can be reviewed without another command:
|
|
140
|
+
|
|
141
|
+
```text
|
|
142
|
+
.loopx/workflows/my-task/view/index.html
|
|
143
|
+
.loopx/workflows/my-task/view/plan.html
|
|
144
|
+
.loopx/views/index.html
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Regenerate derived HTML reading views at any time:
|
|
144
148
|
|
|
145
149
|
```bash
|
|
146
150
|
loopx render my-task
|
|
@@ -174,7 +178,7 @@ loopx repair-install
|
|
|
174
178
|
|
|
175
179
|
The CLI is primarily for runtime, debugging, status inspection, and maintenance. The normal Codex-facing product surface is the bundled skill set, for example `$clarify`, `$plan`, `$build`, `$review`, `$archive`, `$autopilot`, `$debug`, `$tdd`, `$verify`, `$go-style`, and `$kratos`.
|
|
176
180
|
|
|
177
|
-
`loopx status` remains a CLI/runtime diagnostic command rather than a Codex skill. `loopx
|
|
181
|
+
`loopx status` remains a CLI/runtime diagnostic command rather than a Codex skill. `loopx plan` automatically writes human-readable HTML views for the planned workflow and workspace index. `loopx render` regenerates those views from existing runtime artifacts; without a slug it renders every non-legacy workflow plus the workspace index. Markdown and JSON remain the canonical machine-readable and editable sources.
|
|
178
182
|
|
|
179
183
|
## Skill Routing and Governance
|
|
180
184
|
|
|
@@ -223,6 +227,11 @@ Main artifacts:
|
|
|
223
227
|
- `.loopx/workflows/<slug>/architecture.md`
|
|
224
228
|
- `.loopx/workflows/<slug>/development-plan.md`
|
|
225
229
|
- `.loopx/workflows/<slug>/test-plan.md`
|
|
230
|
+
- `.loopx/workflows/<slug>/requirement-traceability.md`
|
|
231
|
+
|
|
232
|
+
After a successful plan run, loopx also writes derived reading views at `.loopx/workflows/<slug>/view/index.html`, `.loopx/workflows/<slug>/view/plan.html`, and `.loopx/views/index.html`. Use these for human review; keep Markdown and JSON as the editable sources of truth.
|
|
233
|
+
|
|
234
|
+
`requirement-traceability.md` maps the original source requirements or PRD to the generated plan package, change delta, vertical slices, and tests. If explicit source coverage items or source requirement tables are not covered by the plan package, `plan` stays blocked before build approval.
|
|
226
235
|
|
|
227
236
|
`spec-delta.md` uses requirement deltas: `## ADDED Requirements`, `## MODIFIED Requirements`, `## REMOVED Requirements`, and `## RENAMED Requirements`. ADDED and MODIFIED entries are full `### Requirement:` blocks with SHALL/MUST language and `#### Scenario:` examples, so archive can merge them into the current long-lived spec state.
|
|
228
237
|
|
|
@@ -258,13 +267,13 @@ The approved PRD, test spec, previous execution record, and workflow-local plan
|
|
|
258
267
|
|
|
259
268
|
The user-facing review result is expected to be written in Chinese.
|
|
260
269
|
|
|
261
|
-
If review approves the run
|
|
270
|
+
If review approves the run and routes it to `done`, the normal Codex-facing next step is `$archive <slug>`; archive consumes the pending completion transition and then syncs specs. CLI-only operators may still explicitly run `loopx approve <slug> --from review --to done` before `loopx archive <slug>`. If review requests implementation changes, run `$build --from-review .loopx/workflows/<slug>/review-report.md`. Plan and clarify rollbacks still use `$plan <slug>` or `$clarify <slug>` when the review finding says the plan or requirements are wrong.
|
|
262
271
|
|
|
263
272
|
The architecture-smell lane is part of review; it does not add a new stage. It records findings under `review-support/architecture-smell.json` and only blocks when module seams, testability, domain vocabulary, or plan architecture assumptions are materially wrong.
|
|
264
273
|
|
|
265
274
|
### archive
|
|
266
275
|
|
|
267
|
-
`archive` consumes a completed workflow and syncs the approved `.loopx/changes/active/<change-id>/spec-delta.md` into long-lived domain specs under `.loopx/specs/`. The change folder is moved to:
|
|
276
|
+
`archive` consumes a completed workflow, or a review-approved workflow whose only pending route is `done`, and syncs the approved `.loopx/changes/active/<change-id>/spec-delta.md` into long-lived domain specs under `.loopx/specs/`. The change folder is moved to:
|
|
268
277
|
|
|
269
278
|
```text
|
|
270
279
|
.loopx/changes/archive/<change-id>/
|
|
@@ -367,7 +376,7 @@ loopx writes runtime state under `.loopx/` in the current project:
|
|
|
367
376
|
|
|
368
377
|
`intake` contains immutable clarify snapshots for a specific request. `workflows` contains the active runtime working set. `changes` contains the proposed change delta for the current request. `specs` contains accepted long-lived behavior after archive.
|
|
369
378
|
|
|
370
|
-
`views/` and `workflows/<slug>/view/` are derived HTML reading views
|
|
379
|
+
`views/` and `workflows/<slug>/view/` are derived HTML reading views written after `plan` and regenerated by `loopx render`. They are for human review only and are safe to regenerate; agents and tooling should continue to read and update the Markdown and JSON artifacts.
|
|
371
380
|
|
|
372
381
|
### Document Boundaries
|
|
373
382
|
|
|
@@ -376,8 +385,9 @@ Documents users normally need to watch:
|
|
|
376
385
|
- `README.md` / `README.zh-CN.md`: product usage, commands, and runtime layout.
|
|
377
386
|
- `.loopx/workflows/<slug>/spec.md`: the current requirement working copy.
|
|
378
387
|
- `.loopx/workflows/<slug>/plan.md`, `architecture.md`, `development-plan.md`, and `test-plan.md`: the current task's plan, architecture, execution, and verification contract.
|
|
388
|
+
- `.loopx/workflows/<slug>/requirement-traceability.md`: original requirement coverage gate used by plan, build, and review.
|
|
379
389
|
- `.loopx/workflows/<slug>/execution-record.md` and `review-report.md`: execution evidence and review result.
|
|
380
|
-
- `.loopx/views/index.html` and `.loopx/workflows/<slug>/view/index.html`: reading entrypoints
|
|
390
|
+
- `.loopx/views/index.html` and `.loopx/workflows/<slug>/view/index.html`: reading entrypoints written after `plan` and regenerated by `loopx render`.
|
|
381
391
|
|
|
382
392
|
Documents users may read and modify as workflow fact sources:
|
|
383
393
|
|
|
@@ -394,7 +404,7 @@ Documents and data the tools depend on, or generate as derived evidence:
|
|
|
394
404
|
- `.loopx/intake/clarify-*.md`: immutable clarify snapshots for audit and traceability; do not treat them as long-lived specs.
|
|
395
405
|
- `.loopx/changes/active/<change-id>/slices.json` and `artifact-graph.json`: structured planning data consumed by build/review/archive.
|
|
396
406
|
- `.loopx/autopilot/<slug>/run.json` and `.loopx/build-active.json`: orchestration and stop-hook runtime state.
|
|
397
|
-
- `.loopx/views/` and `.loopx/workflows/<slug>/view/`: derived HTML views; they can be deleted and regenerated with `loopx render`, and should not be edited as fact sources.
|
|
407
|
+
- `.loopx/views/` and `.loopx/workflows/<slug>/view/`: derived HTML views; they are written after `plan`, can be deleted and regenerated with `loopx render`, and should not be edited as fact sources.
|
|
398
408
|
|
|
399
409
|
## Diagnostics and Repair
|
|
400
410
|
|
|
@@ -511,4 +521,4 @@ node src/cli.mjs status --json
|
|
|
511
521
|
|
|
512
522
|
## Version
|
|
513
523
|
|
|
514
|
-
Current npm package version: `0.1.
|
|
524
|
+
Current npm package version: `0.1.7`.
|
package/README.zh-CN.md
CHANGED
|
@@ -123,18 +123,14 @@ loopx approve my-task --from build --to review
|
|
|
123
123
|
loopx review my-task
|
|
124
124
|
```
|
|
125
125
|
|
|
126
|
-
评审通过后完成工作流:
|
|
127
|
-
|
|
128
|
-
```bash
|
|
129
|
-
loopx approve my-task --from review --to done
|
|
130
|
-
```
|
|
131
|
-
|
|
132
126
|
把已接受行为归档到长期 specs:
|
|
133
127
|
|
|
134
128
|
```text
|
|
135
129
|
$archive my-task
|
|
136
130
|
```
|
|
137
131
|
|
|
132
|
+
当 review 已批准并路由到 `done` 时,`$archive` 会先消费 pending 的 `review -> done` 完成态,再同步 specs。纯 CLI 操作者仍然可以显式执行 `loopx approve my-task --from review --to done`,再执行 `loopx archive my-task`。
|
|
133
|
+
|
|
138
134
|
查看状态:
|
|
139
135
|
|
|
140
136
|
```bash
|
|
@@ -142,7 +138,15 @@ loopx status my-task
|
|
|
142
138
|
loopx status my-task --json
|
|
143
139
|
```
|
|
144
140
|
|
|
145
|
-
|
|
141
|
+
plan 完成后会自动写入派生 HTML 阅读视图,方便直接审阅计划:
|
|
142
|
+
|
|
143
|
+
```text
|
|
144
|
+
.loopx/workflows/my-task/view/index.html
|
|
145
|
+
.loopx/workflows/my-task/view/plan.html
|
|
146
|
+
.loopx/views/index.html
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
需要时也可以重新生成派生 HTML 阅读视图:
|
|
146
150
|
|
|
147
151
|
```bash
|
|
148
152
|
loopx render my-task
|
|
@@ -176,7 +180,7 @@ loopx repair-install
|
|
|
176
180
|
|
|
177
181
|
CLI 主要用于运行时、调试、状态观察和维护。日常面向 Codex 的主入口是同名 skills,例如 `$clarify`、`$plan`、`$build`、`$review`、`$archive`、`$autopilot`、`$debug`、`$tdd`、`$verify`、`$go-style`、`$kratos`。
|
|
178
182
|
|
|
179
|
-
`loopx status` 仍然是 CLI/runtime 诊断命令,不作为单独 Codex skill 暴露。`loopx
|
|
183
|
+
`loopx status` 仍然是 CLI/runtime 诊断命令,不作为单独 Codex skill 暴露。`loopx plan` 会自动为当前计划 workflow 和工作区首页写入给人阅读的 HTML 视图。`loopx render` 会基于现有运行时产物重新生成这些视图;不传 slug 时会渲染所有非 legacy workflow 和工作区首页。Markdown 和 JSON 仍然是机器可读、可编辑的事实源。
|
|
180
184
|
|
|
181
185
|
## Skill 路由与治理
|
|
182
186
|
|
|
@@ -225,6 +229,11 @@ node scripts/verify-skills.mjs
|
|
|
225
229
|
- `.loopx/workflows/<slug>/architecture.md`
|
|
226
230
|
- `.loopx/workflows/<slug>/development-plan.md`
|
|
227
231
|
- `.loopx/workflows/<slug>/test-plan.md`
|
|
232
|
+
- `.loopx/workflows/<slug>/requirement-traceability.md`
|
|
233
|
+
|
|
234
|
+
plan 成功后,loopx 还会写入派生阅读视图:`.loopx/workflows/<slug>/view/index.html`、`.loopx/workflows/<slug>/view/plan.html` 和 `.loopx/views/index.html`。这些视图用于人工审阅;Markdown 和 JSON 仍然是可编辑事实源。
|
|
235
|
+
|
|
236
|
+
`requirement-traceability.md` 会把原始需求或 PRD 映射到生成的 plan package、change delta、vertical slices 和测试。若显式需求覆盖项或需求表格项没有被计划包覆盖,`plan` 会在 build approval 前保持 blocked。
|
|
228
237
|
|
|
229
238
|
`spec-delta.md` 使用 requirement delta:`## ADDED Requirements`、`## MODIFIED Requirements`、`## REMOVED Requirements` 和 `## RENAMED Requirements`。ADDED / MODIFIED 必须是完整的 `### Requirement:` 块,包含 SHALL/MUST 约束和 `#### Scenario:` 场景,archive 才能把它们合并进长期 spec 当前状态。
|
|
230
239
|
|
|
@@ -269,13 +278,13 @@ $build --from-review .loopx/workflows/<slug>/review-report.md
|
|
|
269
278
|
|
|
270
279
|
最终用户可见评审结果要求使用中文。
|
|
271
280
|
|
|
272
|
-
|
|
281
|
+
如果评审通过并路由到 `done`,Codex 侧的正常下一步是 `$archive <slug>`;archive 会消费 pending 的完成态,然后同步 specs。纯 CLI 操作者仍然可以先显式执行 `loopx approve <slug> --from review --to done`,再执行 `loopx archive <slug>`。如果评审要求修实现问题,则运行 `$build --from-review .loopx/workflows/<slug>/review-report.md`。只有当 review 明确指出计划或需求本身错误时,才回到 `$plan <slug>` 或 `$clarify <slug>`。
|
|
273
282
|
|
|
274
283
|
architecture-smell lane 是 review 的一部分,不会增加新阶段。它会把发现记录到 `review-support/architecture-smell.json`,只有当模块边界、可测试性、领域词汇或计划架构假设存在实质性错误时才阻断。
|
|
275
284
|
|
|
276
285
|
### archive
|
|
277
286
|
|
|
278
|
-
`archive`
|
|
287
|
+
`archive` 消费已完成工作流,或 review 已批准且唯一 pending route 是 `done` 的工作流,并把 `.loopx/changes/active/<change-id>/spec-delta.md` 合并进 `.loopx/specs/` 下的长期领域规格。归档后的 change 目录会移动到:
|
|
279
288
|
|
|
280
289
|
```text
|
|
281
290
|
.loopx/changes/archive/<change-id>/
|
|
@@ -378,7 +387,7 @@ loopx 在当前项目下写入 `.loopx/`:
|
|
|
378
387
|
|
|
379
388
|
`intake` 保存一次需求的 clarify 快照;`workflows` 保存当前任务的运行时工作副本;`changes` 保存本次需求对长期行为的 change delta;`specs` 只保存 archive 后的长期领域行为契约。
|
|
380
389
|
|
|
381
|
-
`views/` 和 `workflows/<slug>/view/` 是 `loopx render`
|
|
390
|
+
`views/` 和 `workflows/<slug>/view/` 是 plan 后写入、也可由 `loopx render` 重新生成的派生 HTML 阅读视图,只服务于人的浏览和评审;agent 和工具仍应读取、修改 Markdown 与 JSON 产物。
|
|
382
391
|
|
|
383
392
|
### 文档关注边界
|
|
384
393
|
|
|
@@ -387,8 +396,9 @@ loopx 在当前项目下写入 `.loopx/`:
|
|
|
387
396
|
- `README.md` / `README.zh-CN.md`:产品用法、命令和目录约定。
|
|
388
397
|
- `.loopx/workflows/<slug>/spec.md`:当前需求工作副本。
|
|
389
398
|
- `.loopx/workflows/<slug>/plan.md`、`architecture.md`、`development-plan.md`、`test-plan.md`:当前任务的计划、架构和验证约定。
|
|
399
|
+
- `.loopx/workflows/<slug>/requirement-traceability.md`:plan、build、review 都会消费的原始需求覆盖门禁。
|
|
390
400
|
- `.loopx/workflows/<slug>/execution-record.md`、`review-report.md`:执行证据和评审结论。
|
|
391
|
-
- `.loopx/views/index.html` 与 `.loopx/workflows/<slug>/view/index.html
|
|
401
|
+
- `.loopx/views/index.html` 与 `.loopx/workflows/<slug>/view/index.html`:plan 后写入、也可由 `loopx render` 重新生成的阅读入口。
|
|
392
402
|
|
|
393
403
|
用户可以阅读和按流程修改的事实源文档:
|
|
394
404
|
|
|
@@ -405,7 +415,7 @@ loopx 在当前项目下写入 `.loopx/`:
|
|
|
405
415
|
- `.loopx/intake/clarify-*.md`:clarify 快照,用于审计和追溯;不要当作长期 specs 修改。
|
|
406
416
|
- `.loopx/changes/active/<change-id>/slices.json`、`artifact-graph.json`:计划结构化数据,build/review/archive 会消费。
|
|
407
417
|
- `.loopx/autopilot/<slug>/run.json`、`.loopx/build-active.json`:编排和 stop-hook 运行态。
|
|
408
|
-
- `.loopx/views/` 和 `.loopx/workflows/<slug>/view/`:HTML
|
|
418
|
+
- `.loopx/views/` 和 `.loopx/workflows/<slug>/view/`:HTML 派生视图,plan 后自动写入,可删除后用 `loopx render` 重新生成,不应作为事实源编辑。
|
|
409
419
|
|
|
410
420
|
## 安装诊断与修复
|
|
411
421
|
|
|
@@ -522,4 +532,4 @@ node src/cli.mjs status --json
|
|
|
522
532
|
|
|
523
533
|
## 版本
|
|
524
534
|
|
|
525
|
-
当前 npm 包版本:`0.1.
|
|
535
|
+
当前 npm 包版本:`0.1.7`。
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@ name: archive
|
|
|
3
3
|
description: "Archives an approved loopx change delta into long-lived specs and writes an ADR candidate after done approval. Not for active builds or unapproved reviews."
|
|
4
4
|
when_to_use: "archive, done workflow, spec delta, long-lived specs, ADR candidate, review approved, 归档, 同步规格"
|
|
5
5
|
metadata:
|
|
6
|
-
version: "0.1.
|
|
6
|
+
version: "0.1.7"
|
|
7
7
|
argument-hint: "<workflow slug>"
|
|
8
8
|
---
|
|
9
9
|
|
|
@@ -11,7 +11,7 @@ argument-hint: "<workflow slug>"
|
|
|
11
11
|
|
|
12
12
|
## Purpose
|
|
13
13
|
|
|
14
|
-
Use `archive` after a loopx workflow has reached `done
|
|
14
|
+
Use `archive` after a loopx workflow has reached `done`, or immediately after an approved review that is waiting for `review -> done` completion. It syncs the accepted change delta into long-lived `.loopx/specs/` files, archives the change staging directory, and writes an advisory ADR candidate.
|
|
15
15
|
|
|
16
16
|
The accepted delta is requirement-based, not a changelog block. Archive applies:
|
|
17
17
|
|
|
@@ -24,7 +24,7 @@ into the current long-lived `## Requirements` state for each target domain.
|
|
|
24
24
|
|
|
25
25
|
## Inputs
|
|
26
26
|
|
|
27
|
-
- `<workflow slug>` for a completed loopx workflow
|
|
27
|
+
- `<workflow slug>` for a completed loopx workflow, or for a review-approved workflow whose next route is `done`
|
|
28
28
|
|
|
29
29
|
## Behavior
|
|
30
30
|
|
|
@@ -34,9 +34,12 @@ Run:
|
|
|
34
34
|
loopx archive <slug>
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
+
If review already approved the workflow and the only pending transition is `review -> done`, this command consumes that completion transition before archiving. Do not ask the user to run a separate `loopx approve <slug> --from review --to done` command in that case.
|
|
38
|
+
|
|
37
39
|
Then report in Chinese:
|
|
38
40
|
|
|
39
41
|
- whether the change was archived
|
|
42
|
+
- whether `review -> done` was consumed by archive
|
|
40
43
|
- which long-lived spec files were updated
|
|
41
44
|
- the archived change path
|
|
42
45
|
- the ADR candidate path, if written
|
|
@@ -44,7 +47,7 @@ Then report in Chinese:
|
|
|
44
47
|
|
|
45
48
|
## Boundaries
|
|
46
49
|
|
|
47
|
-
- Do not run archive before
|
|
50
|
+
- Do not run archive before review has approved the workflow and routed it to `done`.
|
|
48
51
|
- Do not archive malformed requirement deltas. ADDED and MODIFIED entries must use `### Requirement:`, SHALL/MUST language, and at least one `#### Scenario:`.
|
|
49
52
|
- Do not archive when `execution-record.md` declares non-empty `remaining_scope`, `completion_claim` other than `full`, or a mismatch between `planned_scope` and `implemented_scope`; route back to build/plan instead.
|
|
50
53
|
- Do not edit implementation code.
|
|
@@ -3,7 +3,7 @@ name: autopilot
|
|
|
3
3
|
description: "Runs one bounded autonomous loopx orchestration over clarify, plan, build, and review while preserving canonical artifacts. Not for manual gate-by-gate control."
|
|
4
4
|
when_to_use: "autopilot, autonomous loopx run, end-to-end workflow, run all stages, bounded orchestration, 自动执行, 全流程"
|
|
5
5
|
metadata:
|
|
6
|
-
version: "0.1.
|
|
6
|
+
version: "0.1.7"
|
|
7
7
|
argument-hint: "<workflow slug>"
|
|
8
8
|
---
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ name: build
|
|
|
3
3
|
description: "Executes an approved loopx plan or review rework contract with evidence, verification, deslop, and regression gates. Not for unclear requirements or independent review."
|
|
4
4
|
when_to_use: "build, implement approved plan, execute PRD, --from-review, review rework, implementation fixes, 执行, 实现, 修改"
|
|
5
5
|
metadata:
|
|
6
|
-
version: "0.1.
|
|
6
|
+
version: "0.1.7"
|
|
7
7
|
argument-hint: "[--no-deslop] <approved PRD path or workflow slug> | --from-review <review artifact path>"
|
|
8
8
|
---
|
|
9
9
|
|
|
@@ -200,6 +200,8 @@ These support artifacts are runtime aids only. They must not become new canonica
|
|
|
200
200
|
<Final_Response_Contract>
|
|
201
201
|
When `build` reaches review handoff readiness, the final response must include an explicit next skill command using the execution record path:
|
|
202
202
|
|
|
203
|
+
Default review handoff after build readiness:
|
|
204
|
+
|
|
203
205
|
```text
|
|
204
206
|
Next:
|
|
205
207
|
$review .loopx/workflows/<slug>/execution-record.md
|
|
@@ -3,7 +3,7 @@ name: clarify
|
|
|
3
3
|
description: "Clarifies ambiguous loopx work into requirements, non-goals, decision boundaries, and design-ready specs before planning. Not for already-approved plans or concrete implementation tasks."
|
|
4
4
|
when_to_use: "clarify, requirements, ambiguous request, unclear scope, non-goals, decision boundaries, acceptance criteria, 需求澄清, 范围不清"
|
|
5
5
|
metadata:
|
|
6
|
-
version: "0.1.
|
|
6
|
+
version: "0.1.7"
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# loopx Clarify
|
|
@@ -308,8 +308,11 @@ After the clarify spec is ready:
|
|
|
308
308
|
|
|
309
309
|
Preferred explicit handoff contract:
|
|
310
310
|
|
|
311
|
-
-
|
|
312
|
-
-
|
|
311
|
+
- Default handoff after normal loopx clarify: `$plan <slug>`
|
|
312
|
+
- Conditional artifact-pinned handoff: `$plan --direct <spec-path>`
|
|
313
|
+
- Recommend `$plan --direct <spec-path>` when the user explicitly wants to plan from a specific requirements artifact, when the source is external/manual/legacy, or when multiple plausible spec files exist and the user has chosen one as the planning source of truth.
|
|
314
|
+
- Do not use `$plan --direct` to work around unclear workflow state, missing approvals, or an uncertain slug; inspect or repair the loopx runtime state instead.
|
|
315
|
+
- For the normal loopx clarify happy path, prefer `$plan <slug>` because the active workflow slug already anchors the clarify artifact and runtime state.
|
|
313
316
|
- Consumer behavior: treat the clarify spec as the source of truth for intent, non-goals, decision boundaries, constraints, and design direction; do not reopen clarification by default
|
|
314
317
|
|
|
315
318
|
`clarify` itself does not implement the feature. The handoff recommendation must name `plan` as the next workflow step.
|
|
@@ -3,7 +3,7 @@ name: debug
|
|
|
3
3
|
description: "Finds root cause for bugs, failing tests, build failures, regressions, and unexpected behavior before fixes. Not for new feature planning or routine code review."
|
|
4
4
|
when_to_use: "debug, bug, test failure, build failure, regression, unexpected behavior, root cause, 报错, 失败, 回归, 排查"
|
|
5
5
|
metadata:
|
|
6
|
-
version: "0.1.
|
|
6
|
+
version: "0.1.7"
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# Systematic Debugging
|
|
@@ -3,7 +3,7 @@ name: go-style
|
|
|
3
3
|
description: "Applies loopx Go coding style for .go edits, tests, errors, context, naming, and interface boundaries. Not for non-Go code or Kratos-specific architecture by itself."
|
|
4
4
|
when_to_use: "go-style, Go, golang, .go files, go tests, gofmt, idiomatic Go, Go style, Go 代码"
|
|
5
5
|
metadata:
|
|
6
|
-
version: "0.1.
|
|
6
|
+
version: "0.1.7"
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# Go Style
|
|
@@ -3,7 +3,7 @@ name: kratos
|
|
|
3
3
|
description: "Supports Go-Kratos microservices, proto/buf APIs, service/biz/data layers, middleware, auth, config, and troubleshooting. Not for generic Go style alone."
|
|
4
4
|
when_to_use: "kratos, Go-Kratos, proto, buf, service layer, biz layer, data layer, middleware, auth, config, Kratos 微服务"
|
|
5
5
|
metadata:
|
|
6
|
-
version: "0.1.
|
|
6
|
+
version: "0.1.7"
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# Kratos
|
|
@@ -3,7 +3,7 @@ name: plan
|
|
|
3
3
|
description: "Creates a consensus-first loopx plan package with Planner, Architect, and Critic review from an approved spec. Not for unresolved requirements or direct implementation."
|
|
4
4
|
when_to_use: "plan, planning, consensus planning, PRD, architecture plan, test plan, approved clarify spec, 规划, 方案, 架构评审"
|
|
5
5
|
metadata:
|
|
6
|
-
version: "0.1.
|
|
6
|
+
version: "0.1.7"
|
|
7
7
|
argument-hint: "[--interactive] [--deliberate] [--direct <spec-path>] <clarified task or spec path>"
|
|
8
8
|
---
|
|
9
9
|
|
|
@@ -164,6 +164,7 @@ On approval, write canonical planning artifacts:
|
|
|
164
164
|
- `.loopx/workflows/<slug>/architecture.md`
|
|
165
165
|
- `.loopx/workflows/<slug>/development-plan.md`
|
|
166
166
|
- `.loopx/workflows/<slug>/test-plan.md`
|
|
167
|
+
- `.loopx/workflows/<slug>/requirement-traceability.md`
|
|
167
168
|
- `.loopx/plans/prd-<slug>.md`
|
|
168
169
|
- `.loopx/plans/test-spec-<slug>.md`
|
|
169
170
|
- `.loopx/changes/active/<change-id>/proposal.md`
|
|
@@ -173,8 +174,17 @@ On approval, write canonical planning artifacts:
|
|
|
173
174
|
- `.loopx/changes/active/<change-id>/slices.json`
|
|
174
175
|
- `.loopx/changes/active/<change-id>/artifact-graph.json`
|
|
175
176
|
|
|
177
|
+
Also generate derived HTML reading views:
|
|
178
|
+
|
|
179
|
+
- `.loopx/workflows/<slug>/view/index.html`
|
|
180
|
+
- `.loopx/workflows/<slug>/view/plan.html`
|
|
181
|
+
- `.loopx/views/index.html`
|
|
182
|
+
|
|
183
|
+
The HTML files are derived reading views for human plan review. They are not canonical fact sources; Markdown and JSON remain authoritative.
|
|
184
|
+
|
|
176
185
|
The final plan must include:
|
|
177
186
|
|
|
187
|
+
- a source-requirement coverage matrix that maps the original requirements/PRD to plan, architecture, slices, spec delta, and tests
|
|
178
188
|
- ADR: Decision, Drivers, Alternatives considered, Why chosen, Consequences, Follow-ups
|
|
179
189
|
- concrete implementation steps sized to the actual task
|
|
180
190
|
- target long-lived spec domains and an OpenSpec-style requirements delta for archive
|
|
@@ -199,6 +209,24 @@ In `--interactive` mode, ask for the next lane:
|
|
|
199
209
|
Without `--interactive`, report the approved plan and recommended next command, but do not launch execution.
|
|
200
210
|
</Consensus_Workflow>
|
|
201
211
|
|
|
212
|
+
<Final_Response_Contract>
|
|
213
|
+
Default build handoff after an approved plan package:
|
|
214
|
+
|
|
215
|
+
```text
|
|
216
|
+
Next:
|
|
217
|
+
$build .loopx/plans/prd-<slug>.md
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
Use the artifact-first PRD path because it pins build to the approved plan package. Do not emit `$build <slug>` as the primary handoff when `.loopx/plans/prd-<slug>.md` is known. If execution is not approved or plan gates remain blocked, state the blocker instead of emitting a build handoff.
|
|
221
|
+
|
|
222
|
+
Also report the generated HTML reading entrypoint so the user can review the plan without running another command:
|
|
223
|
+
|
|
224
|
+
```text
|
|
225
|
+
HTML:
|
|
226
|
+
.loopx/workflows/<slug>/view/index.html
|
|
227
|
+
```
|
|
228
|
+
</Final_Response_Contract>
|
|
229
|
+
|
|
202
230
|
<Runtime_State_Machine>
|
|
203
231
|
`plan` must keep the planning gate machine-checkable. Runtime state should track:
|
|
204
232
|
|
|
@@ -217,6 +245,8 @@ Without `--interactive`, report the approved plan and recommended next command,
|
|
|
217
245
|
- `plan_acceptance_criteria_testable`: `true|false`
|
|
218
246
|
- `plan_verification_steps_resolved`: `true|false`
|
|
219
247
|
- `plan_execution_inputs_resolved`: `true|false`
|
|
248
|
+
- `source_requirements_status`: `complete|partial`
|
|
249
|
+
- `requirement_traceability_path`: `.loopx/workflows/<slug>/requirement-traceability.md`
|
|
220
250
|
- `requested_transition`: remains explicit before build/autopilot
|
|
221
251
|
|
|
222
252
|
The plan gate is blocked until:
|
|
@@ -231,6 +261,7 @@ The plan gate is blocked until:
|
|
|
231
261
|
- acceptance criteria are testable
|
|
232
262
|
- verification steps are concrete
|
|
233
263
|
- execution inputs are fully mapped to concrete sources
|
|
264
|
+
- source requirements are covered by `requirement-traceability.md`; uncovered original PRD requirements block build handoff
|
|
234
265
|
- user approval exists for any execution transition
|
|
235
266
|
</Runtime_State_Machine>
|
|
236
267
|
|
|
@@ -247,8 +278,10 @@ The plan gate is blocked until:
|
|
|
247
278
|
Primary outputs:
|
|
248
279
|
|
|
249
280
|
- approved plan package under `.loopx/workflows/<slug>/`
|
|
281
|
+
- original source requirements and traceability matrix under `.loopx/workflows/<slug>/requirement-traceability.md`
|
|
250
282
|
- canonical PRD and test spec under `.loopx/plans/`
|
|
251
283
|
- change artifacts under `.loopx/changes/active/<change-id>/`
|
|
284
|
+
- derived HTML reading views under `.loopx/workflows/<slug>/view/` and `.loopx/views/`
|
|
252
285
|
- consensus review summary with Planner / Architect / Critic evidence
|
|
253
286
|
- next-step recommendation
|
|
254
287
|
|
|
@@ -3,7 +3,7 @@ name: review
|
|
|
3
3
|
description: "Reviews a loopx build execution record for acceptance, code risks, evidence quality, and architecture smells. Not for doing implementation work or replanning."
|
|
4
4
|
when_to_use: "review, code review, acceptance, go no-go, execution-record, architecture smell, build complete, 审查, 验收"
|
|
5
5
|
metadata:
|
|
6
|
-
version: "0.1.
|
|
6
|
+
version: "0.1.7"
|
|
7
7
|
argument-hint: "<execution-record path or workflow slug>"
|
|
8
8
|
---
|
|
9
9
|
|
|
@@ -50,6 +50,7 @@ Use stable machine values only where they are commands, file paths, JSON/state f
|
|
|
50
50
|
- Review should compare verification evidence against project-native commands recorded in `.loopx/config.json` when available, while still accepting stronger task-specific verification from the approved plan.
|
|
51
51
|
- Review must include the architecture-smell lane as part of review evidence. This is not a new workflow stage and must not create extra user steps.
|
|
52
52
|
- Review must compare the execution scope against the approved workflow scope. If `execution-record.md` declares non-empty `remaining_scope`, `completion_claim` other than `full`, or a mismatch between `planned_scope` and `implemented_scope`, review must return no-go and route to build or plan. A partial slice may be accepted as useful work, but it must not be approved as full workflow completion.
|
|
53
|
+
- Review must compare implementation evidence against the original source requirements and `.loopx/workflows/<slug>/requirement-traceability.md`, not only against the generated plan. If the traceability matrix is missing, partial, or contradicted by code/tests, route to `review -> plan` or `review -> clarify` depending on whether the plan or requirements are wrong.
|
|
53
54
|
- Code review findings should focus on real bugs, regressions, missing tests, broken contracts, security/data-integrity risks, and user-visible behavior gaps.
|
|
54
55
|
- If code review finds blocking high or medium severity issues, return a no-go verdict and rollback guidance instead of approving completion.
|
|
55
56
|
- If architecture-smell findings are only advisory, record them as warnings without blocking. Block only when module seams, testability, domain boundaries, duplicated rules, or plan architecture assumptions are materially wrong.
|
|
@@ -65,6 +66,8 @@ Every no-go review result must end with a concrete next command block.
|
|
|
65
66
|
|
|
66
67
|
For implementation fixes:
|
|
67
68
|
|
|
69
|
+
Default implementation-fix handoff:
|
|
70
|
+
|
|
68
71
|
```text
|
|
69
72
|
Next:
|
|
70
73
|
$build --from-review .loopx/workflows/<slug>/review-report.md
|
|
@@ -3,7 +3,7 @@ name: tdd
|
|
|
3
3
|
description: "Guides feature and bugfix implementation through a failing test before production code and red-green-refactor discipline. Not for generated files or throwaway prototypes."
|
|
4
4
|
when_to_use: "tdd, failing test first, feature implementation, bugfix, regression test, red green refactor, 测试先行"
|
|
5
5
|
metadata:
|
|
6
|
-
version: "0.1.
|
|
6
|
+
version: "0.1.7"
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# Test-Driven Development (TDD)
|
|
@@ -3,7 +3,7 @@ name: verify
|
|
|
3
3
|
description: "Requires fresh verification evidence before claiming work is complete, fixed, passing, review-ready, or ready to commit. Not for speculative confidence or stale results."
|
|
4
4
|
when_to_use: "verify, completion claim, fixed claim, tests pass, review-ready, commit, fresh evidence, 验证, 完成前检查"
|
|
5
5
|
metadata:
|
|
6
|
-
version: "0.1.
|
|
6
|
+
version: "0.1.7"
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# Verification Before Completion
|
package/skills/archive/SKILL.md
CHANGED
|
@@ -3,7 +3,7 @@ name: archive
|
|
|
3
3
|
description: "Archives an approved loopx change delta into long-lived specs and writes an ADR candidate after done approval. Not for active builds or unapproved reviews."
|
|
4
4
|
when_to_use: "archive, done workflow, spec delta, long-lived specs, ADR candidate, review approved, 归档, 同步规格"
|
|
5
5
|
metadata:
|
|
6
|
-
version: "0.1.
|
|
6
|
+
version: "0.1.7"
|
|
7
7
|
argument-hint: "<workflow slug>"
|
|
8
8
|
---
|
|
9
9
|
|
|
@@ -11,7 +11,7 @@ argument-hint: "<workflow slug>"
|
|
|
11
11
|
|
|
12
12
|
## Purpose
|
|
13
13
|
|
|
14
|
-
Use `archive` after a loopx workflow has reached `done
|
|
14
|
+
Use `archive` after a loopx workflow has reached `done`, or immediately after an approved review that is waiting for `review -> done` completion. It syncs the accepted change delta into long-lived `.loopx/specs/` files, archives the change staging directory, and writes an advisory ADR candidate.
|
|
15
15
|
|
|
16
16
|
The accepted delta is requirement-based, not a changelog block. Archive applies:
|
|
17
17
|
|
|
@@ -24,7 +24,7 @@ into the current long-lived `## Requirements` state for each target domain.
|
|
|
24
24
|
|
|
25
25
|
## Inputs
|
|
26
26
|
|
|
27
|
-
- `<workflow slug>` for a completed loopx workflow
|
|
27
|
+
- `<workflow slug>` for a completed loopx workflow, or for a review-approved workflow whose next route is `done`
|
|
28
28
|
|
|
29
29
|
## Behavior
|
|
30
30
|
|
|
@@ -34,9 +34,12 @@ Run:
|
|
|
34
34
|
loopx archive <slug>
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
+
If review already approved the workflow and the only pending transition is `review -> done`, this command consumes that completion transition before archiving. Do not ask the user to run a separate `loopx approve <slug> --from review --to done` command in that case.
|
|
38
|
+
|
|
37
39
|
Then report in Chinese:
|
|
38
40
|
|
|
39
41
|
- whether the change was archived
|
|
42
|
+
- whether `review -> done` was consumed by archive
|
|
40
43
|
- which long-lived spec files were updated
|
|
41
44
|
- the archived change path
|
|
42
45
|
- the ADR candidate path, if written
|
|
@@ -44,7 +47,7 @@ Then report in Chinese:
|
|
|
44
47
|
|
|
45
48
|
## Boundaries
|
|
46
49
|
|
|
47
|
-
- Do not run archive before
|
|
50
|
+
- Do not run archive before review has approved the workflow and routed it to `done`.
|
|
48
51
|
- Do not archive malformed requirement deltas. ADDED and MODIFIED entries must use `### Requirement:`, SHALL/MUST language, and at least one `#### Scenario:`.
|
|
49
52
|
- Do not archive when `execution-record.md` declares non-empty `remaining_scope`, `completion_claim` other than `full`, or a mismatch between `planned_scope` and `implemented_scope`; route back to build/plan instead.
|
|
50
53
|
- Do not edit implementation code.
|
|
@@ -3,7 +3,7 @@ name: autopilot
|
|
|
3
3
|
description: "Runs one bounded autonomous loopx orchestration over clarify, plan, build, and review while preserving canonical artifacts. Not for manual gate-by-gate control."
|
|
4
4
|
when_to_use: "autopilot, autonomous loopx run, end-to-end workflow, run all stages, bounded orchestration, 自动执行, 全流程"
|
|
5
5
|
metadata:
|
|
6
|
-
version: "0.1.
|
|
6
|
+
version: "0.1.7"
|
|
7
7
|
argument-hint: "<workflow slug>"
|
|
8
8
|
---
|
|
9
9
|
|
package/skills/build/SKILL.md
CHANGED
|
@@ -3,7 +3,7 @@ name: build
|
|
|
3
3
|
description: "Executes an approved loopx plan or review rework contract with evidence, verification, deslop, and regression gates. Not for unclear requirements or independent review."
|
|
4
4
|
when_to_use: "build, implement approved plan, execute PRD, --from-review, review rework, implementation fixes, 执行, 实现, 修改"
|
|
5
5
|
metadata:
|
|
6
|
-
version: "0.1.
|
|
6
|
+
version: "0.1.7"
|
|
7
7
|
argument-hint: "[--no-deslop] <approved PRD path or workflow slug> | --from-review <review artifact path>"
|
|
8
8
|
---
|
|
9
9
|
|
|
@@ -200,6 +200,8 @@ These support artifacts are runtime aids only. They must not become new canonica
|
|
|
200
200
|
<Final_Response_Contract>
|
|
201
201
|
When `build` reaches review handoff readiness, the final response must include an explicit next skill command using the execution record path:
|
|
202
202
|
|
|
203
|
+
Default review handoff after build readiness:
|
|
204
|
+
|
|
203
205
|
```text
|
|
204
206
|
Next:
|
|
205
207
|
$review .loopx/workflows/<slug>/execution-record.md
|
package/skills/clarify/SKILL.md
CHANGED
|
@@ -3,7 +3,7 @@ name: clarify
|
|
|
3
3
|
description: "Clarifies ambiguous loopx work into requirements, non-goals, decision boundaries, and design-ready specs before planning. Not for already-approved plans or concrete implementation tasks."
|
|
4
4
|
when_to_use: "clarify, requirements, ambiguous request, unclear scope, non-goals, decision boundaries, acceptance criteria, 需求澄清, 范围不清"
|
|
5
5
|
metadata:
|
|
6
|
-
version: "0.1.
|
|
6
|
+
version: "0.1.7"
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# loopx Clarify
|
|
@@ -308,8 +308,11 @@ After the clarify spec is ready:
|
|
|
308
308
|
|
|
309
309
|
Preferred explicit handoff contract:
|
|
310
310
|
|
|
311
|
-
-
|
|
312
|
-
-
|
|
311
|
+
- Default handoff after normal loopx clarify: `$plan <slug>`
|
|
312
|
+
- Conditional artifact-pinned handoff: `$plan --direct <spec-path>`
|
|
313
|
+
- Recommend `$plan --direct <spec-path>` when the user explicitly wants to plan from a specific requirements artifact, when the source is external/manual/legacy, or when multiple plausible spec files exist and the user has chosen one as the planning source of truth.
|
|
314
|
+
- Do not use `$plan --direct` to work around unclear workflow state, missing approvals, or an uncertain slug; inspect or repair the loopx runtime state instead.
|
|
315
|
+
- For the normal loopx clarify happy path, prefer `$plan <slug>` because the active workflow slug already anchors the clarify artifact and runtime state.
|
|
313
316
|
- Consumer behavior: treat the clarify spec as the source of truth for intent, non-goals, decision boundaries, constraints, and design direction; do not reopen clarification by default
|
|
314
317
|
|
|
315
318
|
`clarify` itself does not implement the feature. The handoff recommendation must name `plan` as the next workflow step.
|
package/skills/debug/SKILL.md
CHANGED
|
@@ -3,7 +3,7 @@ name: debug
|
|
|
3
3
|
description: "Finds root cause for bugs, failing tests, build failures, regressions, and unexpected behavior before fixes. Not for new feature planning or routine code review."
|
|
4
4
|
when_to_use: "debug, bug, test failure, build failure, regression, unexpected behavior, root cause, 报错, 失败, 回归, 排查"
|
|
5
5
|
metadata:
|
|
6
|
-
version: "0.1.
|
|
6
|
+
version: "0.1.7"
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# Systematic Debugging
|
package/skills/go-style/SKILL.md
CHANGED
|
@@ -3,7 +3,7 @@ name: go-style
|
|
|
3
3
|
description: "Applies loopx Go coding style for .go edits, tests, errors, context, naming, and interface boundaries. Not for non-Go code or Kratos-specific architecture by itself."
|
|
4
4
|
when_to_use: "go-style, Go, golang, .go files, go tests, gofmt, idiomatic Go, Go style, Go 代码"
|
|
5
5
|
metadata:
|
|
6
|
-
version: "0.1.
|
|
6
|
+
version: "0.1.7"
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# Go Style
|
package/skills/kratos/SKILL.md
CHANGED
|
@@ -3,7 +3,7 @@ name: kratos
|
|
|
3
3
|
description: "Supports Go-Kratos microservices, proto/buf APIs, service/biz/data layers, middleware, auth, config, and troubleshooting. Not for generic Go style alone."
|
|
4
4
|
when_to_use: "kratos, Go-Kratos, proto, buf, service layer, biz layer, data layer, middleware, auth, config, Kratos 微服务"
|
|
5
5
|
metadata:
|
|
6
|
-
version: "0.1.
|
|
6
|
+
version: "0.1.7"
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# Kratos
|
package/skills/plan/SKILL.md
CHANGED
|
@@ -3,7 +3,7 @@ name: plan
|
|
|
3
3
|
description: "Creates a consensus-first loopx plan package with Planner, Architect, and Critic review from an approved spec. Not for unresolved requirements or direct implementation."
|
|
4
4
|
when_to_use: "plan, planning, consensus planning, PRD, architecture plan, test plan, approved clarify spec, 规划, 方案, 架构评审"
|
|
5
5
|
metadata:
|
|
6
|
-
version: "0.1.
|
|
6
|
+
version: "0.1.7"
|
|
7
7
|
argument-hint: "[--interactive] [--deliberate] [--direct <spec-path>] <clarified task or spec path>"
|
|
8
8
|
---
|
|
9
9
|
|
|
@@ -164,6 +164,7 @@ On approval, write canonical planning artifacts:
|
|
|
164
164
|
- `.loopx/workflows/<slug>/architecture.md`
|
|
165
165
|
- `.loopx/workflows/<slug>/development-plan.md`
|
|
166
166
|
- `.loopx/workflows/<slug>/test-plan.md`
|
|
167
|
+
- `.loopx/workflows/<slug>/requirement-traceability.md`
|
|
167
168
|
- `.loopx/plans/prd-<slug>.md`
|
|
168
169
|
- `.loopx/plans/test-spec-<slug>.md`
|
|
169
170
|
- `.loopx/changes/active/<change-id>/proposal.md`
|
|
@@ -173,8 +174,17 @@ On approval, write canonical planning artifacts:
|
|
|
173
174
|
- `.loopx/changes/active/<change-id>/slices.json`
|
|
174
175
|
- `.loopx/changes/active/<change-id>/artifact-graph.json`
|
|
175
176
|
|
|
177
|
+
Also generate derived HTML reading views:
|
|
178
|
+
|
|
179
|
+
- `.loopx/workflows/<slug>/view/index.html`
|
|
180
|
+
- `.loopx/workflows/<slug>/view/plan.html`
|
|
181
|
+
- `.loopx/views/index.html`
|
|
182
|
+
|
|
183
|
+
The HTML files are derived reading views for human plan review. They are not canonical fact sources; Markdown and JSON remain authoritative.
|
|
184
|
+
|
|
176
185
|
The final plan must include:
|
|
177
186
|
|
|
187
|
+
- a source-requirement coverage matrix that maps the original requirements/PRD to plan, architecture, slices, spec delta, and tests
|
|
178
188
|
- ADR: Decision, Drivers, Alternatives considered, Why chosen, Consequences, Follow-ups
|
|
179
189
|
- concrete implementation steps sized to the actual task
|
|
180
190
|
- target long-lived spec domains and an OpenSpec-style requirements delta for archive
|
|
@@ -199,6 +209,24 @@ In `--interactive` mode, ask for the next lane:
|
|
|
199
209
|
Without `--interactive`, report the approved plan and recommended next command, but do not launch execution.
|
|
200
210
|
</Consensus_Workflow>
|
|
201
211
|
|
|
212
|
+
<Final_Response_Contract>
|
|
213
|
+
Default build handoff after an approved plan package:
|
|
214
|
+
|
|
215
|
+
```text
|
|
216
|
+
Next:
|
|
217
|
+
$build .loopx/plans/prd-<slug>.md
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
Use the artifact-first PRD path because it pins build to the approved plan package. Do not emit `$build <slug>` as the primary handoff when `.loopx/plans/prd-<slug>.md` is known. If execution is not approved or plan gates remain blocked, state the blocker instead of emitting a build handoff.
|
|
221
|
+
|
|
222
|
+
Also report the generated HTML reading entrypoint so the user can review the plan without running another command:
|
|
223
|
+
|
|
224
|
+
```text
|
|
225
|
+
HTML:
|
|
226
|
+
.loopx/workflows/<slug>/view/index.html
|
|
227
|
+
```
|
|
228
|
+
</Final_Response_Contract>
|
|
229
|
+
|
|
202
230
|
<Runtime_State_Machine>
|
|
203
231
|
`plan` must keep the planning gate machine-checkable. Runtime state should track:
|
|
204
232
|
|
|
@@ -217,6 +245,8 @@ Without `--interactive`, report the approved plan and recommended next command,
|
|
|
217
245
|
- `plan_acceptance_criteria_testable`: `true|false`
|
|
218
246
|
- `plan_verification_steps_resolved`: `true|false`
|
|
219
247
|
- `plan_execution_inputs_resolved`: `true|false`
|
|
248
|
+
- `source_requirements_status`: `complete|partial`
|
|
249
|
+
- `requirement_traceability_path`: `.loopx/workflows/<slug>/requirement-traceability.md`
|
|
220
250
|
- `requested_transition`: remains explicit before build/autopilot
|
|
221
251
|
|
|
222
252
|
The plan gate is blocked until:
|
|
@@ -231,6 +261,7 @@ The plan gate is blocked until:
|
|
|
231
261
|
- acceptance criteria are testable
|
|
232
262
|
- verification steps are concrete
|
|
233
263
|
- execution inputs are fully mapped to concrete sources
|
|
264
|
+
- source requirements are covered by `requirement-traceability.md`; uncovered original PRD requirements block build handoff
|
|
234
265
|
- user approval exists for any execution transition
|
|
235
266
|
</Runtime_State_Machine>
|
|
236
267
|
|
|
@@ -247,8 +278,10 @@ The plan gate is blocked until:
|
|
|
247
278
|
Primary outputs:
|
|
248
279
|
|
|
249
280
|
- approved plan package under `.loopx/workflows/<slug>/`
|
|
281
|
+
- original source requirements and traceability matrix under `.loopx/workflows/<slug>/requirement-traceability.md`
|
|
250
282
|
- canonical PRD and test spec under `.loopx/plans/`
|
|
251
283
|
- change artifacts under `.loopx/changes/active/<change-id>/`
|
|
284
|
+
- derived HTML reading views under `.loopx/workflows/<slug>/view/` and `.loopx/views/`
|
|
252
285
|
- consensus review summary with Planner / Architect / Critic evidence
|
|
253
286
|
- next-step recommendation
|
|
254
287
|
|
package/skills/review/SKILL.md
CHANGED
|
@@ -3,7 +3,7 @@ name: review
|
|
|
3
3
|
description: "Reviews a loopx build execution record for acceptance, code risks, evidence quality, and architecture smells. Not for doing implementation work or replanning."
|
|
4
4
|
when_to_use: "review, code review, acceptance, go no-go, execution-record, architecture smell, build complete, 审查, 验收"
|
|
5
5
|
metadata:
|
|
6
|
-
version: "0.1.
|
|
6
|
+
version: "0.1.7"
|
|
7
7
|
argument-hint: "<execution-record path or workflow slug>"
|
|
8
8
|
---
|
|
9
9
|
|
|
@@ -50,6 +50,7 @@ Use stable machine values only where they are commands, file paths, JSON/state f
|
|
|
50
50
|
- Review should compare verification evidence against project-native commands recorded in `.loopx/config.json` when available, while still accepting stronger task-specific verification from the approved plan.
|
|
51
51
|
- Review must include the architecture-smell lane as part of review evidence. This is not a new workflow stage and must not create extra user steps.
|
|
52
52
|
- Review must compare the execution scope against the approved workflow scope. If `execution-record.md` declares non-empty `remaining_scope`, `completion_claim` other than `full`, or a mismatch between `planned_scope` and `implemented_scope`, review must return no-go and route to build or plan. A partial slice may be accepted as useful work, but it must not be approved as full workflow completion.
|
|
53
|
+
- Review must compare implementation evidence against the original source requirements and `.loopx/workflows/<slug>/requirement-traceability.md`, not only against the generated plan. If the traceability matrix is missing, partial, or contradicted by code/tests, route to `review -> plan` or `review -> clarify` depending on whether the plan or requirements are wrong.
|
|
53
54
|
- Code review findings should focus on real bugs, regressions, missing tests, broken contracts, security/data-integrity risks, and user-visible behavior gaps.
|
|
54
55
|
- If code review finds blocking high or medium severity issues, return a no-go verdict and rollback guidance instead of approving completion.
|
|
55
56
|
- If architecture-smell findings are only advisory, record them as warnings without blocking. Block only when module seams, testability, domain boundaries, duplicated rules, or plan architecture assumptions are materially wrong.
|
|
@@ -65,6 +66,8 @@ Every no-go review result must end with a concrete next command block.
|
|
|
65
66
|
|
|
66
67
|
For implementation fixes:
|
|
67
68
|
|
|
69
|
+
Default implementation-fix handoff:
|
|
70
|
+
|
|
68
71
|
```text
|
|
69
72
|
Next:
|
|
70
73
|
$build --from-review .loopx/workflows/<slug>/review-report.md
|
package/skills/tdd/SKILL.md
CHANGED
|
@@ -3,7 +3,7 @@ name: tdd
|
|
|
3
3
|
description: "Guides feature and bugfix implementation through a failing test before production code and red-green-refactor discipline. Not for generated files or throwaway prototypes."
|
|
4
4
|
when_to_use: "tdd, failing test first, feature implementation, bugfix, regression test, red green refactor, 测试先行"
|
|
5
5
|
metadata:
|
|
6
|
-
version: "0.1.
|
|
6
|
+
version: "0.1.7"
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# Test-Driven Development (TDD)
|
package/skills/verify/SKILL.md
CHANGED
|
@@ -3,7 +3,7 @@ name: verify
|
|
|
3
3
|
description: "Requires fresh verification evidence before claiming work is complete, fixed, passing, review-ready, or ready to commit. Not for speculative confidence or stale results."
|
|
4
4
|
when_to_use: "verify, completion claim, fixed claim, tests pass, review-ready, commit, fresh evidence, 验证, 完成前检查"
|
|
5
5
|
metadata:
|
|
6
|
-
version: "0.1.
|
|
6
|
+
version: "0.1.7"
|
|
7
7
|
---
|
|
8
8
|
|
|
9
9
|
# Verification Before Completion
|
package/src/cli.mjs
CHANGED
|
@@ -85,6 +85,8 @@ function printHumanStatus(status) {
|
|
|
85
85
|
console.log(`plan_architect_review_status: ${status.state.plan_architect_review_status}`);
|
|
86
86
|
console.log(`plan_critic_verdict: ${status.state.plan_critic_verdict}`);
|
|
87
87
|
console.log(`plan_artifact_status: ${status.state.plan_docs_status}`);
|
|
88
|
+
console.log(`source_requirements_status: ${status.state.source_requirements_status ?? 'unknown'}`);
|
|
89
|
+
console.log(`requirement_traceability_path: ${status.state.requirement_traceability_path ?? '(none)'}`);
|
|
88
90
|
console.log(`plan_blockers: ${Array.isArray(status.state.plan_blockers) && status.state.plan_blockers.length > 0 ? status.state.plan_blockers.join(', ') : '(none)'}`);
|
|
89
91
|
}
|
|
90
92
|
if (status.state?.current_stage === 'build') {
|
package/src/context-manifest.mjs
CHANGED
|
@@ -128,6 +128,8 @@ export async function generateBuildContextManifest({ cwd, root, state, slug }) {
|
|
|
128
128
|
|| (state.current_stage === 'review' && state.rollback_target === 'build');
|
|
129
129
|
const rows = [
|
|
130
130
|
row(cwd, { stage: 'build', kind: 'spec', path: join(root, 'spec.md'), reason: 'clarified_requirements', priority: 10 }),
|
|
131
|
+
row(cwd, { stage: 'build', kind: 'source-requirements', path: state.plan_source_spec_path || join(root, 'spec.md'), reason: 'original_requirements_source_of_truth', priority: 11 }),
|
|
132
|
+
row(cwd, { stage: 'build', kind: 'requirement-traceability', path: state.requirement_traceability_path || join(root, 'requirement-traceability.md'), reason: 'source_requirement_coverage_gate', priority: 12 }),
|
|
131
133
|
row(cwd, { stage: 'build', kind: 'plan', path: join(root, 'plan.md'), reason: 'implementation_strategy', priority: 20 }),
|
|
132
134
|
row(cwd, { stage: 'build', kind: 'architecture', path: join(root, 'architecture.md'), reason: 'architecture_constraints', priority: 21 }),
|
|
133
135
|
row(cwd, { stage: 'build', kind: 'development-plan', path: join(root, 'development-plan.md'), reason: 'execution_steps', priority: 22 }),
|
|
@@ -150,6 +152,8 @@ export async function generateReviewContextManifest({ cwd, root, state, slug })
|
|
|
150
152
|
const contextSetup = await inspectWorkspaceContext(cwd);
|
|
151
153
|
const rows = [
|
|
152
154
|
row(cwd, { stage: 'review', kind: 'execution-record', path: join(root, 'execution-record.md'), reason: 'execution_evidence', priority: 10 }),
|
|
155
|
+
row(cwd, { stage: 'review', kind: 'source-requirements', path: state.plan_source_spec_path || join(root, 'spec.md'), reason: 'original_requirements_source_of_truth', priority: 11 }),
|
|
156
|
+
row(cwd, { stage: 'review', kind: 'requirement-traceability', path: state.requirement_traceability_path || join(root, 'requirement-traceability.md'), reason: 'source_requirement_coverage_gate', priority: 12 }),
|
|
153
157
|
row(cwd, { stage: 'review', kind: 'test-spec', path: state.test_spec_artifact_path || join(cwd, '.loopx', 'plans', `test-spec-${slug}.md`), reason: 'acceptance_tests', priority: 20 }),
|
|
154
158
|
row(cwd, { stage: 'review', kind: 'prd', path: state.plan_artifact_path || join(cwd, '.loopx', 'plans', `prd-${slug}.md`), reason: 'requirements', priority: 21 }),
|
|
155
159
|
row(cwd, { stage: 'review', kind: 'vertical-slices', path: state.change_artifact_paths?.slices || join(cwd, '.loopx', 'changes', 'active', state.change_id || `chg-${slug}`, 'slices.json'), reason: 'slice_verification_contract', priority: 22 }),
|
package/src/plan-runtime.mjs
CHANGED
|
@@ -364,6 +364,7 @@ export function createRealPlanAdapter({ model } = {}) {
|
|
|
364
364
|
`Deliberate mode: ${Boolean(context.deliberateMode)}`,
|
|
365
365
|
'',
|
|
366
366
|
'Use Chinese for planText / architectureText / developmentPlanText / testPlanText.',
|
|
367
|
+
'Treat the source requirements/PRD as the source of truth. Explicitly cover every named event, field, processing mode, table row, and acceptance item that appears in the source, or clearly mark it out of scope with rationale.',
|
|
367
368
|
'If previous review feedback is present, revise the plan to explicitly resolve it. Do not repeat the same plan unchanged.',
|
|
368
369
|
'Do not ask questions. Do not wrap JSON in markdown.',
|
|
369
370
|
'',
|
package/src/workflow.mjs
CHANGED
|
@@ -357,7 +357,7 @@ function buildWorkspaceReadme() {
|
|
|
357
357
|
'- `workflows/<slug>/spec.md`',
|
|
358
358
|
'- `workflows/<slug>/plan.md`, `architecture.md`, `development-plan.md`, and `test-plan.md`',
|
|
359
359
|
'- `workflows/<slug>/execution-record.md` and `review-report.md`',
|
|
360
|
-
'- `views/index.html` and `workflows/<slug>/view/index.html` after `loopx render`',
|
|
360
|
+
'- `views/index.html` and `workflows/<slug>/view/index.html` after `loopx plan` or `loopx render`',
|
|
361
361
|
'',
|
|
362
362
|
'Documents users may read and edit as workflow fact sources:',
|
|
363
363
|
'',
|
|
@@ -558,6 +558,16 @@ function dedupeStrings(items) {
|
|
|
558
558
|
return [...new Set((items || []).map((item) => String(item || '').trim()).filter(Boolean))];
|
|
559
559
|
}
|
|
560
560
|
|
|
561
|
+
function slugKey(raw) {
|
|
562
|
+
return String(raw || '')
|
|
563
|
+
.trim()
|
|
564
|
+
.toLowerCase()
|
|
565
|
+
.replace(/[`'"*_#()[\]{}]/g, '')
|
|
566
|
+
.replace(/[^a-z0-9\u4e00-\u9fff]+/g, '-')
|
|
567
|
+
.replace(/^-+|-+$/g, '')
|
|
568
|
+
.slice(0, 80) || 'requirement';
|
|
569
|
+
}
|
|
570
|
+
|
|
561
571
|
function bulletsFromSectionText(text, heading) {
|
|
562
572
|
const pattern = new RegExp(`#{2,3} ${heading}\\n\\n([\\s\\S]*?)(?=\\n#{2,3} |$)`, 'i');
|
|
563
573
|
const match = text.match(pattern);
|
|
@@ -572,6 +582,173 @@ function bulletsFromSectionText(text, heading) {
|
|
|
572
582
|
.filter(Boolean);
|
|
573
583
|
}
|
|
574
584
|
|
|
585
|
+
function sectionBodyForHeadings(text, headingPatterns) {
|
|
586
|
+
const body = stripFrontmatter(text);
|
|
587
|
+
const headingPattern = /^#{2,4}\s+(.+?)\s*$/gm;
|
|
588
|
+
const headings = [...body.matchAll(headingPattern)];
|
|
589
|
+
for (let index = 0; index < headings.length; index += 1) {
|
|
590
|
+
const title = headings[index][1].trim();
|
|
591
|
+
if (!headingPatterns.some((pattern) => pattern.test(title))) {
|
|
592
|
+
continue;
|
|
593
|
+
}
|
|
594
|
+
const start = headings[index].index + headings[index][0].length;
|
|
595
|
+
const end = index + 1 < headings.length ? headings[index + 1].index : body.length;
|
|
596
|
+
return body.slice(start, end).trim();
|
|
597
|
+
}
|
|
598
|
+
return '';
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
function explicitCoverageItems(sourceText) {
|
|
602
|
+
const body = sectionBodyForHeadings(sourceText, [
|
|
603
|
+
/required\s+coverage/i,
|
|
604
|
+
/requirement\s+coverage/i,
|
|
605
|
+
/coverage\s+matrix/i,
|
|
606
|
+
/需求.*覆盖/,
|
|
607
|
+
/需求.*完整/,
|
|
608
|
+
/需求.*卡点/,
|
|
609
|
+
]);
|
|
610
|
+
if (!body) {
|
|
611
|
+
return [];
|
|
612
|
+
}
|
|
613
|
+
return body
|
|
614
|
+
.split('\n')
|
|
615
|
+
.map((line) => line.trim())
|
|
616
|
+
.filter((line) => /^[-*]\s+/.test(line) || /^\d+[.)]\s+/.test(line))
|
|
617
|
+
.map((line) => line.replace(/^[-*]\s+/, '').replace(/^\d+[.)]\s+/, '').trim())
|
|
618
|
+
.filter(Boolean);
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
function markdownTableCoverageItems(sourceText) {
|
|
622
|
+
const items = [];
|
|
623
|
+
const lines = String(sourceText || '').split('\n');
|
|
624
|
+
let currentHeading = '';
|
|
625
|
+
for (const line of lines) {
|
|
626
|
+
const heading = line.match(/^#{2,4}\s+(.+?)\s*$/);
|
|
627
|
+
if (heading) {
|
|
628
|
+
currentHeading = heading[1].trim();
|
|
629
|
+
continue;
|
|
630
|
+
}
|
|
631
|
+
if (!line.trim().startsWith('|')) {
|
|
632
|
+
continue;
|
|
633
|
+
}
|
|
634
|
+
const cells = line.split('|').slice(1, -1).map((cell) => cell.trim()).filter(Boolean);
|
|
635
|
+
if (cells.length < 2 || cells.every((cell) => /^:?-{3,}:?$/.test(cell))) {
|
|
636
|
+
continue;
|
|
637
|
+
}
|
|
638
|
+
const first = cells[0].replace(/`/g, '').trim();
|
|
639
|
+
if (!first || /^(字段|事件类型|模块|维度|对象|处理环节|field|type|module)$/i.test(first)) {
|
|
640
|
+
continue;
|
|
641
|
+
}
|
|
642
|
+
if (
|
|
643
|
+
/事件|字段|处理模式|标准化|范围|任务|确认|下发|source|event|field|coverage|requirement/i.test(currentHeading)
|
|
644
|
+
|| cells.some((cell) => /SHALL|MUST|Reuters|OCC|manual_|raw_snapshot|event_|处理|确认|下发|不自动/i.test(cell))
|
|
645
|
+
) {
|
|
646
|
+
items.push(first);
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
return items;
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
function requirementHeadingCoverageItems(sourceText) {
|
|
653
|
+
return [...String(sourceText || '').matchAll(/^###\s+Requirement:\s*(.+?)\s*$/gim)]
|
|
654
|
+
.map((match) => match[1].trim())
|
|
655
|
+
.filter(Boolean);
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
function sourceRequirementItems(sourceText) {
|
|
659
|
+
return dedupeStrings([
|
|
660
|
+
...explicitCoverageItems(sourceText),
|
|
661
|
+
...markdownTableCoverageItems(sourceText),
|
|
662
|
+
...requirementHeadingCoverageItems(sourceText),
|
|
663
|
+
]).slice(0, 80);
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
function normalizedCoverageText(...parts) {
|
|
667
|
+
return parts.join('\n')
|
|
668
|
+
.toLowerCase()
|
|
669
|
+
.replace(/[`'"*_#()[\]{}]/g, '')
|
|
670
|
+
.replace(/\s+/g, ' ');
|
|
671
|
+
}
|
|
672
|
+
|
|
673
|
+
function sourceRequirementCovered(item, haystack) {
|
|
674
|
+
const raw = String(item || '').trim();
|
|
675
|
+
if (!raw) {
|
|
676
|
+
return true;
|
|
677
|
+
}
|
|
678
|
+
const compactNeedle = raw.toLowerCase().replace(/\s+/g, '');
|
|
679
|
+
const compactHaystack = haystack.replace(/\s+/g, '');
|
|
680
|
+
if (compactNeedle.length >= 2 && compactHaystack.includes(compactNeedle)) {
|
|
681
|
+
return true;
|
|
682
|
+
}
|
|
683
|
+
const tokens = raw
|
|
684
|
+
.toLowerCase()
|
|
685
|
+
.replace(/[`'"*_#()[\]{}]/g, ' ')
|
|
686
|
+
.split(/[^a-z0-9\u4e00-\u9fff]+/)
|
|
687
|
+
.map((token) => token.trim())
|
|
688
|
+
.filter((token) => token.length >= 2)
|
|
689
|
+
.filter((token) => !['the', 'and', 'for', 'with', 'from', 'this', 'that'].includes(token));
|
|
690
|
+
if (tokens.length === 0) {
|
|
691
|
+
return false;
|
|
692
|
+
}
|
|
693
|
+
return tokens.every((token) => haystack.includes(token));
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
async function writeRequirementTraceabilityArtifact({ root, sourceSpecPath, sourceText, plannerDraft, changeArtifactPaths }) {
|
|
697
|
+
const traceabilityPath = artifactPath(root, 'requirement-traceability.md');
|
|
698
|
+
const sourceItems = sourceRequirementItems(sourceText);
|
|
699
|
+
const specDeltaText = changeArtifactPaths?.specDelta && existsSync(changeArtifactPaths.specDelta)
|
|
700
|
+
? await readFile(changeArtifactPaths.specDelta, 'utf8')
|
|
701
|
+
: '';
|
|
702
|
+
const slicesText = changeArtifactPaths?.slices && existsSync(changeArtifactPaths.slices)
|
|
703
|
+
? await readFile(changeArtifactPaths.slices, 'utf8')
|
|
704
|
+
: '';
|
|
705
|
+
const haystack = normalizedCoverageText(
|
|
706
|
+
plannerDraft.planText,
|
|
707
|
+
plannerDraft.architectureText,
|
|
708
|
+
plannerDraft.developmentPlanText,
|
|
709
|
+
plannerDraft.testPlanText,
|
|
710
|
+
specDeltaText,
|
|
711
|
+
slicesText,
|
|
712
|
+
);
|
|
713
|
+
const rows = sourceItems.map((item) => ({
|
|
714
|
+
item,
|
|
715
|
+
status: sourceRequirementCovered(item, haystack) ? 'covered' : 'uncovered',
|
|
716
|
+
}));
|
|
717
|
+
const blockers = rows
|
|
718
|
+
.filter((row) => row.status !== 'covered')
|
|
719
|
+
.map((row) => `source_requirement_uncovered_${slugKey(row.item)}`);
|
|
720
|
+
const status = blockers.length > 0 ? 'partial' : 'complete';
|
|
721
|
+
|
|
722
|
+
await writeText(traceabilityPath, [
|
|
723
|
+
'# Source Requirements Traceability',
|
|
724
|
+
'',
|
|
725
|
+
`- source: ${sourceSpecPath}`,
|
|
726
|
+
`- status: ${status}`,
|
|
727
|
+
`- extracted_items: ${rows.length}`,
|
|
728
|
+
'',
|
|
729
|
+
'## Coverage Matrix',
|
|
730
|
+
'',
|
|
731
|
+
'| Source requirement | Status |',
|
|
732
|
+
'| --- | --- |',
|
|
733
|
+
...(rows.length > 0
|
|
734
|
+
? rows.map((row) => `| ${row.item.replace(/\|/g, '\\|')} | ${row.status} |`)
|
|
735
|
+
: ['| No explicit source coverage items detected | covered |']),
|
|
736
|
+
'',
|
|
737
|
+
'## Gate',
|
|
738
|
+
'',
|
|
739
|
+
...(blockers.length > 0
|
|
740
|
+
? blockers.map((blocker) => `- ${blocker}`)
|
|
741
|
+
: ['- complete']),
|
|
742
|
+
].join('\n'));
|
|
743
|
+
|
|
744
|
+
return {
|
|
745
|
+
path: traceabilityPath,
|
|
746
|
+
status,
|
|
747
|
+
blockers,
|
|
748
|
+
itemCount: rows.length,
|
|
749
|
+
};
|
|
750
|
+
}
|
|
751
|
+
|
|
575
752
|
function frontmatterList(text, key) {
|
|
576
753
|
if (!text.startsWith('---\n')) {
|
|
577
754
|
return [];
|
|
@@ -1498,6 +1675,26 @@ async function readPlanCompletion(cwd, root, slug, state) {
|
|
|
1498
1675
|
if (!state.test_spec_artifact_path || !existsSync(state.test_spec_artifact_path)) {
|
|
1499
1676
|
blockers.push('missing_test_spec');
|
|
1500
1677
|
}
|
|
1678
|
+
if (!state.plan_source_spec_path || !existsSync(state.plan_source_spec_path)) {
|
|
1679
|
+
blockers.push('missing_source_requirements');
|
|
1680
|
+
}
|
|
1681
|
+
if (!state.requirement_traceability_path || !existsSync(state.requirement_traceability_path)) {
|
|
1682
|
+
blockers.push('missing_requirement_traceability');
|
|
1683
|
+
}
|
|
1684
|
+
if (state.source_requirements_status && state.source_requirements_status !== 'complete') {
|
|
1685
|
+
if (state.requirement_traceability_path && existsSync(state.requirement_traceability_path)) {
|
|
1686
|
+
const traceabilityText = await readFile(state.requirement_traceability_path, 'utf8');
|
|
1687
|
+
blockers.push(
|
|
1688
|
+
...traceabilityText
|
|
1689
|
+
.split('\n')
|
|
1690
|
+
.map((line) => line.trim())
|
|
1691
|
+
.filter((line) => line.startsWith('- source_requirement_'))
|
|
1692
|
+
.map((line) => line.slice(2).trim()),
|
|
1693
|
+
);
|
|
1694
|
+
} else {
|
|
1695
|
+
blockers.push(`source_requirements_${state.source_requirements_status}`);
|
|
1696
|
+
}
|
|
1697
|
+
}
|
|
1501
1698
|
const workflowDocs = {
|
|
1502
1699
|
plan: artifactPath(root, 'plan.md'),
|
|
1503
1700
|
architecture: artifactPath(root, 'architecture.md'),
|
|
@@ -1520,6 +1717,7 @@ async function readPlanCompletion(cwd, root, slug, state) {
|
|
|
1520
1717
|
return {
|
|
1521
1718
|
blockers,
|
|
1522
1719
|
docsStatus: blockers.some((blocker) => blocker.startsWith('missing_plan_artifact_') || blocker.startsWith('plan_artifact_not_chinese_')) ? 'partial' : 'complete',
|
|
1720
|
+
sourceRequirementsStatus: blockers.some((blocker) => blocker === 'missing_source_requirements' || blocker === 'missing_requirement_traceability' || blocker.startsWith('source_requirement_') || blocker.startsWith('source_requirements_')) ? 'partial' : 'complete',
|
|
1523
1721
|
changeArtifactsStatus: changeStatus.status,
|
|
1524
1722
|
specDeltaStatus: changeStatus.specDeltaStatus,
|
|
1525
1723
|
sliceArtifactsStatus: changeStatus.sliceArtifactsStatus,
|
|
@@ -2508,6 +2706,28 @@ async function refreshExecutionStatus(root, state) {
|
|
|
2508
2706
|
};
|
|
2509
2707
|
}
|
|
2510
2708
|
|
|
2709
|
+
async function renderPlanReadingViews(cwd, root, state, slug) {
|
|
2710
|
+
try {
|
|
2711
|
+
const { renderHtmlViews } = await import('./html-views.mjs');
|
|
2712
|
+
const rendered = await renderHtmlViews(cwd, { slug });
|
|
2713
|
+
return {
|
|
2714
|
+
...state,
|
|
2715
|
+
html_view_status: 'written',
|
|
2716
|
+
html_view_path: rendered.workflowViewPath,
|
|
2717
|
+
workspace_view_path: rendered.workspaceViewPath,
|
|
2718
|
+
html_view_error: null,
|
|
2719
|
+
};
|
|
2720
|
+
} catch (error) {
|
|
2721
|
+
return {
|
|
2722
|
+
...state,
|
|
2723
|
+
html_view_status: 'failed',
|
|
2724
|
+
html_view_path: join(root, 'view', 'index.html'),
|
|
2725
|
+
workspace_view_path: join(resolveWorkspaceRoot(cwd), 'views', 'index.html'),
|
|
2726
|
+
html_view_error: error instanceof Error ? error.message : String(error),
|
|
2727
|
+
};
|
|
2728
|
+
}
|
|
2729
|
+
}
|
|
2730
|
+
|
|
2511
2731
|
export async function initWorkspace(cwd, { slug } = {}) {
|
|
2512
2732
|
const workspaceRoot = resolveWorkspaceRoot(cwd);
|
|
2513
2733
|
const projectConventions = await inspectProjectConventions(cwd);
|
|
@@ -2785,8 +3005,64 @@ export async function approveStage(cwd, slug, { from, to }) {
|
|
|
2785
3005
|
return { root, state: next };
|
|
2786
3006
|
}
|
|
2787
3007
|
|
|
3008
|
+
function isDoneRoute(value) {
|
|
3009
|
+
return value === TRANSITIONS.REVIEW_TO_DONE || value === STAGES.DONE;
|
|
3010
|
+
}
|
|
3011
|
+
|
|
3012
|
+
function canArchiveConsumePendingDoneApproval(state) {
|
|
3013
|
+
if (state.current_stage !== STAGES.REVIEW) {
|
|
3014
|
+
return false;
|
|
3015
|
+
}
|
|
3016
|
+
const reviewVerdict = String(state.review_verdict || '').trim().toLowerCase();
|
|
3017
|
+
const reviewApproved = reviewVerdict === 'approve' || reviewVerdict === 'go';
|
|
3018
|
+
const routesToDone = [
|
|
3019
|
+
state.pending_user_decision,
|
|
3020
|
+
state.requested_transition,
|
|
3021
|
+
state.review_route,
|
|
3022
|
+
state.requested_transition_after_review,
|
|
3023
|
+
].some(isDoneRoute);
|
|
3024
|
+
const completionRequested = [
|
|
3025
|
+
APPROVAL_STATES.REQUESTED,
|
|
3026
|
+
APPROVAL_STATES.APPROVED,
|
|
3027
|
+
].includes(state.approval?.complete) || state.execution_approved === true || state.execution_approved_for_review === true;
|
|
3028
|
+
return reviewApproved && routesToDone && completionRequested;
|
|
3029
|
+
}
|
|
3030
|
+
|
|
3031
|
+
async function consumePendingDoneApprovalForArchive(cwd, root, state, slug) {
|
|
3032
|
+
if (!canArchiveConsumePendingDoneApproval(state)) {
|
|
3033
|
+
return { root, state, consumed: false };
|
|
3034
|
+
}
|
|
3035
|
+
const normalized = withRecommendedAction({
|
|
3036
|
+
...state,
|
|
3037
|
+
review_verdict: 'approve',
|
|
3038
|
+
pending_user_decision: TRANSITIONS.REVIEW_TO_DONE,
|
|
3039
|
+
requested_transition: TRANSITIONS.NONE,
|
|
3040
|
+
approval: {
|
|
3041
|
+
...state.approval,
|
|
3042
|
+
review: APPROVAL_STATES.APPROVED,
|
|
3043
|
+
complete: state.approval?.complete || APPROVAL_STATES.REQUESTED,
|
|
3044
|
+
},
|
|
3045
|
+
});
|
|
3046
|
+
await writeState(root, normalized);
|
|
3047
|
+
const done = await approveStage(cwd, slug, { from: STAGES.REVIEW, to: STAGES.DONE });
|
|
3048
|
+
return {
|
|
3049
|
+
root: done.root,
|
|
3050
|
+
state: {
|
|
3051
|
+
...done.state,
|
|
3052
|
+
archive_consumed_pending_done_approval: true,
|
|
3053
|
+
},
|
|
3054
|
+
consumed: true,
|
|
3055
|
+
};
|
|
3056
|
+
}
|
|
3057
|
+
|
|
2788
3058
|
export async function archiveStage(cwd, slug) {
|
|
2789
|
-
const
|
|
3059
|
+
const loaded = await loadWorkflowState(cwd, slug, { allowLegacy: false });
|
|
3060
|
+
const normalized = loaded.slug;
|
|
3061
|
+
let root = loaded.root;
|
|
3062
|
+
let state = loaded.state;
|
|
3063
|
+
const doneApproval = await consumePendingDoneApprovalForArchive(cwd, root, state, normalized);
|
|
3064
|
+
root = doneApproval.root;
|
|
3065
|
+
state = doneApproval.state;
|
|
2790
3066
|
if (state.current_stage !== STAGES.DONE || !state.completion_confirmed) {
|
|
2791
3067
|
throw new Error('archive_requires_done_workflow');
|
|
2792
3068
|
}
|
|
@@ -2916,6 +3192,13 @@ export async function planStage(cwd, slug, options = {}) {
|
|
|
2916
3192
|
const changeId = state.change_id || changeIdForWorkflowSlug(normalized);
|
|
2917
3193
|
const changeArtifactPaths = await writeChangeArtifacts(cwd, root, normalized, sourceText, plannerDraft, changeId);
|
|
2918
3194
|
const changeArtifactStatus = await readChangeArtifactStatus(changeArtifactPaths);
|
|
3195
|
+
const traceability = await writeRequirementTraceabilityArtifact({
|
|
3196
|
+
root,
|
|
3197
|
+
sourceSpecPath,
|
|
3198
|
+
sourceText,
|
|
3199
|
+
plannerDraft,
|
|
3200
|
+
changeArtifactPaths,
|
|
3201
|
+
});
|
|
2919
3202
|
|
|
2920
3203
|
architectReview = await adapter.architect({
|
|
2921
3204
|
cwd,
|
|
@@ -2961,6 +3244,9 @@ export async function planStage(cwd, slug, options = {}) {
|
|
|
2961
3244
|
plan_review_history: reviewHistory,
|
|
2962
3245
|
plan_artifact_path: artifactPaths.planPath,
|
|
2963
3246
|
test_spec_artifact_path: artifactPaths.testSpecPath,
|
|
3247
|
+
requirement_traceability_path: traceability.path,
|
|
3248
|
+
source_requirements_status: traceability.status,
|
|
3249
|
+
source_requirements_item_count: traceability.itemCount,
|
|
2964
3250
|
change_id: normalizeSlug(changeId),
|
|
2965
3251
|
change_artifacts_status: changeArtifactStatus.status,
|
|
2966
3252
|
change_artifact_paths: changeArtifactPaths,
|
|
@@ -2996,6 +3282,7 @@ export async function planStage(cwd, slug, options = {}) {
|
|
|
2996
3282
|
requested_transition: TRANSITIONS.NONE,
|
|
2997
3283
|
plan_docs_status: completion.docsStatus,
|
|
2998
3284
|
plan_docs_artifact_paths: null,
|
|
3285
|
+
source_requirements_status: completion.sourceRequirementsStatus,
|
|
2999
3286
|
change_artifacts_status: completion.changeArtifactsStatus,
|
|
3000
3287
|
spec_delta_status: completion.specDeltaStatus,
|
|
3001
3288
|
slice_artifacts_status: completion.sliceArtifactsStatus,
|
|
@@ -3004,7 +3291,9 @@ export async function planStage(cwd, slug, options = {}) {
|
|
|
3004
3291
|
build_context_manifest_path: buildManifest?.path || buildContextManifestPath(root),
|
|
3005
3292
|
});
|
|
3006
3293
|
await writeState(root, next);
|
|
3007
|
-
|
|
3294
|
+
const renderedNext = await renderPlanReadingViews(cwd, root, next, normalized);
|
|
3295
|
+
await writeState(root, renderedNext);
|
|
3296
|
+
return { root, state: renderedNext, architectReview, criticReview };
|
|
3008
3297
|
}
|
|
3009
3298
|
|
|
3010
3299
|
export async function buildStage(cwd, slug, options = {}) {
|