@gordon.gan/specflow 1.5.0-beta → 1.8.0-beta
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 +2 -2
- package/dist/cli/commands/approval-assemble.d.ts +48 -5
- package/dist/cli/commands/approval-assemble.js +347 -34
- package/dist/core/approval/assemble.js +15 -22
- package/dist/core/approval/bundle.d.ts +9 -0
- package/dist/core/approval/bundle.js +172 -0
- package/dist/core/approval/forbidden-patterns.d.ts +6 -0
- package/dist/core/approval/forbidden-patterns.js +40 -0
- package/dist/core/approval/index-schema.d.ts +203 -0
- package/dist/core/approval/index-schema.js +47 -0
- package/dist/core/approval/index.d.ts +10 -2
- package/dist/core/approval/index.js +7 -1
- package/dist/core/approval/lint.d.ts +10 -0
- package/dist/core/approval/lint.js +302 -0
- package/dist/core/approval/paths.d.ts +5 -0
- package/dist/core/approval/paths.js +15 -0
- package/dist/core/approval/pipeline.d.ts +28 -0
- package/dist/core/approval/pipeline.js +146 -0
- package/dist/core/approval/playbook-schema.d.ts +182 -0
- package/dist/core/approval/playbook-schema.js +51 -0
- package/dist/core/approval/render.d.ts +20 -0
- package/dist/core/approval/render.js +210 -0
- package/dist/core/approval/review-pack.d.ts +26 -0
- package/dist/core/approval/review-pack.js +205 -0
- package/dist/core/approval/types.d.ts +103 -0
- package/dist/integrations/shared/capability-evidence.js +3 -0
- package/dist/integrations/shared/parity-manifest.js +3 -0
- package/package.json +2 -1
- package/prompts/approval/acp-pipeline.md +106 -0
- package/prompts/approval/ai-review.md +145 -0
- package/prompts/approval/generate.md +107 -9
- package/prompts/approval/multi-repo-guidance.md +71 -10
- package/prompts/approval/multi-repo-spoke-subagent.md +94 -0
- package/prompts/approval/runtime-guidance.md +64 -0
- package/prompts/approval/segmented-generation.md +14 -8
- package/skills/GUIDANCE_PACKS.md +1 -1
- package/skills/specflow-approval/SKILL.md +160 -22
- package/templates/approval-index.yaml +25 -4
- package/templates/approval-part.md +1 -1
- package/templates/approval-playbook-talos-scenario-job-compile.yaml +29 -0
- package/templates/approval-playbook.yaml +28 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gordon.gan/specflow",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0-beta",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "SpecFlow — unified spec-driven development: OpenSpec planning + Superpowers execution in one CLI and cross-IDE workflow",
|
|
6
6
|
"keywords": [
|
|
@@ -58,6 +58,7 @@
|
|
|
58
58
|
"chalk": "^5.4.1",
|
|
59
59
|
"commander": "^13.1.0",
|
|
60
60
|
"js-yaml": "^4.1.0",
|
|
61
|
+
"marked": "^15.0.12",
|
|
61
62
|
"zod": "^3.24.4"
|
|
62
63
|
},
|
|
63
64
|
"devDependencies": {
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# Approval · ACP Pipeline (Approval Compiler Pipeline)
|
|
2
|
+
|
|
3
|
+
> Router for `/specflow:approval` **Stage 12** when `acp.pipeline=acp/v2` (recommended for non-lightweight changes).
|
|
4
|
+
> Legacy segmented flow remains valid; ACP adds **lint**, **AI review**, and **bundle** gates.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Pipeline (hard order)
|
|
9
|
+
|
|
10
|
+
```text
|
|
11
|
+
Phase 1 Analyze → analysis.json + IR planner (chat gate)
|
|
12
|
+
Phase 2 IR Freeze → index.yaml (+ interfaces[].frozen, feature_slices, acp.review)
|
|
13
|
+
Phase 3 Skeleton → parts 01–03, 04-detail-core, 06/09/10
|
|
14
|
+
Phase 4 Slot Map → batched parts 04.4–04.9 (vertical slice first)
|
|
15
|
+
Phase 5 AI Review → Stage 12e in-session (prompts/approval/ai-review.md) — **inside /specflow-approval**
|
|
16
|
+
Phase 6 finalize → specflow approval finalize <change> [--bundle] [--render]
|
|
17
|
+
Phase 7 render → specflow approval render <change> [--input] [--output]
|
|
18
|
+
|
|
19
|
+
**Preferred**: one `finalize` after Map + AI review. Subcommands (`lint`, `assemble`, …) are for CI/debug only.
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**Never** skip Phase 6a–6b with LLM paste. **Never** write `approval-unified.md` by hand when bundle is enabled.
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## index.yaml ACP block
|
|
27
|
+
|
|
28
|
+
```yaml
|
|
29
|
+
acp:
|
|
30
|
+
pipeline: acp/v2
|
|
31
|
+
context_budget_tokens: 40000
|
|
32
|
+
output_budget_tokens: 8000
|
|
33
|
+
feature_slices:
|
|
34
|
+
- id: step-reporting
|
|
35
|
+
parts: [04.5-api-worker, 04.5-api-east, 04-detail-core]
|
|
36
|
+
interfaces: [I13, I14, I16, I17]
|
|
37
|
+
review:
|
|
38
|
+
enabled: true
|
|
39
|
+
required_pass: true
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## interfaces[].frozen (IR freeze before Map)
|
|
43
|
+
|
|
44
|
+
```yaml
|
|
45
|
+
interfaces:
|
|
46
|
+
- id: I14
|
|
47
|
+
short: SubmitStepResult
|
|
48
|
+
change: scenario-job-compile
|
|
49
|
+
part: 04.5-api-worker
|
|
50
|
+
pairs_with: I13
|
|
51
|
+
layers: [L3]
|
|
52
|
+
frozen:
|
|
53
|
+
rpc: scheduler.Scheduler.SubmitStepResult
|
|
54
|
+
http_path: POST /internal/v1/tasks/{job_id}/step-results
|
|
55
|
+
status_enum: [passed, failed, skipped, error]
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Multi-repo default
|
|
61
|
+
|
|
62
|
+
- **True source**: `per_repo` — each repo `approval/` + `approval.md`
|
|
63
|
+
- **Read-only view**: `approval bundle` from `approval-playbook.yaml`
|
|
64
|
+
- Do **not** LLM-unify three repos into one primary `approval/parts`
|
|
65
|
+
|
|
66
|
+
See `multi-repo-guidance.md` + `templates/approval-playbook.yaml` (+ example `templates/approval-playbook-talos-scenario-job-compile.yaml`).
|
|
67
|
+
|
|
68
|
+
**Orchestration**: multi-repo mode A uses **Stage 1c** subagent parallel dispatch (`multi-repo-spoke-subagent.md`) — not a single-repo `finalize` across repos.
|
|
69
|
+
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
## Context packet (Map batch)
|
|
73
|
+
|
|
74
|
+
Read only:
|
|
75
|
+
|
|
76
|
+
1. `index.yaml` subset for this batch (ids + frozen fields)
|
|
77
|
+
2. `analysis.json` verdicts (not full Pass essays)
|
|
78
|
+
3. design/spec **snippets** for batch entities
|
|
79
|
+
4. 1–2 anchor files for this batch
|
|
80
|
+
5. guidance router (path only, not full paste)
|
|
81
|
+
|
|
82
|
+
Do **not** reload entire four-artifact sets each batch.
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## CLI reference
|
|
87
|
+
|
|
88
|
+
| Command | Purpose |
|
|
89
|
+
|---------|---------|
|
|
90
|
+
| `approval render` | MD → standalone HTML (tables, GFM, mermaid via CDN) |
|
|
91
|
+
| `approval finalize` | **Preferred** — full lint → review-check → check → assemble → bundle |
|
|
92
|
+
| `approval lint` | Cross-part consistency (CI / debug) |
|
|
93
|
+
| `approval review-pack` | Emit `review-packet.json` (debug; finalize auto-runs when needed) |
|
|
94
|
+
| `approval review-check` | Validate `review-result.json` (debug) |
|
|
95
|
+
| `approval check` | Part presence + lazy stub (debug) |
|
|
96
|
+
| `approval assemble` | Deterministic Reduce (debug) |
|
|
97
|
+
| `approval bundle` | Multi-repo readonly merge (debug; finalize can auto-run) |
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## Related guidance
|
|
102
|
+
|
|
103
|
+
- `segmented-generation.md` — Map anti-lazy L1–L10
|
|
104
|
+
- `ai-review.md` — Stage 12e AI approval/revision
|
|
105
|
+
- `runtime-guidance.md` — optional async/lease/cancel (when in scope)
|
|
106
|
+
- `api-guidance.md` — optional multi-layer API contracts (when api_in_scope)
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# Approval · Stage 12e AI Review (审批 / 修订)
|
|
2
|
+
|
|
3
|
+
> Runs **after** Map parts written, **before** `specflow approval finalize` completes.
|
|
4
|
+
> Purpose: catch **long-document / multi-part semantic drift** that mechanical lint cannot judge; **revise parts in place**.
|
|
5
|
+
|
|
6
|
+
**Scope**: checks apply to **any** segmented approval — not tied to a specific product, repo, or domain.
|
|
7
|
+
Use `index.yaml` + `analysis.json` as the contract; do not inject checks from unrelated case studies.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## 0. Trigger
|
|
12
|
+
|
|
13
|
+
Run when **any**:
|
|
14
|
+
|
|
15
|
+
- `acp.review.enabled=true` in `index.yaml` (default for non-lightweight)
|
|
16
|
+
- User asks for AI 审批 / 方案审查 / 一致性检查
|
|
17
|
+
- `specflow approval finalize` paused at `review-required`
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 1. Prep (hard)
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
specflow approval finalize <change> # pauses + writes review-packet.json if needed
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Read:
|
|
28
|
+
|
|
29
|
+
- `approval/review-packet.json` (checklist + lint diagnostics)
|
|
30
|
+
- `approval/index.yaml` (inventory, design_points, frozen fields, parts_order)
|
|
31
|
+
- `approval/analysis.json` (Pass verdicts — gaps to close)
|
|
32
|
+
- **All** `approval/parts/*.md` in `parts_order`
|
|
33
|
+
|
|
34
|
+
Optional domain packs (only when design **actually** touches that topic):
|
|
35
|
+
|
|
36
|
+
- `runtime-guidance.md` — async job / lease / retry / cancel semantics
|
|
37
|
+
- `api-guidance.md` — multi-layer API contracts
|
|
38
|
+
- `frontend-guidance.md` — §4.6 depth
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 2. Review dimensions (long-document generic)
|
|
43
|
+
|
|
44
|
+
These target **failure modes of long, batched documents** — inconsistency across parts written at different times.
|
|
45
|
+
|
|
46
|
+
| ID | Category | Check (generic) |
|
|
47
|
+
|----|----------|-----------------|
|
|
48
|
+
| R1 | **Cross-part naming** | Same entity (service, table, interface, page, enum) uses **one** canonical name/id across §2, §4, diagrams, and `index.yaml`. No 「暂定 / 实现时 / 如 Xxx / TBD」 for listed inventory ids. |
|
|
49
|
+
| R2 | **Decision traceability** | Each `decisions[]` / §2 row appears in §4 with concrete behavior — not only repeated in summary. |
|
|
50
|
+
| R3 | **Inventory ↔ body** | Every `tables[]` / `interfaces[]` / `pages[]` / `design_points[]` entry in index has **substantive** content in its assigned `part`. No orphan ids; no body content for ids missing from index. |
|
|
51
|
+
| R4 | **Depth parity** | Parts in the same `feature_slices` or batch have **comparable** depth. No pattern of one part fully detailed while sibling parts are one-line stubs. |
|
|
52
|
+
| R5 | **Cross-reference integrity** | Internal refs use stable ids (`§4.5 I2`, `P3`, `Page·列表`, `T1`) — not bare 「详见 design/tasks」. Ref targets exist and match. |
|
|
53
|
+
| R6 | **Diagram ↔ prose** | Sequence / flow diagrams agree with adjacent prose (actors, message names, order, error branches). |
|
|
54
|
+
| R7 | **Contract completeness** | Each listed interface/page-api has minimum skeleton from Part E (fields, success example, **failure example**, error table) — depth scaled to `api_in_scope` / `ui_in_scope`. |
|
|
55
|
+
| R8 | **Enum / state closure** | Status, enum, and terminal-state sets are **explicit and closed** wherever the doc defines them — no 「等」 or open-ended lists unless explicitly extensible by design. |
|
|
56
|
+
| R9 | **Unclosed branches** | Every **mentioned** branch (retry, cancel, timeout, idempotency, rollback, concurrency) has a documented outcome — or is flagged `[待 refine 澄清: …]` with owner. Do **not** assume domain-specific branches (e.g. lease reclaim) unless design/analysis mentions them. |
|
|
57
|
+
| R10 | **UI ↔ API alignment** | When `ui_in_scope`: §4.6 field names, types, and api refs align with §4.5 / `pages[].apis`. |
|
|
58
|
+
| R11 | **Multi-repo parity** | When `multi_repo.enabled`: each repo slice in scope has proportionate depth; no 「主仓详、他仓 stub」 unless explicitly out of scope. |
|
|
59
|
+
| R12 | **Stub purge** | No `TODO` / `待补充` / `此处省略` / placeholder-only sections in parts slated for assemble. |
|
|
60
|
+
| R13 | **Verdict coherence** | §9 implementability / readiness matches §4 depth — no READY alongside unexplained NEEDS REFINEMENT or contradictory gates. |
|
|
61
|
+
|
|
62
|
+
**Not in default scope**: product-specific rules (talos lease wipe, ingest whitelist, L2/L3 layering) — load the matching guidance pack **only** when the change design requires it.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## 3. Revision rules (hard)
|
|
67
|
+
|
|
68
|
+
1. **Edit `approval/parts/*.md` only** — never edit assembled `approval.md` directly
|
|
69
|
+
2. **Update `index.yaml` first** when changing frozen ids, rpc names, or inventory
|
|
70
|
+
3. Each finding → fix in named `part` OR waive (`minor` only) with `waiver_reason`
|
|
71
|
+
4. Re-run:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
specflow approval finalize <change>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
## 4. Write review-result.json
|
|
80
|
+
|
|
81
|
+
Path: `approval/review-result.json`
|
|
82
|
+
|
|
83
|
+
```json
|
|
84
|
+
{
|
|
85
|
+
"schema": "specflow.approval.review/v1",
|
|
86
|
+
"change": "<change-name>",
|
|
87
|
+
"reviewed_at": "2026-08-26T12:00:00Z",
|
|
88
|
+
"reviewer": "ai",
|
|
89
|
+
"verdict": "pass",
|
|
90
|
+
"summary": "Fixed cross-part naming for I3; expanded P2 error path in 04-detail-core",
|
|
91
|
+
"part_hashes": [
|
|
92
|
+
{ "id": "04.5-api", "sha256": "<sha256-after-fixes>" },
|
|
93
|
+
{ "id": "04-detail-core", "sha256": "<sha256-after-fixes>" }
|
|
94
|
+
],
|
|
95
|
+
"findings": [
|
|
96
|
+
{
|
|
97
|
+
"id": "F1",
|
|
98
|
+
"severity": "critical",
|
|
99
|
+
"category": "cross_part_naming",
|
|
100
|
+
"message": "I3 RPC name differs between §2 and 04.5-api",
|
|
101
|
+
"part": "04.5-api",
|
|
102
|
+
"status": "fixed"
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
"id": "F2",
|
|
106
|
+
"severity": "important",
|
|
107
|
+
"category": "unclosed_branch",
|
|
108
|
+
"message": "Retry path mentioned in §4.3 but no terminal outcome",
|
|
109
|
+
"part": "04-detail-core",
|
|
110
|
+
"status": "fixed"
|
|
111
|
+
}
|
|
112
|
+
]
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
| verdict | When |
|
|
117
|
+
|---------|------|
|
|
118
|
+
| `pass` | All findings `fixed`; strict lint pass; **`part_hashes` match current parts** |
|
|
119
|
+
| `pass_with_waivers` | Only `minor` waived with `waiver_reason` |
|
|
120
|
+
| `fail` | Any `critical` / `important` still `open` |
|
|
121
|
+
|
|
122
|
+
**Waive policy**: only `minor` may be waived; critical/important must fix or escalate to user.
|
|
123
|
+
|
|
124
|
+
**part_hashes (required when `acp.review.enabled`)**: After fixing parts, run `specflow approval review-hashes <change> --json` and copy the array into `review-result.json`. `review-check` fails if parts change after review without updating review-result.
|
|
125
|
+
|
|
126
|
+
---
|
|
127
|
+
|
|
128
|
+
## 5. User gate
|
|
129
|
+
|
|
130
|
+
When a finding requires a **product/architecture choice** the artifacts do not resolve:
|
|
131
|
+
|
|
132
|
+
```text
|
|
133
|
+
[待用户确认] <topic>: options A / B / C — record choice as new decision + update affected parts
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
Stop finalize until user chooses; do not invent policy.
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## 6. Announce
|
|
141
|
+
|
|
142
|
+
```text
|
|
143
|
+
AI Review: findings=<n> fixed=<n> waived=<n> verdict=pass|fail
|
|
144
|
+
Next: specflow approval finalize <change>
|
|
145
|
+
```
|
|
@@ -1412,7 +1412,8 @@ When `approval/index.yaml` has `mode: segmented` (default for non-trivial §4),
|
|
|
1412
1412
|
2. **Gate** — user confirms index inventory + optional chapters + mode
|
|
1413
1413
|
3. **12b Map Append** — batched `04.4*` / `04.5*` / `04.6*` / `04.7–04.9`
|
|
1414
1414
|
4. **12c Optional** — `05*` / `07` / `08` only when opted in
|
|
1415
|
-
5. **
|
|
1415
|
+
5. **12e AI Review** — fix parts; write `review-result.json` with `part_hashes` (see `ai-review.md`)
|
|
1416
|
+
6. **12f Finalize** — `specflow approval finalize <change>` (lint → review-check → check → assemble → bundle)
|
|
1416
1417
|
|
|
1417
1418
|
**Reduce 禁止 LLM** — never stitch parts in chat or paste from memory.
|
|
1418
1419
|
|
|
@@ -1420,7 +1421,7 @@ When `approval/index.yaml` has `mode: segmented` (default for non-trivial §4),
|
|
|
1420
1421
|
|
|
1421
1422
|
| # | Forbidden | Required |
|
|
1422
1423
|
|---|-----------|----------|
|
|
1423
|
-
| L1 | One-shot full `approval.md` when `mode=segmented` | Write parts;
|
|
1424
|
+
| L1 | One-shot full `approval.md` when `mode=segmented` | Write parts; `specflow approval finalize` |
|
|
1424
1425
|
| L2 | Empty part, `< 20` chars, placeholder-only | Full section per Part E |
|
|
1425
1426
|
| L3 | `TODO` / `待补充` / `此处省略` / bare `TBD` | Concrete text or `[待 refine 澄清: <元素>]` |
|
|
1426
1427
|
| L4 | `详见 design/tasks` without §/In/Page id | Cross-ref `§4.5 I2` / `Page·列表` / `P1` |
|
|
@@ -1431,7 +1432,7 @@ When `approval/index.yaml` has `mode: segmented` (default for non-trivial §4),
|
|
|
1431
1432
|
| L7 | Skip IDE skills/rules scan for §4.6 | `frontend-guidance.md` §3 before Map |
|
|
1432
1433
|
| L8 | Paste skill/rule bodies verbatim | Readable Chinese + path in §4.6.1 |
|
|
1433
1434
|
| L9 | Foreign `## N.` headings in parts | `###`/`####` only; CLI injects chapter headers |
|
|
1434
|
-
| L10 | Mark done without
|
|
1435
|
+
| L10 | Mark done without finalize passing | Fix diagnostics; run `specflow approval finalize` |
|
|
1435
1436
|
|
|
1436
1437
|
CLI lazy validation mirrors L2–L3 (`lazy_part_content` on assemble/check).
|
|
1437
1438
|
|
|
@@ -1475,24 +1476,121 @@ User natural language, workset, or cross-repo design → `multi_repo.enabled=tru
|
|
|
1475
1476
|
|
|
1476
1477
|
### G.2 User gates (hard, before Stage 12a)
|
|
1477
1478
|
|
|
1478
|
-
1. **Document mode**:
|
|
1479
|
-
2. If **
|
|
1480
|
-
3. Record in `index.yaml`; do not assemble until
|
|
1479
|
+
1. **Document mode**: **A** bundle (per_repo + CLI bundle, recommended) **or** **B** per_repo only **or** **C** legacy unified LLM merge (discourage).
|
|
1480
|
+
2. If **A or C**: **主仓** `primary_repo` — playbook/bundle or unified workspace path.
|
|
1481
|
+
3. Record in `index.yaml`; set `acp.pipeline: acp/v2`; do not assemble until answered.
|
|
1481
1482
|
|
|
1482
|
-
### G.3
|
|
1483
|
+
### G.3 Bundle 合订视图 (recommended)
|
|
1484
|
+
|
|
1485
|
+
- Each repo: own `approval/` + `specflow approval assemble <repo.change>`.
|
|
1486
|
+
- Primary repo: `approval-playbook.yaml` + `specflow approval bundle <primary.change>`.
|
|
1487
|
+
- Output: `approval-unified.md` (readonly concatenation, no LLM merge).
|
|
1488
|
+
|
|
1489
|
+
### G.4 Legacy unified LLM 合订 (discouraged)
|
|
1483
1490
|
|
|
1484
1491
|
- Read **every** repo's four artifacts + anchors.
|
|
1485
1492
|
- `index.change` **should equal** primary repo's change name.
|
|
1486
1493
|
- Header lists all repos; §2.3 / 附录 B per-repo tables.
|
|
1487
1494
|
- CLI: `specflow approval assemble <primary.change>` from **primary** planning root.
|
|
1488
1495
|
|
|
1489
|
-
### G.
|
|
1496
|
+
### G.5 Per-repo 分仓
|
|
1490
1497
|
|
|
1491
1498
|
- Separate `approval/` (or monolithic `approval.md`) **in each repo**.
|
|
1492
1499
|
- Each document scoped to that repo only; cross-ref sibling paths.
|
|
1493
1500
|
- Separate assemble per repo.
|
|
1494
1501
|
|
|
1495
|
-
### G.
|
|
1502
|
+
### G.6 Inventory
|
|
1496
1503
|
|
|
1497
1504
|
Recommend `repo` on `tables[]` / `interfaces[]` / `pages[]` entries for unified mode traceability.
|
|
1498
1505
|
|
|
1506
|
+
### G.7 主仓一键 · Subagent 并行 (mode A)
|
|
1507
|
+
|
|
1508
|
+
> Router: `prompts/approval/multi-repo-spoke-subagent.md` · Orchestrator: `skills/specflow-approval/SKILL.md` **Stage 1c**
|
|
1509
|
+
|
|
1510
|
+
When user starts `/specflow:approval` from **primary** repo and chose **A (bundle)**:
|
|
1511
|
+
|
|
1512
|
+
1. Primary writes `approval-playbook.yaml`; spoke indexes set `bundle.enabled: false`.
|
|
1513
|
+
2. **Parallel** Task subagents per non-primary repo → full spoke Map + 12e + `finalize` (no `--bundle`).
|
|
1514
|
+
3. Primary **wait gate** — all spokes `finalize_ok`.
|
|
1515
|
+
4. Primary Map + finalize + `finalize --bundle --workspace-root <primary.planning_root>`.
|
|
1516
|
+
|
|
1517
|
+
**Anti-lazy (multi-repo)**: no unified LLM merge when mode A chosen; no stub spoke parts (`见 design.md` rows without decision text); each spoke needs `analysis.json` + `review-result.json` when `acp.review.enabled`.
|
|
1518
|
+
|
|
1519
|
+
---
|
|
1520
|
+
|
|
1521
|
+
## Part H: ACP Pipeline (Approval Compiler Pipeline)
|
|
1522
|
+
|
|
1523
|
+
> Router: `prompts/approval/acp-pipeline.md` · AI review: `prompts/approval/ai-review.md`
|
|
1524
|
+
|
|
1525
|
+
### H.1 When to use
|
|
1526
|
+
|
|
1527
|
+
| Signal | Action |
|
|
1528
|
+
|--------|--------|
|
|
1529
|
+
| Segmented mode (`approval/parts/`) | **Always** run ACP Verify before assemble |
|
|
1530
|
+
| Multi-repo bundle | per_repo assemble → `approval bundle` |
|
|
1531
|
+
| Long doc / cross-part inconsistency risk | Enable `acp.review` (Stage 12e) |
|
|
1532
|
+
|
|
1533
|
+
### H.2 Pipeline stages
|
|
1534
|
+
|
|
1535
|
+
```text
|
|
1536
|
+
Analyze (Pass 1–7) → IR Freeze (index.yaml + interfaces[].frozen)
|
|
1537
|
+
→ Map (batched parts) → lint → review-pack → AI Review (12e) → review-check
|
|
1538
|
+
→ check → assemble → bundle (optional)
|
|
1539
|
+
```
|
|
1540
|
+
|
|
1541
|
+
### H.3 index.yaml `acp` block
|
|
1542
|
+
|
|
1543
|
+
```yaml
|
|
1544
|
+
acp:
|
|
1545
|
+
pipeline: acp/v2
|
|
1546
|
+
review:
|
|
1547
|
+
enabled: true
|
|
1548
|
+
required_pass: true # assemble --require-review gates on this
|
|
1549
|
+
```
|
|
1550
|
+
|
|
1551
|
+
Also freeze RPC names in `interfaces[].frozen` before Map batches.
|
|
1552
|
+
|
|
1553
|
+
### H.4 CLI
|
|
1554
|
+
|
|
1555
|
+
**Preferred (skill default)**:
|
|
1556
|
+
|
|
1557
|
+
```bash
|
|
1558
|
+
specflow approval finalize <change> [--bundle] [--workspace-root <root>]
|
|
1559
|
+
```
|
|
1560
|
+
|
|
1561
|
+
| Command | Purpose |
|
|
1562
|
+
|---------|---------|
|
|
1563
|
+
| `specflow approval review-hashes <change> [--json]` | Emit `part_hashes[]` for `review-result.json` |
|
|
1564
|
+
| `specflow approval finalize <change>` | One-shot: lint → review-check → check → assemble → bundle |
|
|
1565
|
+
| `specflow approval lint <change> [--strict]` | Debug / CI: cross-part consistency |
|
|
1566
|
+
| `specflow approval review-pack <change>` | Debug: generate review packet |
|
|
1567
|
+
| `specflow approval review-check <change>` | Debug: validate review-result |
|
|
1568
|
+
| `specflow approval check <change>` | Debug: parts/index validation |
|
|
1569
|
+
| `specflow approval assemble <change> [--require-review]` | Debug: merge parts only |
|
|
1570
|
+
| `specflow approval bundle <change>` | Debug: multi-repo readonly merge |
|
|
1571
|
+
|
|
1572
|
+
### H.5 Stage 12e AI Review (mandatory when `acp.review.enabled`)
|
|
1573
|
+
|
|
1574
|
+
Runs **inside `/specflow-approval`** — not as separate user steps:
|
|
1575
|
+
|
|
1576
|
+
1. `specflow approval finalize <change>` — pauses with `review-packet.json` if needed
|
|
1577
|
+
2. Agent reads `prompts/approval/ai-review.md` + parts; fixes parts; writes `review-result.json`
|
|
1578
|
+
3. Re-run `specflow approval finalize <change>`
|
|
1579
|
+
|
|
1580
|
+
AI review targets **long-document failure modes**: cross-part naming drift, inventory/body mismatch, depth imbalance across batches, unclosed branches, diagram/prose divergence, §4.6/§4.5 misalignment — not product-specific case rules.
|
|
1581
|
+
|
|
1582
|
+
Optional domain packs (`runtime-guidance.md`, `api-guidance.md`) apply **only when** design/analysis mentions those topics.
|
|
1583
|
+
|
|
1584
|
+
### H.6 Render (MD → HTML)
|
|
1585
|
+
|
|
1586
|
+
```bash
|
|
1587
|
+
specflow approval render <change> [--input approval.md] [--output approval.html]
|
|
1588
|
+
specflow approval finalize <change> --render # optional: render after finalize
|
|
1589
|
+
```
|
|
1590
|
+
|
|
1591
|
+
Standalone HTML with embedded CSS; Mermaid diagrams load from CDN when present.
|
|
1592
|
+
|
|
1593
|
+
### H.7 Playbook bundle (multi-repo)
|
|
1594
|
+
|
|
1595
|
+
Template: `templates/approval-playbook.yaml`. Lists per-repo `approval.md` paths; `bundle` concatenates with repo headers — **no LLM merge**.
|
|
1596
|
+
|
|
@@ -69,25 +69,61 @@ multi_repo:
|
|
|
69
69
|
```text
|
|
70
70
|
本需求跨 N 个仓库,审批技术文档如何产出?
|
|
71
71
|
|
|
72
|
-
A)
|
|
73
|
-
B)
|
|
72
|
+
A) 一份合订视图 (bundle) — 各仓 per_repo 真源 + CLI bundle 只读合订 (**推荐**)
|
|
73
|
+
B) 多份分仓 (per_repo) — 每仓各自 approval.md(默认 Map 模式)
|
|
74
|
+
C) 一份 LLM 合订 (legacy unified) — 仅当用户明确要求且无 bundle;不推荐
|
|
74
75
|
|
|
75
|
-
请选择 A 或
|
|
76
|
+
请选择 A、B 或 C。
|
|
76
77
|
```
|
|
77
78
|
|
|
78
|
-
### 2.1
|
|
79
|
+
### 2.1 Bundle(推荐 — A)
|
|
79
80
|
|
|
80
|
-
|
|
81
|
+
**真源**: 各仓 **per_repo** `approval.md` + `approval/parts/`(ACP Map 分片)。
|
|
81
82
|
|
|
82
|
-
|
|
83
|
-
|
|
83
|
+
**只读合订**: 主仓 `approval-playbook.yaml` + `specflow approval bundle <primary.change>` → `approval-unified.md`(**无 LLM 合并**)。
|
|
84
|
+
|
|
85
|
+
再询问主仓:
|
|
84
86
|
|
|
87
|
+
```text
|
|
88
|
+
合订 playbook 与 bundle 输出存放在哪个主仓?
|
|
85
89
|
1) talos (平台)
|
|
86
90
|
2) talos-web (控制台)
|
|
87
|
-
3) talos-worker (Worker)
|
|
88
91
|
…
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
**硬规则**:
|
|
95
|
+
|
|
96
|
+
- `multi_repo.document_mode: per_repo`
|
|
97
|
+
- `multi_repo.bundle.enabled: true`
|
|
98
|
+
- `multi_repo.primary_repo: <id>` — playbook 与 bundle 输出路径
|
|
99
|
+
- 各仓独立 Stage 12 + assemble;**全部 assemble 通过后** 在主仓执行 bundle
|
|
100
|
+
- `acp.pipeline: acp/v2` 写入 `index.yaml`
|
|
89
101
|
|
|
90
|
-
|
|
102
|
+
```yaml
|
|
103
|
+
multi_repo:
|
|
104
|
+
document_mode: per_repo
|
|
105
|
+
primary_repo: talos
|
|
106
|
+
bundle:
|
|
107
|
+
enabled: true
|
|
108
|
+
output: approval-unified.md
|
|
109
|
+
outputs:
|
|
110
|
+
per_repo: [ …各仓路径… ]
|
|
111
|
+
bundle:
|
|
112
|
+
repo: talos
|
|
113
|
+
change: scenario-job-compile
|
|
114
|
+
path: specflow/changes/scenario-job-compile/approval-unified.md
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
### 2.2 Per-repo only(B)
|
|
118
|
+
|
|
119
|
+
见 §2.3;`bundle.enabled: false`。
|
|
120
|
+
|
|
121
|
+
### 2.3 Legacy unified LLM 合订(C — 不推荐)
|
|
122
|
+
|
|
123
|
+
仅在用户 **明确要求** 且拒绝 bundle 时使用。再询问主仓:
|
|
124
|
+
|
|
125
|
+
```text
|
|
126
|
+
合订文档存放在哪个主仓?(approval.md 与 approval/ 工作区写在该仓 change 目录下)
|
|
91
127
|
```
|
|
92
128
|
|
|
93
129
|
**硬规则**:
|
|
@@ -112,7 +148,7 @@ outputs:
|
|
|
112
148
|
path: specflow/changes/scenario-job-compile/approval.md
|
|
113
149
|
```
|
|
114
150
|
|
|
115
|
-
### 2.
|
|
151
|
+
### 2.4 Per-repo(B 详情)
|
|
116
152
|
|
|
117
153
|
**硬规则**:
|
|
118
154
|
|
|
@@ -200,3 +236,28 @@ interfaces:
|
|
|
200
236
|
## 7. 与单仓关系
|
|
201
237
|
|
|
202
238
|
`multi_repo.enabled=false` 时忽略本章;`change` 字段为当前规划根 change,行为与旧版一致。
|
|
239
|
+
|
|
240
|
+
---
|
|
241
|
+
|
|
242
|
+
## 8. 主仓一键 · Subagent 并行 (mode A/B)
|
|
243
|
+
|
|
244
|
+
> Router: `prompts/approval/multi-repo-spoke-subagent.md` · Orchestrator: `skills/specflow-approval/SKILL.md` **Stage 1c**
|
|
245
|
+
|
|
246
|
+
当用户在 **主仓** 发起 `/specflow:approval` 且已选 **A (bundle)** 或 **B (per_repo)**:
|
|
247
|
+
|
|
248
|
+
| 角色 | 职责 |
|
|
249
|
+
|------|------|
|
|
250
|
+
| **主 Agent(主仓)** | intake、playbook、scope 拆分、闭环 Pass 1–11、主仓 Map、等待子仓、主仓 finalize、bundle |
|
|
251
|
+
| **Subagent × 子仓** | 各子仓独立 `approval/` → Map → 12e → `finalize <spoke.change>`(**禁止** `--bundle`) |
|
|
252
|
+
|
|
253
|
+
**硬顺序**:
|
|
254
|
+
|
|
255
|
+
1. 主仓写好 `approval-playbook.yaml` + `multi_repo.repos[].root_hint`
|
|
256
|
+
2. **并行**派发子仓 subagent(web / worker / …)
|
|
257
|
+
3. **等待**全部 `finalize_ok: true`
|
|
258
|
+
4. 主仓 Map + finalize
|
|
259
|
+
5. 主仓 `finalize --bundle --workspace-root <主仓规划根>`
|
|
260
|
+
|
|
261
|
+
**禁止**: 仅在主仓 unified 合订而不拆仓;子仓未 finalize 就 bundle;让用户手动 cd 子仓跑 CLI(除非 subagent 不可用)。
|
|
262
|
+
|
|
263
|
+
**从 unified 迁移**: 将 `04.6-ui`、Worker L2 接口等 **搬迁** 到对应子仓 parts;主仓留 cross-ref + 平台/L3 正文。示例 playbook: `templates/approval-playbook-talos-scenario-job-compile.yaml`。
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Approval · Multi-Repo Spoke Subagent Brief
|
|
2
|
+
|
|
3
|
+
> **Invoked by** primary `/specflow:approval` orchestrator via **Task** subagent (one per non-primary repo).
|
|
4
|
+
> Primary repo Map/Review/Finalize stays on the **orchestrator** unless user explicitly runs approval from a spoke root.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Mission
|
|
9
|
+
|
|
10
|
+
Run **full ACP approval for ONE spoke repo only** — Index → Map → Stage 12e AI Review → `specflow approval finalize <spoke.change>` — scoped to that repo's four artifacts and **only** entities assigned to this repo in the shared playbook / primary `index.yaml`.
|
|
11
|
+
|
|
12
|
+
**Do NOT** write into the primary repo. **Do NOT** LLM-merge cross-repo content into one file.
|
|
13
|
+
|
|
14
|
+
**Spoke index rule**: only **`primary_repo`** sets `multi_repo.bundle.enabled: true` + hosts `approval-playbook.yaml`. Spoke repos set `bundle.enabled: false` — they **never** run `--bundle`.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Inputs (primary must pass all)
|
|
19
|
+
|
|
20
|
+
| Field | Example |
|
|
21
|
+
|-------|---------|
|
|
22
|
+
| `repo_id` | `talos-web` |
|
|
23
|
+
| `planning_root` | `/Users/gankang/TALOS-WORK/talos-web` |
|
|
24
|
+
| `change` | `web-scenario-cases` |
|
|
25
|
+
| `role` | `web` |
|
|
26
|
+
| `primary_change` | `scenario-job-compile` |
|
|
27
|
+
| `primary_repo_id` | `talos` |
|
|
28
|
+
| `workset_root` | `/Users/gankang/TALOS-WORK` |
|
|
29
|
+
| `scope` | Which parts/capabilities/interfaces/pages belong to this spoke (from playbook or primary index) |
|
|
30
|
+
| `cross_ref_policy` | Cross-repo refs: `见 talos approval §4.5 I8` — never duplicate platform DDL/RPC bodies |
|
|
31
|
+
|
|
32
|
+
Read before writing:
|
|
33
|
+
|
|
34
|
+
1. `specflow/changes/<change>/` four artifacts (phase must be `refined`)
|
|
35
|
+
2. `prompts/approval/generate.md` (Part E/F), `acp-pipeline.md`, `ai-review.md`
|
|
36
|
+
3. Role packs: `frontend-guidance.md` (web), `api-guidance.md` (worker), etc.
|
|
37
|
+
4. Primary `approval/index.yaml` `multi_repo.repos[]` entry for this repo
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## Hard scope rules
|
|
42
|
+
|
|
43
|
+
| Role | Own in approval/parts | Cross-ref only (do not copy bodies) |
|
|
44
|
+
|------|----------------------|-------------------------------------|
|
|
45
|
+
| `platform` | compile, scheduler RPC/L4, DDL, gateway, ingest | Worker L2 HTTP, console pages |
|
|
46
|
+
| `web` | §4.6 UI, web APIs (I5/I6), nav/routes | Platform scheduler/result RPC details |
|
|
47
|
+
| `worker` | L2 Worker HTTP (I7/I9), executor logic, Pack | Platform L3 SubmitStepResult, Web UI |
|
|
48
|
+
|
|
49
|
+
Each spoke document is **standalone per repo**: `01-intro` … `10-signoff` with **repo-scoped** §1–§3 and detailed §4 batches for that repo only.
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Execution order (spoke)
|
|
54
|
+
|
|
55
|
+
```text
|
|
56
|
+
cd <planning_root>
|
|
57
|
+
→ Write approval/index.yaml (multi_repo.enabled=false OR spoke-local block only)
|
|
58
|
+
→ Write approval/analysis.json (Passes scoped to this repo)
|
|
59
|
+
→ 12a skeleton parts
|
|
60
|
+
→ 12b Map batches (repo scope only)
|
|
61
|
+
→ 12e: specflow approval finalize <change> # may pause → review-packet
|
|
62
|
+
→ Fix parts; write review-result.json + part_hashes (specflow approval review-hashes --json)
|
|
63
|
+
→ specflow approval finalize <change> # must exit ok
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**Never** run `--bundle` on a spoke. Bundle is **primary only**, after all spokes report success.
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Return payload to orchestrator (required)
|
|
71
|
+
|
|
72
|
+
Report in final message:
|
|
73
|
+
|
|
74
|
+
```yaml
|
|
75
|
+
repo_id: talos-web
|
|
76
|
+
change: web-scenario-cases
|
|
77
|
+
finalize_ok: true
|
|
78
|
+
output_path: specflow/changes/web-scenario-cases/approval.md
|
|
79
|
+
review_result: specflow/changes/web-scenario-cases/approval/review-result.json
|
|
80
|
+
lint_errors: []
|
|
81
|
+
blocked: false
|
|
82
|
+
notes: ""
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
If `finalize_ok: false`, set `blocked: true` and paste diagnostics — orchestrator **must not** bundle.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## Anti-patterns
|
|
90
|
+
|
|
91
|
+
- Writing `04.6-ui` into platform repo when web spoke exists
|
|
92
|
+
- Running bundle from spoke cwd
|
|
93
|
+
- Skipping finalize and pasting assembled markdown
|
|
94
|
+
- Unified LLM merge (mode C) when mode A was chosen
|