specpro-cli 0.1.0__py3-none-any.whl
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.
- specpro_cli/__init__.py +16 -0
- specpro_cli/assets/commands/specpro.analyze.md +1102 -0
- specpro_cli/assets/commands/specpro.checklist.md +335 -0
- specpro_cli/assets/commands/specpro.clarify.md +581 -0
- specpro_cli/assets/commands/specpro.constitution.md +488 -0
- specpro_cli/assets/commands/specpro.feature.md +115 -0
- specpro_cli/assets/commands/specpro.implement.md +1881 -0
- specpro_cli/assets/commands/specpro.manual-test.md +206 -0
- specpro_cli/assets/commands/specpro.plan.md +3284 -0
- specpro_cli/assets/commands/specpro.qc.md +1489 -0
- specpro_cli/assets/commands/specpro.scenarios.md +154 -0
- specpro_cli/assets/commands/specpro.specify.md +1449 -0
- specpro_cli/assets/commands/specpro.status.md +863 -0
- specpro_cli/assets/commands/specpro.tasks.md +1207 -0
- specpro_cli/assets/commands/specpro.test-implement.md +462 -0
- specpro_cli/assets/commands/specpro.test-plan.md +383 -0
- specpro_cli/assets/commands/specpro.user-manual.md +178 -0
- specpro_cli/assets/scripts/bash/check-anti-coupling.sh +293 -0
- specpro_cli/assets/scripts/bash/check-prerequisites.sh +176 -0
- specpro_cli/assets/scripts/bash/common.sh +88 -0
- specpro_cli/assets/scripts/bash/create-new-feature.sh +336 -0
- specpro_cli/assets/scripts/bash/qc-auto-fix.sh +121 -0
- specpro_cli/assets/scripts/bash/setup-plan.sh +60 -0
- specpro_cli/assets/scripts/bash/verify-cumulative-records.sh +203 -0
- specpro_cli/assets/scripts/bash/verify-deliverables-tracked.sh +147 -0
- specpro_cli/assets/scripts/bash/verify-deployment.sh +239 -0
- specpro_cli/assets/scripts/bash/verify-frontmatter-yaml.sh +63 -0
- specpro_cli/assets/scripts/bash/verify-ledger.sh +376 -0
- specpro_cli/assets/scripts/bash/verify-shapes.sh +1082 -0
- specpro_cli/assets/scripts/git-hooks/pre-commit +243 -0
- specpro_cli/assets/scripts/install-git-hooks.sh +67 -0
- specpro_cli/assets/scripts/powershell/check-anti-coupling.ps1 +249 -0
- specpro_cli/assets/scripts/powershell/check-prerequisites.ps1 +148 -0
- specpro_cli/assets/scripts/powershell/common.ps1 +95 -0
- specpro_cli/assets/scripts/powershell/create-new-feature.ps1 +229 -0
- specpro_cli/assets/scripts/powershell/qc-auto-fix.ps1 +110 -0
- specpro_cli/assets/scripts/powershell/setup-plan.ps1 +61 -0
- specpro_cli/assets/scripts/powershell/verify-cumulative-records.ps1 +133 -0
- specpro_cli/assets/scripts/powershell/verify-deliverables-tracked.ps1 +112 -0
- specpro_cli/assets/scripts/powershell/verify-deployment.ps1 +278 -0
- specpro_cli/assets/scripts/powershell/verify-frontmatter-yaml.ps1 +56 -0
- specpro_cli/assets/scripts/powershell/verify-ledger.ps1 +383 -0
- specpro_cli/assets/scripts/powershell/verify-shapes.ps1 +978 -0
- specpro_cli/assets/templates/agent-context-template.md +49 -0
- specpro_cli/assets/templates/assumptions-template.md +248 -0
- specpro_cli/assets/templates/checklist-template.md +40 -0
- specpro_cli/assets/templates/clarifications-template.md +155 -0
- specpro_cli/assets/templates/constitution-template.md +50 -0
- specpro_cli/assets/templates/feature-spec-template.md +66 -0
- specpro_cli/assets/templates/plan-overview-template.md +150 -0
- specpro_cli/assets/templates/plan-template.md +387 -0
- specpro_cli/assets/templates/protocol-golden-bytes-guide.md +195 -0
- specpro_cli/assets/templates/requirements-template.md +356 -0
- specpro_cli/assets/templates/spec-template.md +267 -0
- specpro_cli/assets/templates/tasks-template.md +252 -0
- specpro_cli/assets/templates/test-tasks-template.md +174 -0
- specpro_cli/cli/__init__.py +5 -0
- specpro_cli/cli/cmd_init.py +416 -0
- specpro_cli/cli/cmd_remove.py +122 -0
- specpro_cli/cli/entry.py +181 -0
- specpro_cli/integrations/__init__.py +36 -0
- specpro_cli/integrations/base.py +601 -0
- specpro_cli/integrations/claude/__init__.py +101 -0
- specpro_cli/integrations/copilot/__init__.py +153 -0
- specpro_cli/integrations/cursor_agent/__init__.py +51 -0
- specpro_cli/integrations/gemini/__init__.py +44 -0
- specpro_cli/integrations/opencode/__init__.py +48 -0
- specpro_cli/integrations/qodercli/__init__.py +54 -0
- specpro_cli/integrations/registry.py +88 -0
- specpro_cli/packaged/__init__.py +5 -0
- specpro_cli/packaged/sync.py +106 -0
- specpro_cli-0.1.0.dist-info/METADATA +117 -0
- specpro_cli-0.1.0.dist-info/RECORD +76 -0
- specpro_cli-0.1.0.dist-info/WHEEL +4 -0
- specpro_cli-0.1.0.dist-info/entry_points.txt +2 -0
- specpro_cli-0.1.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,3284 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: "Execute the implementation planning workflow using the plan template to generate design artifacts. ✨ OPTIMIZED: Pre-flight checks, incremental updates, clear next steps."
|
|
3
|
+
handoffs:
|
|
4
|
+
- label: Create Tasks
|
|
5
|
+
agent: specpro-tasks
|
|
6
|
+
prompt: Break the plan into tasks
|
|
7
|
+
send: true
|
|
8
|
+
- label: Create Checklist
|
|
9
|
+
agent: specpro-checklist
|
|
10
|
+
prompt: Create a checklist for the following domain...
|
|
11
|
+
writes:
|
|
12
|
+
# This command's write surface: only what it produces AS THE PRODUCER of that
|
|
13
|
+
# (artifact, unit) pair. A write this command makes on a non-producer path is a
|
|
14
|
+
# boundary violation by definition (FR-051) and MUST NOT be declared here.
|
|
15
|
+
# The full ownership map is the UNION of every command's writes: block.
|
|
16
|
+
- artifact: specs/plan.md
|
|
17
|
+
unit: "## Technical Context, ## Quality Targets, ## Architecture (b-d), ## Project Structure, ## Deprecated Items"
|
|
18
|
+
- artifact: specs/plan-overview.md
|
|
19
|
+
unit: "## Summary, ## Constitution Check, ## Implementation Plan, ## Complexity Tracking"
|
|
20
|
+
- artifact: specs/research.md
|
|
21
|
+
unit: "whole file - every NEEDS CLARIFICATION decision resolved; **not** the appended ## Addendum sections, which are /specpro-implement's"
|
|
22
|
+
- artifact: specs/data-model.md
|
|
23
|
+
unit: "entity blocks; incremental mode updates only the entities of planStatus=update stories"
|
|
24
|
+
- artifact: specs/contracts/<name>.md
|
|
25
|
+
unit: "whole file per contract; regenerated/merged when its source moves"
|
|
26
|
+
- artifact: specs/quickstart.md
|
|
27
|
+
unit: "whole file"
|
|
28
|
+
- artifact: specs/scenarios.md
|
|
29
|
+
unit: "whole file - INITIAL RUN ONLY; ownership then passes to /specpro-scenarios"
|
|
30
|
+
- artifact: specs/spec.md
|
|
31
|
+
unit: "per-item Lifecycle fields -> [plan:processed|deprecated]"
|
|
32
|
+
- artifact: specs/implement_issues.md
|
|
33
|
+
unit: "the [plan] section -> appended ISS-NNN entries; its own entries marked [x]; the statistics table (**its own row only** — seven commands declare this artifact); appended ISS-NNN entries in any section — registration is routing; only [x]-marking is section-scoped"
|
|
34
|
+
- artifact: CLAUDE.md (or AGENTS.md / .cursorrules / equivalent)
|
|
35
|
+
unit: "thin pointer only - created if missing; entries added or fixed only when missing or contradictory"
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## User Input
|
|
39
|
+
|
|
40
|
+
```text
|
|
41
|
+
$ARGUMENTS
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
You **MUST** consider the user input before proceeding (if not empty).
|
|
45
|
+
|
|
46
|
+
**Rerun safety — detect the artifact, default to incremental** ⚠️ [settled 2026-09-13]:
|
|
47
|
+
|
|
48
|
+
**Before writing `specs/plan.md`, detect whether it already exists.** Use the SAME check in every command:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
[ -s specs/plan.md ] && echo EXISTS || echo NEW # -s: exists AND non-empty (an empty placeholder counts as NEW)
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**This command produces several artifacts** (`data-model.md`, `plan-overview.md`, `research.md`, `contracts/`, and — **on the initial run only** — `scenarios.md`). `plan.md` is the sentinel: when it is present the run is incremental, and the same rule governs every companion artifact produced in that run. **`scenarios.md` is the exception** ⚠️: once the initial run creates it, ownership passes to `/specpro-scenarios`, and this command never rewrites it.
|
|
55
|
+
|
|
56
|
+
| Detection | Mode |
|
|
57
|
+
|-----------|------|
|
|
58
|
+
| **NEW** (absent or empty) | **Initial** — generate from scratch |
|
|
59
|
+
| **EXISTS** | **Incremental** — evolve it; **never silently regenerate from scratch** |
|
|
60
|
+
|
|
61
|
+
**Overwriting an existing artifact requires explicit, confirmed intent:**
|
|
62
|
+
1. Only when the user *explicitly* asks (in their own words) does the initial path run on an existing artifact.
|
|
63
|
+
2. **Even then, confirm once more before writing** — name the artifact that will be replaced and what will be lost; wait for the answer.
|
|
64
|
+
3. **Silence is not consent.** An unspecified run on an existing artifact is ALWAYS incremental.
|
|
65
|
+
|
|
66
|
+
> **Why a shared rule rather than per-command courtesy**: nine of the twelve non-implementation commands already had some protection, but each wrote it its own way (`EXISTING_SPEC` check · "creates a NEW file" · `NEVER overwrite` · "incremental regeneration" · `AUTO_MODE=false`), and **three had none at all** — not by decision, but because the discipline had no shared carrier. Overwriting an artifact the user has been evolving is not recoverable within the session; the cost of asking is one prompt.
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
### Scope Resolution 🆕 (FR-063 / T050 · v0.23)
|
|
70
|
+
|
|
71
|
+
1. **作用域判定**: 当前工作目录位于 `specs/fNNN-简称/` 内 ⇒ **feature 作用域**(读写范围 = 本 feature 目录,由 `check-prerequisites.sh` 的作用域感知解析);位于仓库根或 `specs/` 根 ⇒ **母作用域**(读写母规格链)。feature 作用域内 MUST NOT 写母产物——唯一例外:**发现登记**(台账路由,`[specify]`/`[plan]` 分区)。
|
|
72
|
+
2. **新会话首次执行**: 若 `specs/features.md` 存在且含 `active` 行、而用户未指明作用域 ⇒ **询问用户**在母作用域还是某个 feature 内工作,MUST NOT 自行挑选。
|
|
73
|
+
3. 本命令的产物路径随之解析:feature 作用域下落 `<feature 目录>/`,母作用域下落 `specs/`。
|
|
74
|
+
|
|
75
|
+
## Optimization Summary
|
|
76
|
+
|
|
77
|
+
This optimized version includes:
|
|
78
|
+
- ✅ **Pre-flight Checks** (Step 1.5) - Fail fast, clear error messages
|
|
79
|
+
- ✅ **One-time Lifecycle Cache** (Step 4) - Eliminate redundant spec.md reads
|
|
80
|
+
- ✅ **Contract Pre-validation** (Phase 1 Step 2.0) - Generate only missing contracts
|
|
81
|
+
- ✅ **Progress Indicators** - Clear visibility into execution progress
|
|
82
|
+
- ✅ **Enhanced Next Steps** (Step 7) - Clear guidance after Phase 2
|
|
83
|
+
|
|
84
|
+
**Performance Impact**: 20-30% faster for incremental updates, clearer UX
|
|
85
|
+
|
|
86
|
+
## Outline
|
|
87
|
+
|
|
88
|
+
**Artifact Language Rule** 🌐 [CRITICAL — applies to ALL generated content]:
|
|
89
|
+
- **Prose content** (descriptions, rationale, scenario text, guidance) follows the project's **Artifact Language** setting — from `specs/constitution.md` → **Artifact Language** field; default `en` when absent
|
|
90
|
+
- **Structural anchors are ALWAYS English**, regardless of the artifact language: section headings from the template, item ID prefixes (US/FR), status enums, and table column names — exactly as written in the template
|
|
91
|
+
- **Entry field labels are structural anchors too** (`source:`, `Evidence:`, `Fix Direction:`) — never translated, even when the surrounding prose is not English. They exist to be **searched**: an entry's fields must be greppable across artifacts and projects, and a translated label silently drops out of every consumer's scan.
|
|
92
|
+
- Rationale: fixed anchors keep artifacts machine-parseable across specpro commands and keep instructions ↔ artifacts aligned for review
|
|
93
|
+
|
|
94
|
+
### **Step 0: Check for --review-issues argument** 🆕
|
|
95
|
+
|
|
96
|
+
**Purpose**: Process implement issues submitted from the implement phase
|
|
97
|
+
|
|
98
|
+
**0.1 Parse arguments**:
|
|
99
|
+
- If `$ARGUMENTS` contains `--review-issues`:
|
|
100
|
+
* **Skip the question below**; proceed directly to step 0.2 (review issues)
|
|
101
|
+
- Else: **detect, then ask** ⚠️ [settled 2026-09-13]:
|
|
102
|
+
* Check the `[plan]` section of `specs/implement_issues.md` for open `[ ]` entries
|
|
103
|
+
* **None** → continue with normal plan generation (Step 1+). **No prompt.**
|
|
104
|
+
* **Some** → **ask**: "N open `[plan]` issues in specs/implement_issues.md. Process them first, or run normally?"
|
|
105
|
+
- *Process first* → proceed to step 0.2 (review issues)
|
|
106
|
+
- *Run normally* → continue with normal plan generation (Step 1+)
|
|
107
|
+
* **Rationale**: the flag used to be the whole switch — not passing it left pending issues **silently unprocessed**, passing it meant overriding the work the user actually wanted, and **which issues were pending was invisible until the command ran**. Detect-then-ask makes it an explicit choice; the flag now only means *"I already know — don't ask"*.
|
|
108
|
+
(Same model as `/specpro-implement` and `/specpro-test-plan` — see TOOL-008.)
|
|
109
|
+
|
|
110
|
+
**0.2 Review implement issues**:
|
|
111
|
+
|
|
112
|
+
**a. Read issues file**:
|
|
113
|
+
- Read `specs/implement_issues.md`
|
|
114
|
+
- Extract all issues from `[plan]` section
|
|
115
|
+
- Filter for issues marked `[ ]` (pending) only
|
|
116
|
+
- If no pending issues found:
|
|
117
|
+
* Display: "✓ No pending [plan] issues to process"
|
|
118
|
+
* Exit
|
|
119
|
+
|
|
120
|
+
**b. Display issue summary**:
|
|
121
|
+
```markdown
|
|
122
|
+
📋 [plan] Issues Review
|
|
123
|
+
|
|
124
|
+
Found N pending [plan] issues:
|
|
125
|
+
1. [ ] ISS-XXX: Issue description
|
|
126
|
+
2. [ ] ISS-XXX: Issue description
|
|
127
|
+
...
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**c. Process each issue**:
|
|
131
|
+
For each pending issue:
|
|
132
|
+
* Read issue details:
|
|
133
|
+
- Problem description
|
|
134
|
+
- Current plan (what's wrong)
|
|
135
|
+
- Suggested plan (what should be)
|
|
136
|
+
- Related tasks/modules
|
|
137
|
+
* Determine appropriate action:
|
|
138
|
+
- **Update design**: Modify design section in plan.md
|
|
139
|
+
- **Change technology**: Update technology stack
|
|
140
|
+
- **Adjust architecture**: Modify architecture section
|
|
141
|
+
- **Add missing design**: Insert new design section
|
|
142
|
+
- **Fix contract**: Correct the affected file under `specs/contracts/`
|
|
143
|
+
* Apply the change to the artifact the action targets — plan.md, or the contract file
|
|
144
|
+
* Mark issue as `[x]` in implement_issues.md
|
|
145
|
+
* Display: "✓ Processed ISS-XXX: [action taken]"
|
|
146
|
+
|
|
147
|
+
**Ownership of contract findings** 🌐: this command owns `specs/contracts/` — a contract is a plan-phase artifact, and a finding against one is fixed here rather than by the audit that reported it. `/specpro-analyze` reports and stays read-only by default; it does not edit contracts.
|
|
148
|
+
|
|
149
|
+
Route by *which link is broken*:
|
|
150
|
+
|
|
151
|
+
| The finding says | Broken link | Fixed here by |
|
|
152
|
+
|------------------|-------------|---------------|
|
|
153
|
+
| The contract misstates what its cited source says | contract | correcting the contract |
|
|
154
|
+
| The contract has no citation, or cites a source that cannot cover the claim | contract | adding a supportable citation — and if no source can support it, the item is a design choice and MUST be recorded as one |
|
|
155
|
+
| The contract correctly reflects a source that is itself wrong or missing | the source (spec / FR / upstream artifact) | correcting the contract to match reality in the near term, **and** raising the upstream artifact as a `[specify]` issue — a contract MUST NOT be left stating a wrong fact merely because its source is wrong |
|
|
156
|
+
| The contract reflects the implementing code (self-witness) | contract | replacing the citation with an independent source; if none exists, record the item as unverified rather than asserting it |
|
|
157
|
+
|
|
158
|
+
When fixing a contract, apply the source-attribution requirements of the contract content rules (source layer and version for every asserted fact; no implementation-as-source).
|
|
159
|
+
|
|
160
|
+
**Handing work downstream — the obligation, and the form it must take** ⚠️ [FR-048 / ISS-110 · ISS-93]
|
|
161
|
+
|
|
162
|
+
A resolution may conclude that the work belongs to a later stage. When it does, **this round MUST
|
|
163
|
+
also register the entry, in the target section, in the same pass** — a decision that says the work
|
|
164
|
+
moved, with nothing arriving at the target, is indistinguishable from a decision that was never
|
|
165
|
+
acted on.
|
|
166
|
+
|
|
167
|
+
⚠️ **Why this is written down at all**: the channel was never missing. 登记即路由 — any command may
|
|
168
|
+
append to any section, and that is the ledger's only routing act. What was missing was the
|
|
169
|
+
**obligation** to append, and a point where its absence stops something. The observed case: a
|
|
170
|
+
resolution closed with "hand this to `/specpro-tasks --review-issues`", created no `[tasks]` entry,
|
|
171
|
+
and that command read an **empty queue** and exited having done nothing — while the resolution read
|
|
172
|
+
as complete.
|
|
173
|
+
|
|
174
|
+
**The form** — write the hand-off on its own line, inside the resolving entry, exactly like this:
|
|
175
|
+
|
|
176
|
+
**移交**: <target section> → ISS-NNN
|
|
177
|
+
|
|
178
|
+
- `<target section>` is a section name **as the contract spells it** — `tasks`, `specify`, `test-plan`,
|
|
179
|
+
… A name the contract does not define has no consumer, and a hand-off there is a dead end.
|
|
180
|
+
- `ISS-NNN` is the entry **written into that section in this same round**.
|
|
181
|
+
- ⚠️ **The form is fixed, and that is the only reason this can be judged mechanically.** An
|
|
182
|
+
intention scattered through prose has no shape to test. `scripts/bash/verify-ledger.sh`
|
|
183
|
+
(and its PowerShell twin) asserts it: for every **completed** entry carrying such a line, the
|
|
184
|
+
named ID must exist **in the named section**, and the named section must be one the contract
|
|
185
|
+
defines. The check is a commit-time gate — the pre-commit hook runs that verifier.
|
|
186
|
+
- ⚠️ **Only `[x]` entries are checked.** An entry still `[ ]` has not handed anything off yet;
|
|
187
|
+
requiring its target to exist would punish the correct order of work.
|
|
188
|
+
- A hand-off line **without** a registration is the failure this rule exists to stop. If the work
|
|
189
|
+
genuinely does not belong to a later stage, do not write the line.
|
|
190
|
+
|
|
191
|
+
**裁定触及工具源时:授权边界不动,改走移交** ⚠️ [FR-051 · ISS-119 · ISS-153 · T169]
|
|
192
|
+
|
|
193
|
+
`plan` 层的裁定**经常**需要同时改两处:契约(`specs/contracts/`,**在本命令的写入面内 ✓**)与
|
|
194
|
+
**工具源**(`commands/` · `templates/` · `scripts/` · `tools/`,**不在 ✗**)。
|
|
195
|
+
成例是 `ISS-115`:它的裁定要求同时改契约与 `tools/specpro.dev-audit.md`。
|
|
196
|
+
|
|
197
|
+
**处置 —— 不动写入面,改走 `[tasks]` 移交:**
|
|
198
|
+
|
|
199
|
+
1. 在**写入面内**做完能做的:更正契约、更正本命令自己的产物。
|
|
200
|
+
2. **同轮**按上面的**移交形态**登记一条 `[tasks]` 条目(`**移交**: [tasks] → ISS-NNN`),
|
|
201
|
+
条目里**点名工具源的那个文件**,并写明缺的是哪一步。
|
|
202
|
+
3. ⚠️ **指向与登记必须同轮**:在契约里写一句"此事由某任务承接"却**不登记**,那句话就
|
|
203
|
+
**指不到任何能动它的任务**(`ISS-153` 的形态 —— 它当时指向一条 Location 不含该文件的在办任务)。
|
|
204
|
+
登记之后,`scripts/bash/verify-ledger.sh` 的移交检查**会核这条点名**:点名的条目不存在即**报错**。
|
|
205
|
+
|
|
206
|
+
⚠️ **为什么不把工具源加进 `writes:`**(这是本条被反复重推的那个岔口,一次写死):
|
|
207
|
+
`writes:` 块**自己的判据**是"本命令**作为生产者**产出什么",而本命令**不是**工具源的生产者
|
|
208
|
+
—— 加进去会与该判据直接冲突。FR-051 要的是"**越界不发生**",而不是"越界被声明";
|
|
209
|
+
**把一处越界写进声明,不使它成为不越界**,只是把它从可发现变成已登记。
|
|
210
|
+
⇒ 工具源的生产者**仍然是任务**(`/specpro-implement` 执行一条 Location 点名了该文件的任务)。
|
|
211
|
+
|
|
212
|
+
**d. Update statistics**:
|
|
213
|
+
- Update the statistics table at the **top** of `implement_issues.md` (its position is deliberate — see the note below)
|
|
214
|
+
- **Edit order and idempotency check** ⚠️ [a silent false-skip, observed 2026-09-13]: write the **entry body first** (into its own section), then the derived summaries (statistics table + `Last Updated`) — never the reverse. A derived summary written first introduces the new ID into the file's text before the entry exists, so an idempotency guard that greps the file for that ID falsely concludes "already present" and **skips the entry**, while the summaries still claim it landed. For the same reason the guard MUST match the entry body's **line-start pattern**, never a full-text keyword search:
|
|
215
|
+
```bash
|
|
216
|
+
grep -qE '^- \[[x ]\] ISS-<N>:' specs/implement_issues.md # correct — matches an ENTRY, not a mention
|
|
217
|
+
# grep -q 'ISS-<N>' … # wrong — also matches the statistics Pending-Items column, the Last Updated line, cross-references
|
|
218
|
+
```
|
|
219
|
+
- **General rule: every grep/awk example shown in an instruction or template must itself obey the line-start pattern** (TOOL-009) — the executing side copies examples verbatim, so an example that uses a whole-file match propagates the same misjudgment to everyone who copies it. This file has already corrected its own sentinel self-check command under this rule.
|
|
220
|
+
`.specpro/scripts/bash/verify-ledger.sh` reports the resulting inconsistency as a count mismatch — but only if it is run, and by then the entry is already missing.
|
|
221
|
+
- **Entry placement**: append new entries to the end of their own section, never to the end of the file. The file's statistics block sits at the top precisely so that "append to the end" lands inside the last section rather than between sections; moving or duplicating a section header breaks that and produces an orphaned section no `--review-issues` run will read.
|
|
222
|
+
- **Verify mechanically after writing**: run `.specpro/scripts/bash/verify-ledger.sh` — it checks entry section membership, statistics-vs-actual counts, and the trailing newline in one pass (non-zero exit names the violation). Marking issues `[x]` changes the counts, so this applies to this command too, not only to commands that append. A pre-commit hook enforces the same check.
|
|
223
|
+
- Count: [plan] issues processed, remaining
|
|
224
|
+
|
|
225
|
+
**e. Display completion summary**:
|
|
226
|
+
```markdown
|
|
227
|
+
✅ Completed [plan] issues review
|
|
228
|
+
|
|
229
|
+
Processed: N issues
|
|
230
|
+
Updated: specs/plan.md
|
|
231
|
+
Marked as [x] in implement_issues.md
|
|
232
|
+
|
|
233
|
+
⚠️ IMPORTANT: Next steps
|
|
234
|
+
|
|
235
|
+
1. Run /specpro-tasks to regenerate task list
|
|
236
|
+
2. Then you can process [tasks] issues
|
|
237
|
+
|
|
238
|
+
Do NOT process [tasks] issues yet.
|
|
239
|
+
They require the tasks update first.
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### **Step 1: Setup & Pre-flight Validation** ✨ ENHANCED
|
|
243
|
+
|
|
244
|
+
**1.1 Run setup script**:
|
|
245
|
+
```bash
|
|
246
|
+
.specpro/scripts/bash/setup-plan.sh --json
|
|
247
|
+
```
|
|
248
|
+
Parse JSON output to extract:
|
|
249
|
+
- `FEATURE_SPEC`: Path to specs/spec.md
|
|
250
|
+
- `IMPL_PLAN`: Path to specs/plan.md
|
|
251
|
+
- `SPECS_DIR`: Path to specs/ directory
|
|
252
|
+
|
|
253
|
+
**Progress**: 📋 [1/8] Setting up plan environment...
|
|
254
|
+
|
|
255
|
+
**1.5 Pre-flight Validation** ✨ NEW (FAIL FAST):
|
|
256
|
+
|
|
257
|
+
**Purpose**: Validate environment before executing expensive operations
|
|
258
|
+
|
|
259
|
+
**a. Required files check**:
|
|
260
|
+
```markdown
|
|
261
|
+
Check these files exist:
|
|
262
|
+
- ✅ $FEATURE_SPEC (specs/spec.md)
|
|
263
|
+
- ✅ $IMPL_PLAN_TEMPLATE (.specpro/templates/plan-template.md)
|
|
264
|
+
- ✅ $IMPL_PLAN_OVERVIEW_TEMPLATE (.specpro/templates/plan-overview-template.md)
|
|
265
|
+
- ✅ $CONSTITUTION (specs/constitution.md)
|
|
266
|
+
|
|
267
|
+
If any missing:
|
|
268
|
+
❌ ERROR: Required file missing: $file
|
|
269
|
+
Fix: Run /specpro-specify or check installation
|
|
270
|
+
EXIT 1
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
**b. Directory permissions check**:
|
|
274
|
+
```markdown
|
|
275
|
+
Check writable directories:
|
|
276
|
+
- ✅ $SPECS_DIR (specs/) is writable
|
|
277
|
+
- ✅ $CONTRACTS_DIR (specs/contracts/) can be created
|
|
278
|
+
|
|
279
|
+
If not writable:
|
|
280
|
+
❌ ERROR: No write permission to $directory
|
|
281
|
+
Fix: chmod +w $directory or run with appropriate permissions
|
|
282
|
+
EXIT 1
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
**c. Bash scripts executable check**:
|
|
286
|
+
```markdown
|
|
287
|
+
Check scripts are executable:
|
|
288
|
+
- ✅ setup-plan.sh
|
|
289
|
+
|
|
290
|
+
If not executable:
|
|
291
|
+
⚠️ WARNING: Script not executable, attempting to fix...
|
|
292
|
+
chmod +x $script
|
|
293
|
+
```
|
|
294
|
+
|
|
295
|
+
**d. Quality gate: requirements.md validation** 🆕 [ENFORCED - AUTO-REPAIR]:
|
|
296
|
+
```markdown
|
|
297
|
+
Check specs/checklists/requirements.md:
|
|
298
|
+
- ✅ File exists
|
|
299
|
+
- ✅ Every item marked `[x]` (passed) ← ⚠️ **不在此处印条数**(`T238` / `T229` ③):条数的真源是 `requirements-template.md` 的 `**Total Items**` 与清单自身,**在这里重述一个数字即制造第二个来源** —— 它已经漂过一次(此处曾印 `12`,而真值早已不是)。要看条数,去读清单自己的那份字段。
|
|
300
|
+
|
|
301
|
+
⚠️ CRITICAL: This is a mandatory quality gate - QC execution is enforced automatically
|
|
302
|
+
|
|
303
|
+
Check file exists:
|
|
304
|
+
if [[ ! -f "$SPECS_DIR/checklists/requirements.md" ]]; then
|
|
305
|
+
❌ AUTO-REPAIR TRIGGERED: Missing requirements.md
|
|
306
|
+
|
|
307
|
+
Problem: Spec quality validation not completed.
|
|
308
|
+
Required: specs/checklists/requirements.md (all items marked [x])
|
|
309
|
+
Current: File not found
|
|
310
|
+
|
|
311
|
+
Action: Auto-running QC to generate requirements.md...
|
|
312
|
+
```
|
|
313
|
+
# Auto-run QC to fix missing requirements.md
|
|
314
|
+
echo ""
|
|
315
|
+
echo "🔄 AUTO-REPAIR: Running QC to generate requirements.md..."
|
|
316
|
+
/specpro-qc --scope="full"
|
|
317
|
+
# ⚠️ **No `--auto` here, and this is a decision, not an omission** (`T203` / `ISS-163`):
|
|
318
|
+
# this command's `writes:` unit for `spec.md` is its **Lifecycle fields**, so a
|
|
319
|
+
# repair of the FR PROSE is outside its write face — and delegating the repair to
|
|
320
|
+
# `/specpro-qc` does not widen it (it only moves the violation one level up, where
|
|
321
|
+
# it is harder to see). The checklist below is still produced: that happens on
|
|
322
|
+
# EVERY qc run, independently of any flag. ⇒ **Every qc call in this file is
|
|
323
|
+
# flag-less for this reason — and so is every other caller's** (`T136`): the
|
|
324
|
+
# `--fix-owner` parameter used to name the artifact whose owner was authorised to
|
|
325
|
+
# repair it, and `FR-058` removed the repair path itself ⇒ there is no such
|
|
326
|
+
# parameter to pass and **no caller that passes one**. ⚠️ **Do not restore the old
|
|
327
|
+
# wording**: an authorisation parameter whose subject no longer exists still reads
|
|
328
|
+
# as a live interface, so a reader who greps for it finds it here — and only here.
|
|
329
|
+
|
|
330
|
+
# Verify QC succeeded
|
|
331
|
+
if [[ ! -f "$SPECS_DIR/checklists/requirements.md" ]]; then
|
|
332
|
+
echo ""
|
|
333
|
+
echo "❌ AUTO-REPAIR FAILED: QC could not generate requirements.md"
|
|
334
|
+
echo " This indicates the spec may have critical quality issues."
|
|
335
|
+
echo " Please run /specpro-qc manually to diagnose issues."
|
|
336
|
+
exit 1
|
|
337
|
+
fi
|
|
338
|
+
|
|
339
|
+
echo "✓ AUTO-REPAIR COMPLETE: requirements.md generated"
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
Check all items passed:
|
|
343
|
+
# 完成度按「Status 取值」判定,不按复选框——模板即 `- [ ] **Status**: …`,
|
|
344
|
+
# 「诚实跳过」与「未做」在复选框上完全同形(工具缺陷 #10)
|
|
345
|
+
QC_UNRESOLVED=$(grep -E '^- \[[ x]\] \*\*Status\*\*:' "$SPECS_DIR/checklists/requirements.md" 2>/dev/null \
|
|
346
|
+
| grep -vE '\*\*Status\*\*:[[:space:]]*(x|⊘[[:space:]]*Skipped)[[:space:]]*$' || true)
|
|
347
|
+
if [ -n "$QC_UNRESOLVED" ]; then
|
|
348
|
+
❌ AUTO-REPAIR TRIGGERED: Incomplete requirements.md
|
|
349
|
+
|
|
350
|
+
Problem: Spec quality validation not completed.
|
|
351
|
+
Required: specs/checklists/requirements.md (all items marked [x])
|
|
352
|
+
Current: Some items are still unchecked [ ]
|
|
353
|
+
|
|
354
|
+
Action: Auto-running QC to fix issues...
|
|
355
|
+
```
|
|
356
|
+
# Auto-run QC to fix unchecked items
|
|
357
|
+
echo ""
|
|
358
|
+
echo "🔄 AUTO-REPAIR: Running QC to fix unchecked items..."
|
|
359
|
+
/specpro-qc --scope="incremental"
|
|
360
|
+
|
|
361
|
+
# Verify QC succeeded
|
|
362
|
+
# 完成度按「Status 取值」判定,不按复选框——模板即 `- [ ] **Status**: …`,
|
|
363
|
+
# 「诚实跳过」与「未做」在复选框上完全同形(工具缺陷 #10)
|
|
364
|
+
QC_UNRESOLVED=$(grep -E '^- \[[ x]\] \*\*Status\*\*:' "$SPECS_DIR/checklists/requirements.md" 2>/dev/null \
|
|
365
|
+
| grep -vE '\*\*Status\*\*:[[:space:]]*(x|⊘[[:space:]]*Skipped)[[:space:]]*$' || true)
|
|
366
|
+
if [ -n "$QC_UNRESOLVED" ]; then
|
|
367
|
+
echo ""
|
|
368
|
+
echo "❌ AUTO-REPAIR FAILED: QC could not resolve all issues"
|
|
369
|
+
echo " Check specs/checklists/requirements.md for details."
|
|
370
|
+
echo " Please run /specpro-qc manually to diagnose issues."
|
|
371
|
+
exit 1
|
|
372
|
+
fi
|
|
373
|
+
|
|
374
|
+
echo "✓ AUTO-REPAIR COMPLETE: All items now marked [x]"
|
|
375
|
+
```
|
|
376
|
+
|
|
377
|
+
✓ Quality validation passed
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
**e. Spec.md format validation**:
|
|
381
|
+
```markdown
|
|
382
|
+
Check spec.md has Lifecycle fields:
|
|
383
|
+
- ✅ Contains "**Lifecycle**:" markers
|
|
384
|
+
|
|
385
|
+
If missing:
|
|
386
|
+
⚠️ WARNING: spec.md missing Lifecycle fields
|
|
387
|
+
This may cause incremental processing to fail
|
|
388
|
+
Recommendation: Run /specpro-specify to add Lifecycle tracking
|
|
389
|
+
|
|
390
|
+
Your choice:
|
|
391
|
+
1. Continue anyway (may encounter issues)
|
|
392
|
+
2. Exit and fix Lifecycle fields first
|
|
393
|
+
|
|
394
|
+
Your choice (1/2):
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
**All checks passed**: ✓ Continue to Step 2
|
|
398
|
+
**Any check failed**: ❌ STOP with clear error message
|
|
399
|
+
|
|
400
|
+
---
|
|
401
|
+
|
|
402
|
+
### **Step 2: Load Context**
|
|
403
|
+
|
|
404
|
+
**Progress**: 📋 [2/8] Loading context files...
|
|
405
|
+
|
|
406
|
+
Load required files:
|
|
407
|
+
- Read `FEATURE_SPEC` (specs/spec.md)
|
|
408
|
+
- Read `specs/constitution.md`
|
|
409
|
+
- Load `IMPL_PLAN` template (already copied by setup script)
|
|
410
|
+
|
|
411
|
+
**b. Extract Acceptance Scenarios from spec.md** 🆕:
|
|
412
|
+
- For each User Story in spec.md, extract:
|
|
413
|
+
* **Independent Test** (verbatim copy - preserve exact wording)
|
|
414
|
+
* **Acceptance Scenarios** (all Given-When-Then scenarios)
|
|
415
|
+
* **Categorize scenarios by type**:
|
|
416
|
+
- Happy Path (1-2 scenarios): Core success case
|
|
417
|
+
- Error Scenarios (2-3 scenarios): Error handling and recovery
|
|
418
|
+
- Edge Cases (1-2 scenarios): Boundary conditions, constraints
|
|
419
|
+
- Permission Scenarios (1-2 scenarios): Access control, authentication
|
|
420
|
+
- **Count and validate scenarios**:
|
|
421
|
+
* Each story should have 5-9 scenarios (warn if outside range)
|
|
422
|
+
* All 4 types should be represented (warn if missing type)
|
|
423
|
+
- **Generate scenario labels**: S1, S2, S3... for each scenario in story order
|
|
424
|
+
- **Report scenario statistics**:
|
|
425
|
+
* Total scenarios per story
|
|
426
|
+
* Breakdown by type (Happy, Error, Edge, Permission)
|
|
427
|
+
* Validation warnings if applicable
|
|
428
|
+
|
|
429
|
+
**Validation**: All files loaded successfully, Acceptance Scenarios extracted
|
|
430
|
+
|
|
431
|
+
---
|
|
432
|
+
|
|
433
|
+
### **Step 3: Quality Gates**
|
|
434
|
+
|
|
435
|
+
**Progress**: 📋 [3/8] Checking quality gates...
|
|
436
|
+
|
|
437
|
+
#### **3.0 Clarifications Quality Gate**
|
|
438
|
+
|
|
439
|
+
**a. Check if clarifications.md exists**:
|
|
440
|
+
- Read `specs/clarifications.md`
|
|
441
|
+
- If file doesn't exist:
|
|
442
|
+
```markdown
|
|
443
|
+
⚠️ No clarifications.md found. Running /specpro-clarify --scan...
|
|
444
|
+
```
|
|
445
|
+
- Automatically invoke: `/specpro-clarify --scan`
|
|
446
|
+
- After scan completes, re-check clarifications.md
|
|
447
|
+
|
|
448
|
+
**b. Parse clarifications.md**:
|
|
449
|
+
- Extract all clarification items
|
|
450
|
+
- Count by category and status:
|
|
451
|
+
* [Must Clarify] with `[ ]` (unresolved)
|
|
452
|
+
* [Must Clarify] with `[x]` (resolved)
|
|
453
|
+
* [Must Clarify] with `[inferred]` (auto-inferred)
|
|
454
|
+
* [Suggested Clarify] (any status)
|
|
455
|
+
* [Can Infer] (any status)
|
|
456
|
+
|
|
457
|
+
**c. Quality gate enforcement**:
|
|
458
|
+
- **If ANY [Must Clarify] items are unresolved**:
|
|
459
|
+
```markdown
|
|
460
|
+
⛔ PLAN BLOCKED: Unresolved [Must Clarify] items
|
|
461
|
+
|
|
462
|
+
The following [Must Clarify] items must be resolved:
|
|
463
|
+
- Q[XXX]: [Question summary]
|
|
464
|
+
- Q[YYY]: [Question summary]
|
|
465
|
+
|
|
466
|
+
Total: N unresolved items
|
|
467
|
+
|
|
468
|
+
Auto-invoking /specpro-clarify...
|
|
469
|
+
```
|
|
470
|
+
- Automatically invoke: `/specpro-clarify` (interactive mode)
|
|
471
|
+
- After clarification completes, re-check clarifications.md
|
|
472
|
+
- **MAX 3 ATTEMPTS** (new safeguard):
|
|
473
|
+
* After 3rd failed clarification attempt, require manual intervention
|
|
474
|
+
* Display: "⚠️ Maximum clarification attempts reached. Please manually resolve items in specs/clarifications.md and re-run /specpro-plan"
|
|
475
|
+
|
|
476
|
+
- **If ALL [Must Clarify] items are resolved**:
|
|
477
|
+
```markdown
|
|
478
|
+
✓ Clarification quality gate passed
|
|
479
|
+
|
|
480
|
+
**Clarifications Status**:
|
|
481
|
+
- [Must Clarify]: N/M resolved (✓ all required items)
|
|
482
|
+
- [Suggested Clarify]: X/Y resolved or inferred
|
|
483
|
+
- [Can Infer]: P/Q resolved or inferred
|
|
484
|
+
|
|
485
|
+
Proceeding with planning...
|
|
486
|
+
```
|
|
487
|
+
- Continue to Step 3.5
|
|
488
|
+
|
|
489
|
+
**d. Optional auto-inference prompt** (if non-Must items remain):
|
|
490
|
+
```markdown
|
|
491
|
+
Some [Suggested Clarify] or [Can Infer] items remain unresolved.
|
|
492
|
+
Auto-infer these now? (yes/no)
|
|
493
|
+
```
|
|
494
|
+
- If yes: Process all remaining items using auto-inference
|
|
495
|
+
- If no: Proceed to planning (these items are optional)
|
|
496
|
+
|
|
497
|
+
#### **3.5 Quality Validation Status** ✨ ENHANCED
|
|
498
|
+
|
|
499
|
+
**Purpose**: Load and display quality checklist status, load recommendations into planning context
|
|
500
|
+
|
|
501
|
+
**Progress**: 📋 [3.5/8] Checking quality validation status...
|
|
502
|
+
|
|
503
|
+
**a. Check if checklists/requirements.md exists** 🆕 [ENFORCED - AUTO-REPAIR]:
|
|
504
|
+
- Read `specs/checklists/requirements.md`
|
|
505
|
+
- If file doesn't exist:
|
|
506
|
+
```markdown
|
|
507
|
+
❌ AUTO-REPAIR TRIGGERED: Missing requirements.md
|
|
508
|
+
|
|
509
|
+
Problem: Quality validation not completed before planning.
|
|
510
|
+
Required: specs/checklists/requirements.md (quality validation artifact)
|
|
511
|
+
Current: File not found
|
|
512
|
+
|
|
513
|
+
Action: Auto-running QC to generate requirements.md...
|
|
514
|
+
```
|
|
515
|
+
# Auto-run QC to fix missing requirements.md
|
|
516
|
+
echo ""
|
|
517
|
+
echo "🔄 AUTO-REPAIR: Running QC to generate requirements.md..."
|
|
518
|
+
/specpro-qc --scope="full"
|
|
519
|
+
|
|
520
|
+
# Verify QC succeeded
|
|
521
|
+
if [[ ! -f "$SPECS_DIR/checklists/requirements.md" ]]; then
|
|
522
|
+
echo ""
|
|
523
|
+
echo "❌ AUTO-REPAIR FAILED: QC could not generate requirements.md"
|
|
524
|
+
echo " Planning is BLOCKED without quality validation."
|
|
525
|
+
echo " Please run /specpro-qc manually to diagnose issues."
|
|
526
|
+
exit 1
|
|
527
|
+
fi
|
|
528
|
+
|
|
529
|
+
echo "✓ AUTO-REPAIR COMPLETE: requirements.md generated, proceeding with planning..."
|
|
530
|
+
```
|
|
531
|
+
- Continue to Step 4 (quality validation complete)
|
|
532
|
+
|
|
533
|
+
**b. Parse checklist for validation results**:
|
|
534
|
+
- Read the checklist's **own** fields — verbatim, and only these:
|
|
535
|
+
* `**Status**`: `PASS` | `BLOCK` — the producer sets `PASS` ⟺ `**Failed**` == 0
|
|
536
|
+
* `**Total Items**` · `**Passed**` · `**Failed**`
|
|
537
|
+
* per-item rows: `- [ ] **Status**: x | ⊘ Skipped | ✗ Failed`
|
|
538
|
+
- ⚠️ Do **not** look for `Overall Quality`, a `N/M` score, or a warning tier:
|
|
539
|
+
`templates/requirements-template.md` emits none of them ⇒ a reader keyed on
|
|
540
|
+
them finds nothing on **every** checklist and reports "no warnings", which is
|
|
541
|
+
indistinguishable from a clean pass.
|
|
542
|
+
- The blocking set = the rows whose per-item value is `✗ Failed`.
|
|
543
|
+
- The `⊘ Skipped` rows are **non-blocking**: the template's rule is that an honest
|
|
544
|
+
skip is a conclusion, not a debt. Surface them; never gate on them.
|
|
545
|
+
|
|
546
|
+
**c. Display quality status summary** (fields verbatim from the checklist):
|
|
547
|
+
```markdown
|
|
548
|
+
## Quality Validation Status
|
|
549
|
+
|
|
550
|
+
**Status**: PASS | BLOCK
|
|
551
|
+
**Passed**: 22 / 25
|
|
552
|
+
|
|
553
|
+
**Blocking (✗ Failed)**:
|
|
554
|
+
- "Protocol implementation test-first"
|
|
555
|
+
- Constitution Article IV requires >90% test coverage
|
|
556
|
+
- But FR-xxx~FR-yyy (the wire-protocol requirements) do not specify testing requirements
|
|
557
|
+
|
|
558
|
+
**Skipped (⊘)** — non-blocking; listed so the skips stay visible:
|
|
559
|
+
- "Edge cases not identified"
|
|
560
|
+
- "Assumptions not converted to FRs"
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
**d. Handle blocking issues**:
|
|
564
|
+
- **If `**Status**: BLOCK`** (any `✗ Failed` row):
|
|
565
|
+
```markdown
|
|
566
|
+
**Blocking Issues Detected** (N issues)
|
|
567
|
+
|
|
568
|
+
Fix issues before planning, or proceed despite issues? (fix/proceed)
|
|
569
|
+
```
|
|
570
|
+
- If fix: Wait for user to update spec.md, then re-run validation
|
|
571
|
+
- If proceed: Mark as ⚠️ "Proceeding despite blocking issues" and continue
|
|
572
|
+
|
|
573
|
+
- **If `**Status**: PASS`**: display the summary from **c** — including the
|
|
574
|
+
`⊘ Skipped` rows — and continue. ⚠️ A `⊘ Skipped` row does **not** open the
|
|
575
|
+
"proceed despite" prompt above: an honest skip needs no risk acknowledgment.
|
|
576
|
+
|
|
577
|
+
**e. Load recommendations into planning context**:
|
|
578
|
+
- Extract all recommendations from checklist
|
|
579
|
+
- Categorize by priority (High/Medium/Low)
|
|
580
|
+
- Store for use in Phase 0 (Research) and Phase 1 (Design)
|
|
581
|
+
- Examples:
|
|
582
|
+
* "High Priority: Add test coverage requirement for the wire-protocol module (Constitution)"
|
|
583
|
+
* "Medium Priority: Add 4K streaming performance edge cases"
|
|
584
|
+
* "Medium Priority: Explicitly state LAN latency assumption in FR-xxx"
|
|
585
|
+
|
|
586
|
+
---
|
|
587
|
+
|
|
588
|
+
### **Step 4: Load Lifecycle Status (One-Time Cache)** ✨ OPTIMIZED
|
|
589
|
+
|
|
590
|
+
**Purpose**: Create lifecycle_cache ONCE, avoid redundant spec.md reads
|
|
591
|
+
|
|
592
|
+
**Progress**: 📋 [4/8] Loading Lifecycle status...
|
|
593
|
+
|
|
594
|
+
**4.a Parse ALL Lifecycle fields from spec.md** (ONE TIME READ):
|
|
595
|
+
```markdown
|
|
596
|
+
Load FEATURE_SPEC and extract ALL items with Lifecycle fields:
|
|
597
|
+
- User Stories: ID, Title, Priority, Lifecycle: [specify:<status>][plan:<status>][tasks:<status>]
|
|
598
|
+
- Functional Requirements: ID, Title, Lifecycle: [specify:<status>][plan:<status>][tasks:<status>]
|
|
599
|
+
|
|
600
|
+
Status values: create, update, delete, processed, deprecated
|
|
601
|
+
Example: **Lifecycle**: [specify:create][plan:processed][tasks:processed]
|
|
602
|
+
|
|
603
|
+
Create lifecycle_cache object:
|
|
604
|
+
```
|
|
605
|
+
|
|
606
|
+
**4.b Create lifecycle_cache**:
|
|
607
|
+
```javascript
|
|
608
|
+
lifecycle_cache = {
|
|
609
|
+
version: "1.0",
|
|
610
|
+
generated_at: "YYYY-MM-DD HH:MM:SS",
|
|
611
|
+
statistics: {
|
|
612
|
+
total_items: 0,
|
|
613
|
+
new_items: 0, // planStatus = "create"
|
|
614
|
+
modified_items: 0, // planStatus = "update"
|
|
615
|
+
deprecated_items: 0, // planStatus = "deprecated"
|
|
616
|
+
completed_items: 0 // planStatus = "processed"
|
|
617
|
+
},
|
|
618
|
+
items: [
|
|
619
|
+
{
|
|
620
|
+
id: "FR-xxx",
|
|
621
|
+
type: "FR",
|
|
622
|
+
title: "Plugin API",
|
|
623
|
+
specStatus: "create",
|
|
624
|
+
planStatus: "processed", // Already planned
|
|
625
|
+
tasksStatus: "processed" // Already task-broken
|
|
626
|
+
},
|
|
627
|
+
{
|
|
628
|
+
id: "FR-xxx",
|
|
629
|
+
type: "FR",
|
|
630
|
+
title: "Connection Manager",
|
|
631
|
+
specStatus: "create",
|
|
632
|
+
planStatus: "create", // ← NEW, needs planning
|
|
633
|
+
tasksStatus: "create" // ← NEW, needs task breakdown
|
|
634
|
+
},
|
|
635
|
+
// ... all items
|
|
636
|
+
],
|
|
637
|
+
|
|
638
|
+
// Helper methods
|
|
639
|
+
byPlanStatus: function(status) {
|
|
640
|
+
return this.items.filter(item => item.planStatus === status);
|
|
641
|
+
},
|
|
642
|
+
|
|
643
|
+
bySpecStatus: function(status) {
|
|
644
|
+
return this.items.filter(item => item.specStatus === status);
|
|
645
|
+
},
|
|
646
|
+
|
|
647
|
+
needsProcessing: function() {
|
|
648
|
+
// Items needing planning: planStatus != "processed" && planStatus != "deprecated"
|
|
649
|
+
return this.items.filter(item =>
|
|
650
|
+
item.planStatus !== "processed" && item.planStatus !== "deprecated"
|
|
651
|
+
);
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
```
|
|
655
|
+
|
|
656
|
+
**4.c Categorize items by PlanStatus**:
|
|
657
|
+
```markdown
|
|
658
|
+
Processing categories:
|
|
659
|
+
- New items: N (planStatus = "create") → NEED planning
|
|
660
|
+
- Modified items: M (planStatus = "update") → NEED re-planning
|
|
661
|
+
- Deprecated items: Z (planStatus = "deprecated") → NEED cleanup
|
|
662
|
+
- Skipping: K (planStatus = "processed") → PRESERVE [x]
|
|
663
|
+
```
|
|
664
|
+
|
|
665
|
+
**4.d Report processing statistics**:
|
|
666
|
+
```markdown
|
|
667
|
+
## Lifecycle Processing Summary
|
|
668
|
+
|
|
669
|
+
**Total Items**: N
|
|
670
|
+
- **New items**: X (need planning, PlanStatus empty)
|
|
671
|
+
- **Modified items**: Y (need re-planning, PlanStatus Modified)
|
|
672
|
+
- **Deprecated items**: Z (need cleanup, PlanStatus Deprecated)
|
|
673
|
+
- **Skipping**: M (already Processed, will mark as [x])
|
|
674
|
+
|
|
675
|
+
Processing X+Y items, preserving M items, removing Z items...
|
|
676
|
+
```
|
|
677
|
+
|
|
678
|
+
**4.e Filter items for workflow**:
|
|
679
|
+
- Create `filtered_items` list containing only:
|
|
680
|
+
* Items where PlanStatus != "Processed"
|
|
681
|
+
* These are the ONLY items to include in plan generation
|
|
682
|
+
- Items with PlanStatus = "Processed" are:
|
|
683
|
+
* Marked as [x] in plan.md
|
|
684
|
+
* Excluded from design generation
|
|
685
|
+
* Preserved for reference
|
|
686
|
+
|
|
687
|
+
**KEY OPTIMIZATION**: All subsequent steps (5-7) MUST use `lifecycle_cache`, NOT re-read spec.md
|
|
688
|
+
|
|
689
|
+
---
|
|
690
|
+
|
|
691
|
+
### **Step 5: Generate Plan.md** (Using lifecycle_cache)
|
|
692
|
+
|
|
693
|
+
**Progress**: 📋 [5/8] Generating plan.md sections...
|
|
694
|
+
|
|
695
|
+
**5.0 Load Lifecycle Status from Cache** ✨ OPTIMIZED:
|
|
696
|
+
```markdown
|
|
697
|
+
**DO NOT re-read spec.md** - Use lifecycle_cache from Step 4
|
|
698
|
+
|
|
699
|
+
a. Create completion status map:
|
|
700
|
+
- Load from lifecycle_cache.items
|
|
701
|
+
- Map: itemId → { planStatus, specStatus, tasksStatus }
|
|
702
|
+
|
|
703
|
+
b. ⚠️ **[x]/[ ] 标记规则只适用于 §5.x 那批 Part I 小节 —— 不适用于 Part II**(T171 修正):
|
|
704
|
+
本节此前给出「Mark as [x] / Mark as [ ]」的规则,并在 `c` 里要求把它用到 **Implementation Plan
|
|
705
|
+
阶段**上;而 **§5.6 明令该章节不得出现复选框**(`**No checkboxes. No ✅/⚠️/❌. No "status" column.**`
|
|
706
|
+
· `**Validation**: … no checkbox syntax`)——**同一份文档里,一处指示写、另一处禁止写**。
|
|
707
|
+
⇒ **§5.6 是后出的裁决,本节服从它**:那里的进度由 `lifecycle_cache` 在**生成时**决定
|
|
708
|
+
(FR 是 `create`/`update` 就重跑,`processed` 就跳过),**不落成复选框**。
|
|
709
|
+
⇒ Part I 小节的 `- [x]` 标记照旧(那些是机器读的交付物清单,`tasks` 按它取件)。
|
|
710
|
+
|
|
711
|
+
Example:
|
|
712
|
+
```markdown
|
|
713
|
+
#### Phase 2: Core Infrastructure
|
|
714
|
+
**Deliverables**:
|
|
715
|
+
- [x] PluginManager (FR-xxx) ← planStatus = "processed"
|
|
716
|
+
- [x] ProtocolHandler (FR-xxx) ← planStatus = "processed"
|
|
717
|
+
- [ ] ConnectionManager (FR-xxx) ← planStatus = "create" (new)
|
|
718
|
+
```
|
|
719
|
+
```
|
|
720
|
+
|
|
721
|
+
**Validation**: lifecycle_cache loaded successfully, map created
|
|
722
|
+
|
|
723
|
+
### **Part assignment and two standing rules** ⚠️ [read before generating any §5.x section]
|
|
724
|
+
|
|
725
|
+
**Part assignment — TWO FILES, not two halves of one file** (settled 2026-09-13). Each §5.x step below carries a marker saying **which file it writes**:
|
|
726
|
+
|
|
727
|
+
| Marker | File | Template | Standing |
|
|
728
|
+
|--------|------|----------|----------|
|
|
729
|
+
| 🅼 **[Machine-Read]** | **`specs/plan.md`** | `.specpro/templates/plan-template.md` | Consumed by downstream commands, which extract **by section**. MUST be mechanically parseable. No checkboxes, no status, no decision narrative. |
|
|
730
|
+
| 🅷 **[Human-Read]** | **`specs/plan-overview.md`** | `.specpro/templates/plan-overview-template.md` | For people; *sufficient useful information is enough.* **No command reads it** — and **no command may reference its section names**. |
|
|
731
|
+
|
|
732
|
+
**Why two files rather than one file with two halves.** The rule "implement never reads the human half" would otherwise be a *convention* that holds only as long as every reader extracts by section. A reader that loads a whole file would silently pull the human half into a task's context, and nothing would report it. Separate files make it **structural**: the human half is not in the file being read. This follows the boundary-declaration discipline: *a constraint with no enforcement point is a statement, not a constraint.*
|
|
733
|
+
|
|
734
|
+
> **Cross-file references are one-way.** `plan.md` MUST NOT reference `plan-overview.md` section names either — a machine-read artifact that points at a human-read one reintroduces the coupling the split removes. Pointing at the *file* by path is fine (the reader can choose to open it); pointing at a *section* is not.
|
|
735
|
+
|
|
736
|
+
> **The generation order of the §5.x steps is NOT the file order.** All §5.x steps run before Phase 0 (they "write the document"), and Step 6.5 backfills afterwards. The **file order is the template's** — Part I sections first, then Part II. Do not reorder the file to match the steps.
|
|
737
|
+
|
|
738
|
+
**Standing rule 0 — every section declares its purpose and consumers** (settled 2026-09-13).
|
|
739
|
+
|
|
740
|
+
**Every `##` and `###` section MUST open with a one-line `*Purpose · Consumers*` note.** Write it before the content, from the template's own line for that section — do not leave it blank, and do not write a vague one.
|
|
741
|
+
|
|
742
|
+
Three requirements on that line:
|
|
743
|
+
1. **Name the consumers concretely** — the command and the step that reads it (`tasks` §4.j-2), not "downstream" or "the workflow".
|
|
744
|
+
2. **Say what is done with it** — extracted for task generation? used as an acceptance threshold? a grounding reference? A consumer named without a use is not a declaration.
|
|
745
|
+
3. **If no machine consumer exists, say so plainly** — and then ask whether the section belongs in Part I at all. **A section in Part I with no machine consumer is a Part-assignment error** (see below), not a labelling problem.
|
|
746
|
+
|
|
747
|
+
⚠️ **Cover sub-sections too, not just top-level sections.** The failure this rule prevents: top-level sections get the line, sub-sections do not — and the sub-sections are exactly what the per-subsection extractions (`§4.i-1..i-4`, `§4.j-1..j-3`) read. A reader then cannot tell which sub-section feeds which downstream step.
|
|
748
|
+
|
|
749
|
+
**Standing rule 1 — no upstream-reads-downstream.** This stage MUST NOT read a later stage's artifact to refresh its own content. If a piece of information's source of truth is downstream (test assets, coverage reports, task state), it MUST NOT be written into plan.md at all: this stage has no way to keep it current, so it would freeze at the value it had when written while downstream consumers act on that stale value. Two known instances of this trap: per-phase checkboxes (§5.6b) and the protocol inventory's coverage-status column (§5.4g).
|
|
750
|
+
|
|
751
|
+
**Standing rule 2 — change propagation.** When a **Part I** section changes, the change MUST reach `tasks` — but only through the FR state, because that is the only channel `tasks` reads:
|
|
752
|
+
|
|
753
|
+
- **Record the change**: a technology or architecture change MUST leave a record — as a `[plan]` issue entry in `specs/implement_issues.md` when it was driven by one, or as an entry in `## Complexity Tracking` (§5.7) when it came from a user decision or this stage's own reasoning. **An unrecorded design change is the failure this rule exists to prevent.**
|
|
754
|
+
- **Stay within SDD**: spec.md remains the sole source of requirements. This is not a licence to invent requirements here.
|
|
755
|
+
- **Judge the blast radius yourself — this is deliberately not mechanical.** By change type: a spec item change → that item; a technology swap → the FRs that rely on that technology for their satisfaction (swapping the network library touches the network-transport FRs, not FR text — the FR says "non-blocking async I/O" and does not name a library); a threshold change → the FRs in that threshold's risk band; a new/changed constraint → the constraint's scope; a placement change → the tasks whose paths match the pattern. **A purely editorial or structural change (wording, ordering, de-duplication) changes nothing downstream — issue no signal.**
|
|
756
|
+
- **Update the state**: set `[tasks:update]` on each affected FR/US so `tasks` regenerates their tasks.
|
|
757
|
+
- **If you cannot identify the blast radius**, the change has **no FR anchor** — that is the signal to register it as an issue for the appropriate stage instead of writing it silently.
|
|
758
|
+
|
|
759
|
+
**Why this is a rule and not a mechanism:** a change made here that never reaches `tasks` leaves `tasks.md` built on the old design — and because `tasks` gates on FR state, even a manual re-run will not produce new tasks for it. There is no mechanical detector for "changed but not signalled"; the four steps above are the backstop.
|
|
760
|
+
|
|
761
|
+
---
|
|
762
|
+
|
|
763
|
+
#### **5.1 Generate Summary Section** 🅷 **→ `specs/plan-overview.md`**
|
|
764
|
+
|
|
765
|
+
**Progress**: 📋 [5.1/8] Generating Summary section...
|
|
766
|
+
|
|
767
|
+
Extract from spec.md:
|
|
768
|
+
- Paragraph 1: What is being built (from Overview)
|
|
769
|
+
- Paragraph 2: Technical approach (**from research.md** — see note below)
|
|
770
|
+
- Paragraph 3: Key outcomes (from Overview and quantified FRs)
|
|
771
|
+
|
|
772
|
+
> ⚠️ **Paragraph 2's input does not exist yet when this step runs** (settled 2026-09-13). This section is written in the §5.x block, which runs **before** Phase 0 Research — so on an initial run `research.md` is absent. In initial mode write paragraph 2 from what is available and **mark it for backfill**; **Step 6.5 backfills it** once research.md exists. Leaving it without a backfill leaves a technical-approach paragraph with no source, and nothing detects it afterwards.
|
|
773
|
+
|
|
774
|
+
**Validation**: 2-3 paragraphs, includes "what" and "how"; paragraph 2's source is either research.md (incremental run) or scheduled for Step 6.5 backfill (initial run).
|
|
775
|
+
|
|
776
|
+
#### **5.2 Generate Technical Context Section** 🅼 **→ `specs/plan.md`**
|
|
777
|
+
|
|
778
|
+
**Progress**: 📋 [5.2/8] Generating Technical Context...
|
|
779
|
+
|
|
780
|
+
For each field, use extraction rules:
|
|
781
|
+
|
|
782
|
+
| Field | Extraction Rule | Default if Not Found |
|
|
783
|
+
|-------|----------------|---------------------|
|
|
784
|
+
| **Language/Version** | Check spec.md for "Kotlin", "Python", etc. | NEEDS CLARIFICATION |
|
|
785
|
+
| **Primary Dependencies** | Extract from research.md "Dependencies" | NEEDS CLARIFICATION |
|
|
786
|
+
| **Storage** | Check spec.md for persistence requirements | N/A |
|
|
787
|
+
| **Testing** | Extract from research.md "Testing Framework" | NEEDS CLARIFICATION |
|
|
788
|
+
| **Target Platform** | Extract from spec.md Overview | NEEDS CLARIFICATION |
|
|
789
|
+
| **Project Type** | Infer from Technical Context | single |
|
|
790
|
+
| **Performance Goals** | Extract quantified targets from spec.md FRs (latency / throughput / capacity) | NEEDS CLARIFICATION |
|
|
791
|
+
| **Constraints** | Extract from research.md + Constitution | NEEDS CLARIFICATION |
|
|
792
|
+
| **Scale/Scope** | Extract from spec.md Overview | NEEDS CLARIFICATION |
|
|
793
|
+
|
|
794
|
+
**Validation**: All 9 fields filled (can have NEEDS CLARIFICATION)
|
|
795
|
+
|
|
796
|
+
#### **5.3 Generate Constitution Check Section** 🅷 **→ `specs/plan-overview.md`**
|
|
797
|
+
|
|
798
|
+
**Progress**: 📋 [5.3/8] Generating Constitution Check...
|
|
799
|
+
|
|
800
|
+
**a. Load Constitution**: Read `specs/constitution.md`
|
|
801
|
+
|
|
802
|
+
**b. Identify Applicable Principles**:
|
|
803
|
+
- Use keyword matching from spec.md
|
|
804
|
+
- Example mappings:
|
|
805
|
+
* "network", "connect" → Principle V (Performance & Resource Management)
|
|
806
|
+
* "protocol", "encoding" → Article IV (Risk-Based Quality Assurance)
|
|
807
|
+
* "multiplatform", "Android", "iOS" → Platform-specific principles
|
|
808
|
+
* "security", "encryption" → Security principles
|
|
809
|
+
|
|
810
|
+
**c. For Each Applicable Principle**:
|
|
811
|
+
- Extract requirement text
|
|
812
|
+
- Evaluate compliance against spec.md and plan.md
|
|
813
|
+
- Document status: ✅ PASS or ❌ FAIL
|
|
814
|
+
- If FAIL: Provide justification (requires Complexity Tracking section)
|
|
815
|
+
|
|
816
|
+
**d. Format Output**:
|
|
817
|
+
```markdown
|
|
818
|
+
### ✅ [Principle Name]
|
|
819
|
+
|
|
820
|
+
**Requirement**: [Specific requirement]
|
|
821
|
+
**Status**: PASS | ⚠️ PARTIAL | ❌ FAIL
|
|
822
|
+
|
|
823
|
+
**Compliance**:
|
|
824
|
+
- ✅ [Evidence 1]
|
|
825
|
+
- ✅ [Evidence 2]
|
|
826
|
+
|
|
827
|
+
### Overall Constitution Compliance: ✅ PASS (X/Y principles)
|
|
828
|
+
```
|
|
829
|
+
|
|
830
|
+
**e. State the level explicitly when a gap exists** ⚠️ (settled 2026-09-13): a design can satisfy a principle **at the design level** while an **integration-level** gap remains tracked. Write both levels out — `Overall … PASS (6/6)` alongside a principle marked `⚠️ PARTIAL — component-level PASS, integration gap tracked` is **not** a contradiction *if the qualifier is stated*; without it, the two lines read as contradictory and the reader cannot tell which one is current. Never let a principle's own status and the overall line disagree in silence: if the overall line means "at the design level", say so on that line.
|
|
831
|
+
|
|
832
|
+
**f. FR-level risk enumeration is NOT here** ⚠️ (settled 2026-09-13): the per-FR risk split (`HIGH-RISK: FR-011~024E …` / `MEDIUM-RISK: …` / `LOW-RISK: …`) **belongs in `Quality Targets → Risk Classification` (§5.3.1)**, next to the coverage table it pairs with — because it is a **machine input** (`tasks` §4.j-2 reads it to classify each FR), not a compliance statement. Put it here and it sits in a human-read section that no command extracts.
|
|
833
|
+
|
|
834
|
+
**Validation**: All applicable principles evaluated; overall assessment provided; when any principle is PARTIAL or FAIL, the level qualifier (design-level vs integration-level) is stated on both the principle and the overall line.
|
|
835
|
+
|
|
836
|
+
#### **5.3.1 Generate Quality Targets Section** ✨ NEW 🅼 **→ `specs/plan.md`**
|
|
837
|
+
|
|
838
|
+
**Progress**: 📋 [5.3.1/8] Generating Quality Targets...
|
|
839
|
+
|
|
840
|
+
**Purpose**: Automatically determine project type and set appropriate test coverage targets based on Constitution Article IV principles
|
|
841
|
+
|
|
842
|
+
**a. Infer Project Type** 📋 [CRITICAL]:
|
|
843
|
+
Analyze spec.md and technical context to determine project type:
|
|
844
|
+
|
|
845
|
+
**Decision Logic** (in order of priority):
|
|
846
|
+
|
|
847
|
+
1. **Medical/Life-Critical** (Highest priority):
|
|
848
|
+
- Keywords: "medical", "health", "patient", "clinical", "diagnostic", "FDA", "IEC 62304"
|
|
849
|
+
- Impact: Life-safety or health-critical
|
|
850
|
+
- → Project Type: **Medical Application**
|
|
851
|
+
|
|
852
|
+
2. **Financial/Trading**:
|
|
853
|
+
- Keywords: "financial", "trading", "payment", "banking", "transaction", "SEC", "FINRA", "PCI-DSS"
|
|
854
|
+
- Impact: Direct monetary loss or regulatory compliance
|
|
855
|
+
- → Project Type: **Financial/Trading Application**
|
|
856
|
+
|
|
857
|
+
3. **Platform/Framework**:
|
|
858
|
+
- Keywords: "platform", "framework", "SDK", "library", "API", "plugin", "multi-application"
|
|
859
|
+
- Impact: Multiple applications depend on this codebase
|
|
860
|
+
- → Project Type: **Platform Application**
|
|
861
|
+
|
|
862
|
+
4. **Enterprise/Business**:
|
|
863
|
+
- Keywords: "enterprise", "business", "SaaS", "B2B", "team", "organization", "company"
|
|
864
|
+
- Impact: Business processes depend on this software
|
|
865
|
+
- → Project Type: **Enterprise Application**
|
|
866
|
+
|
|
867
|
+
5. **MVP/Prototype**:
|
|
868
|
+
- Keywords: "MVP", "prototype", "proof of concept", "validate", "experiment", "hackathon"
|
|
869
|
+
- Impact: Early-stage, high rate of change
|
|
870
|
+
- → Project Type: **MVP/Prototype**
|
|
871
|
+
|
|
872
|
+
6. **Personal Application** (Default):
|
|
873
|
+
- Keywords: "personal", "individual", "hobby", "personal productivity"
|
|
874
|
+
- Impact: Single user
|
|
875
|
+
- → Project Type: **Personal Application**
|
|
876
|
+
|
|
877
|
+
**Inference Process**:
|
|
878
|
+
- Check spec.md Overview for keywords
|
|
879
|
+
- Check spec.md quantified FRs for impact statements
|
|
880
|
+
- Check Technical Context for deployment model
|
|
881
|
+
- Default to "Enterprise Application" if unclear
|
|
882
|
+
|
|
883
|
+
**b. Select Coverage Targets** 📋 [CRITICAL]:
|
|
884
|
+
Based on the inferred project type, **copy the coverage targets from the constitution's Quality Assurance Matrix** — ⚠️ **they are NOT listed here** (`T242` / `ISS-215`):
|
|
885
|
+
|
|
886
|
+
- **Read** `specs/constitution.md` → the Quality Assurance Matrix (one row per project type) and take that project type's three targets.
|
|
887
|
+
- **Then classify this project's modules** by risk level (step `c` below) and fill `### Risk-Based Coverage Targets` (plan.md) and `### Risk Classification` with them.
|
|
888
|
+
|
|
889
|
+
⚠️ **This step used to carry its own copy of the matrix**, and the toolchain had **three copies of the same defaults in total** (this one, the plan template's, and the constitution command's matrix). The two plan-side copies agreed with each other and **disagreed with the source in five of six rows** (Platform: 90/70/0 here vs 95/85/50 in the matrix) — a restated default is a source that drifts without reporting, which is why this copy is gone rather than corrected. **Do not paste a table back here**: if the defaults need to change, they change in the matrix.
|
|
890
|
+
|
|
891
|
+
**c. Identify Risk Level Examples** — produce the **`### Risk Classification`** subsection:
|
|
892
|
+
For each risk level, enumerate the **FR ids** (not just module descriptions):
|
|
893
|
+
|
|
894
|
+
| Risk level | Test-First | FR list |
|
|
895
|
+
|------------|-----------|---------|
|
|
896
|
+
| HIGH-RISK | MANDATORY | [FR-xxx, FR-yyy …] |
|
|
897
|
+
| MEDIUM-RISK | RECOMMENDED | [FR-xxx …] |
|
|
898
|
+
| LOW-RISK | OPTIONAL | [FR-xxx …] |
|
|
899
|
+
|
|
900
|
+
- **HIGH-RISK** — protocol implementations (if "protocol"/"encoding" in spec.md) · cryptography/security (if "encryption"/"authentication") · network transport (if "network"/"connection") · critical data operations · financial calculations (if Financial project type)
|
|
901
|
+
- **MEDIUM-RISK** — business logic and orchestration · data models and repositories · platform API bindings (if "multiplatform")
|
|
902
|
+
- **LOW-RISK** — UI components (if "UI"/"frontend") · utilities and helpers · dev tools
|
|
903
|
+
|
|
904
|
+
⚠️ **FR ids are mandatory here** (settled 2026-09-13): `tasks` §4.j-2 reads this table **per FR** to classify each requirement, and §4.j-3 annotates the generated tasks from it. A table of module descriptions with no FR ids cannot be consumed — the reader would have to re-derive the mapping the table was supposed to supply.
|
|
905
|
+
⚠️ **This subsection is where the FR-level risk split lives** — it was previously written into `## Constitution Check` (Part II, human-read) where nothing extracted it. See §5.3f.
|
|
906
|
+
|
|
907
|
+
**d. Format Output**:
|
|
908
|
+
```markdown
|
|
909
|
+
## Quality Targets
|
|
910
|
+
|
|
911
|
+
*PURPOSE: Define project-specific quality standards based on Constitution principles and project type*
|
|
912
|
+
|
|
913
|
+
### Project Type Classification
|
|
914
|
+
|
|
915
|
+
**Project Type**: **[Inferred Type]** [Emoji]
|
|
916
|
+
|
|
917
|
+
**Rationale**:
|
|
918
|
+
- [Why this project type was chosen based on spec.md analysis]
|
|
919
|
+
- [Impact of bugs/failures on users]
|
|
920
|
+
- [Stability and reliability requirements]
|
|
921
|
+
|
|
922
|
+
**Impact on Quality Standards**:
|
|
923
|
+
- [How project type influences coverage targets]
|
|
924
|
+
- [Trade-offs between velocity and quality]
|
|
925
|
+
|
|
926
|
+
### Risk-Based Coverage Targets
|
|
927
|
+
|
|
928
|
+
| Risk Level | Coverage Target | Test Approach | Example Modules |
|
|
929
|
+
|------------|----------------|---------------|-----------------|
|
|
930
|
+
| **HIGH-RISK** | **>XX%** | MANDATORY Test-First | [Examples from spec.md] |
|
|
931
|
+
| **MEDIUM-RISK** | **>YY%** | RECOMMENDED Test-First | [Examples from spec.md] |
|
|
932
|
+
| **LOW-RISK** | **Optional** | Manual testing acceptable | [Examples from spec.md] |
|
|
933
|
+
|
|
934
|
+
### Constitution Compliance
|
|
935
|
+
|
|
936
|
+
**Constitution Reference**: Article IV (Risk-Based Quality Assurance)
|
|
937
|
+
|
|
938
|
+
**Alignment**:
|
|
939
|
+
- ✅ Coverage targets proportional to module risk level
|
|
940
|
+
- ✅ HIGH-RISK modules: Test-First MANDATORY with >XX% coverage
|
|
941
|
+
- ✅ MEDIUM-RISK modules: Test-First RECOMMENDED with >YY% coverage
|
|
942
|
+
- ✅ LOW-RISK modules: Testing OPTIONAL (manual acceptable)
|
|
943
|
+
|
|
944
|
+
### Quality Validation Strategy
|
|
945
|
+
|
|
946
|
+
**Per User Story Phase** (executed by `/specpro-tasks` Step j — unit-test tasks ONLY; integration / component E2E / app E2E are planned separately by `/specpro-test-plan` into specs/test-tasks.md):
|
|
947
|
+
- Generate unit test tasks (`[Quality]` tasks) based on FR risk level (tasks Step j-4)
|
|
948
|
+
- Annotate implementation tasks with risk level and coverage requirement (tasks Step j-3)
|
|
949
|
+
- Add quality checkpoint to verify coverage targets met (tasks Step j-5)
|
|
950
|
+
|
|
951
|
+
**Measurement**:
|
|
952
|
+
- Code coverage measured via [coverage tool based on language]
|
|
953
|
+
- Scenario automation measured via test scenario count (target: 85-90% of scenarios)
|
|
954
|
+
- Both dimensions tracked independently
|
|
955
|
+
|
|
956
|
+
**Quality Gates**:
|
|
957
|
+
- HIGH-RISK FRs must achieve >XX% unit-test coverage before merge
|
|
958
|
+
- MEDIUM-RISK FRs recommended >YY% unit-test coverage before merge
|
|
959
|
+
- All tests must pass — unit tests via tasks.md; contract / integration / E2E via specs/test-tasks.md
|
|
960
|
+
```
|
|
961
|
+
|
|
962
|
+
**e. Language-Specific Coverage Tools**:
|
|
963
|
+
Select coverage tool based on Technical Context:
|
|
964
|
+
- **Kotlin/JVM**: JaCoCo
|
|
965
|
+
- **Kotlin Multiplatform**: JaCoCo (JVM targets) + platform-specific tools
|
|
966
|
+
- **TypeScript/JavaScript**: Istanbul/NYC
|
|
967
|
+
- **Python**: Coverage.py or pytest-cov
|
|
968
|
+
- **Go**: Built-in coverage
|
|
969
|
+
- **Java**: JaCoCo
|
|
970
|
+
- **Rust**: tarpaulin or cargo-llvm-cov
|
|
971
|
+
|
|
972
|
+
**Validation**: Quality Targets section complete with:
|
|
973
|
+
- ✅ Project type inferred from spec.md
|
|
974
|
+
- ✅ Coverage targets selected based on project type
|
|
975
|
+
- ✅ Example modules extracted from spec.md
|
|
976
|
+
- ✅ Constitution compliance documented
|
|
977
|
+
- ✅ Measurement strategy defined
|
|
978
|
+
- ✅ Coverage tool specified
|
|
979
|
+
- ✅ ⚠️ **`### Risk Classification` 的每一档都带 FR ids,且**逐档抽样核对**:抽到的号确实
|
|
980
|
+
出现在 `spec.md`(T171 / audit finding:「plan 要求某表必须有 FR ids,而其自身验证不含该性质」)。
|
|
981
|
+
**判据**:把该表三档里的 FR 号**逐个**与 `spec.md` 的定义对一遍 —— 数"表里有几个号"证明不了
|
|
982
|
+
它们**是**东西;而这张表正是 `tasks` §4.j-2 **逐 FR** 读它来分类的那一张。
|
|
983
|
+
|
|
984
|
+
#### **5.4 Generate Architecture Section** 🅼 **→ `specs/plan.md`** — except (a), which goes to `plan-overview.md` (see below)
|
|
985
|
+
|
|
986
|
+
**Progress**: 📋 [5.4/8] Generating Architecture...
|
|
987
|
+
|
|
988
|
+
> ⚠️ **This section spans both parts** (settled 2026-09-13):
|
|
989
|
+
> - **(a) System Overview → Part II** (human-read). It is the runtime component-stack view.
|
|
990
|
+
> - **(b)–(g) → Part I** (machine-read). They are the source-set ownership view plus the protocol spec, and `tasks` §4.i-1..i-4 extracts from them per subsection.
|
|
991
|
+
>
|
|
992
|
+
> Both views MUST carry a view-semantics line so a reader — human or machine — never has to guess which model a layering claim belongs to.
|
|
993
|
+
|
|
994
|
+
**a. System Overview** 🅷 **→ `specs/plan-overview.md`**:
|
|
995
|
+
- Architecture diagram or text description
|
|
996
|
+
- Major subsystems and relationships
|
|
997
|
+
- Core architecture pattern (e.g., microkernel + plugins)
|
|
998
|
+
- 2-3 sentence summary
|
|
999
|
+
- **MUST state the view semantics**: this view is the **runtime component stack**; the Layered Architecture below is the **source-set ownership** view. They answer different questions and MUST NOT be applied to each other. Without this line a project can end up with a diagram whose layering contradicts the prose — and the prose is what `tasks` §4.i-2 extracts from, so the human reader and the machine would be working from two different layer models.
|
|
1000
|
+
|
|
1001
|
+
**b. Layered Architecture** 🅼 **[Part I · Machine-Read]**:
|
|
1002
|
+
- Define 2-4 major layers
|
|
1003
|
+
- For each layer:
|
|
1004
|
+
* Responsibilities
|
|
1005
|
+
* Contains (specific components)
|
|
1006
|
+
* Constraints (Must/Must not) — **each constraint MUST carry its source anchor** (an FR id, or `Constitution Principle N`). A constraint with no anchor is not grounded: state where it comes from or drop it.
|
|
1007
|
+
|
|
1008
|
+
**c. Component Interaction** 🅼 **[Part I · Machine-Read]**:
|
|
1009
|
+
- How major components interact
|
|
1010
|
+
- Key interaction patterns (e.g., Plugin → Core)
|
|
1011
|
+
- **Coverage criterion — the RELATIONSHIPS must be complete, not the count.** MUST cover at least: plugin↔core · plugin↔plugin · any cross-process or cross-device interaction. Do not treat "one pattern is enough" as satisfied: a constraint that regulates a relationship (e.g. "plugins MUST communicate via the event bus") presupposes that relationship is itself a registered pattern — a constraint over an unregistered pattern is a dangling rule.
|
|
1012
|
+
- Interaction constraints — **each MUST carry its source anchor** (FR id or `Constitution Principle N`), same rule as (b).
|
|
1013
|
+
|
|
1014
|
+
**d. Architecture Patterns** (CRITICAL: Keep concise):
|
|
1015
|
+
- Document 2-5 critical patterns
|
|
1016
|
+
- **NO** detailed Problem/Solution/Trade-offs (those belong in research.md)
|
|
1017
|
+
- For each pattern:
|
|
1018
|
+
* **Description**: Brief description
|
|
1019
|
+
* **Key Points**: What it provides, how it's used
|
|
1020
|
+
* **See**: Reference to research.md section for detailed analysis
|
|
1021
|
+
|
|
1022
|
+
**e. Critical Constraints**:
|
|
1023
|
+
- Define architecture-level constraints
|
|
1024
|
+
- For each: Requirement, Architecture Impact
|
|
1025
|
+
|
|
1026
|
+
**f. Shared/Platform Boundary Declaration** 🌐 [CONDITIONAL — only when the constitution contains a shared-code / multiplatform / core-logic principle]
|
|
1027
|
+
|
|
1028
|
+
**Why this subsection exists**: a layered-architecture description names layers but does not say which concrete source set each layer OWNS. Left unstated, module placement follows whichever directory is nearest at implementation time, and two components with the same role drift into different locations — the layered diagram still looks correct throughout, so nothing detects the drift. The declaration below closes that gap by making the boundary a checkable product, in the same shape as the protocol Activation Gate: state the verdict, make it mechanically reproducible.
|
|
1029
|
+
|
|
1030
|
+
**f.1 Read the constitution principles first.** For every principle that mandates shared code, core logic, a shared protocol, or a cross-platform module, extract:
|
|
1031
|
+
- the **mandated scope** — the categories it says MUST be shared (e.g. business logic, core protocol, data models)
|
|
1032
|
+
- the **excluded scope** — what it says platform layers may contain (e.g. platform bindings, UI rendering, hardware integration)
|
|
1033
|
+
|
|
1034
|
+
**f.2 Emit the declaration table** (one row per principle-scope pair):
|
|
1035
|
+
|
|
1036
|
+
| Planned home | Constitutional basis | Category (protocol / business logic / data model / platform abstraction) | Owning layer | Corpus set — the shared source set mandatory for that layer | Path pattern |
|
|
1037
|
+
|---|---|---|---|---|---|
|
|
1038
|
+
| `XxxProtocol` | Principle \<N\> | protocol | shared | `commonMain` (or the build's equivalent) | `core/src/commonMain/.../protocol/...` |
|
|
1039
|
+
| `XxxBinding` | Principle \<N\> | platform abstraction | platform-specific | platform source sets | `core/src/{platform}Main/...` |
|
|
1040
|
+
|
|
1041
|
+
Two columns carry the weight and MUST NOT be left vague:
|
|
1042
|
+
- **Corpus set** — the *shared* source set the layer is mandatory in, AND the platform source sets that merely *may* extend it. A layer marked shared but landing only in a platform set never reaches the other platforms; the requirement is not "exists somewhere" but "lives in the corpus set".
|
|
1043
|
+
- **Path pattern** — a concrete path, not a name. A scope claimed without a location cannot be audited.
|
|
1044
|
+
|
|
1045
|
+
**f.3 State the dependency boundary the corpus set must honour.** For each shared layer, record what it MUST NOT depend on. Draw these from the architecture's own layers: a protocol layer MUST NOT depend on a transport-layer object (a live socket, connection, or session holder) — a handler that takes one cannot be constructed without a real network, which makes independent testing impossible and forces every verification end-to-end, where timing coupling masquerades as test flakiness.
|
|
1046
|
+
|
|
1047
|
+
**f.4 State the platform-abstraction requirement.** When the shared layer needs a capability the platform provides (compression, image codec, file system, crypto), declare it as an expect/actual pair: the declaration lives in the corpus set, the implementation in each platform set. Listing the capability without its abstraction means the shared layer cannot compile for the other platforms — and the failure surfaces only at build time on a platform the author may not be running.
|
|
1048
|
+
|
|
1049
|
+
**Validation**: the declaration table exists whenever the constitution carries a shared-code principle; every shared code category named in that principle traces to a row; every row has both a corpus set and a path pattern; shared layers that consume platform capabilities have a corresponding expect/actual pair declared. A plan with a multiplatform constitution and no boundary declaration is incomplete — record it as a gap rather than omitting the subsection.
|
|
1050
|
+
|
|
1051
|
+
**g. Protocol Codec Design Artifacts** 🌐 [CONDITIONAL — only when the Activation Gate is ACTIVE or ACTIVE-WITH-GAPS] 🅼 **[Part I · Machine-Read]**:
|
|
1052
|
+
|
|
1053
|
+
**Hosting (settled 2026-09-13)**: these artifacts live **here, under `## Architecture`** — they are design specification, not quality targets. The protocol rules in the seven commands require the design output to contain them but do not name a host section; without one they end up parked wherever space is free (in one project: under `## Quality Targets`, which is semantically wrong and — because that section carried no validation — went unnoticed).
|
|
1054
|
+
|
|
1055
|
+
Produce, per `.specpro/templates/protocol-golden-bytes-guide.md`:
|
|
1056
|
+
- **`**Verdict record (§6.4)**`** — the stage/verdict/trigger/evidence/artifacts table. One row per consuming stage.
|
|
1057
|
+
- **`#### Protocol-Point Inventory` (§1)** — one row per protocol point, granularity to the **branch**; ambiguous semantics recorded as **byte-level examples, never prose**.
|
|
1058
|
+
⚠️ **The last column is `Coverage method`, NOT coverage status.** It states the testing *means* the point requires (matrix cases / property tests / incremental-context cases / environment annotations) — a design specification, fixed when the row is written. Which points are covered *right now* is a **downstream** fact (the actual test assets) and MUST NOT be recorded here: this stage cannot keep it current without reading downstream artifacts, and downstream consumers would act on a stale value. **Anchor reachability** IS recorded here — an unreachable anchor is a **GAP** (§6.3), because only the stage that did the anchoring knows whether the source was reachable.
|
|
1059
|
+
- **`#### Golden-Bytes Strategy` (§2)** — L1→L2→L3 cross-anchoring, each anchor stating its source layer and protocol version.
|
|
1060
|
+
- **`#### Test Matrix` (§3)** — the four-part shape for codec modules: decode matrix · encode reverse matrix · shared golden-bytes fixture · property-test extension. Two requirements carry the weight:
|
|
1061
|
+
- **Error paths are part of the matrix** — truncated stream, invalid control byte, over-long run, out-of-range index: each MUST have a **decided** expected behaviour (reject vs tolerate). "Unspecified" is not an answer.
|
|
1062
|
+
- **Admissibility of a shared fixture anchor** ⚠️: every anchor MUST first pass §2's three-layer check (source layer + protocol version), or be recorded as a GAP (§6.3). **A constructor whose semantics came from the implementation under test MUST NOT be promoted into the shared fixture** — generalising it copies the same misreading into both the encoder and the decoder side, so every assertion passes by construction (§3.1's self-confirming loop). A project that has such a "behaviour-lock" constructor already (built for a pilot matrix) MUST say so here and forbid its promotion.
|
|
1063
|
+
- **`#### Stream-Semantics Comparison` (MANDATORY when one client speaks several encoders)** — continuous single stream vs per-message independent stream. ⚠️ **No single guide section owns this** — the rule is distributed across the guide: continuous-stream segmented verification uses a **reuse-style decode path** (§2), the lateral audit scans sibling functions for the same stream-semantics defect (§4, L1), and a fix's lesson MUST NOT be transferred to another encoder by default because the semantics may be opposite (§7). Cite those, not a non-existent section.
|
|
1064
|
+
|
|
1065
|
+
**g2. Shared-Layer Relocation Design** 🌐 [CONDITIONAL — only when the boundary declaration and the build disagree] 🅼 **[Part I · Machine-Read]**:
|
|
1066
|
+
|
|
1067
|
+
**When**: `f` produced a declaration but an audit (`analyze` Pass M) found the build disagrees — shared-mandated code in a platform-only source set, a handler constructed from a live transport object, a platform dialect imported into a shared file. The declaration states intent; **it does not state how to get from here to there**. No disagreement → omit.
|
|
1068
|
+
|
|
1069
|
+
Produce, under `### Shared-Layer Relocation Design`:
|
|
1070
|
+
- **Design decisions the declaration does not cover** — the dependency shape a shared component MUST NOT take, and the platform abstractions it consumes. Each with its **rejected alternative** (this is where "the handler must not take a live connection" and *why the simpler route was insufficient* belong).
|
|
1071
|
+
- **Migration plan** — ordered steps: what moves, from where to where, what depends on it, how the move is verified.
|
|
1072
|
+
- **Rulings** — decisions taken along the way: what was decided · what was rejected · why · evidence. A ruling that changes an earlier statement MUST say so explicitly rather than silently superseding it.
|
|
1073
|
+
- **Dispatch breakdown** — which work items this design produces for `/specpro-tasks`. ⚠️ **These items are NOT task IDs** — plan MUST NOT invent an ID prefix; `/specpro-tasks` assigns `T-nnn`. They carry no FR, so the FR-driven generation path does not apply.
|
|
1074
|
+
|
|
1075
|
+
**Validation**: every design decision carries a rejected alternative; every migration step names its verification; the dispatch breakdown uses plain numbered items with no invented ID prefix.
|
|
1076
|
+
|
|
1077
|
+
**Validation**: when the gate is ACTIVE or ACTIVE-WITH-GAPS, all four items are present; the inventory's last column contains **no** ✅/⚠️/❌ status; every unroutable anchor is a GAP row rather than an invented byte sequence.
|
|
1078
|
+
|
|
1079
|
+
**Validation (subsection completeness)**: every subsection this step defines is present and non-empty. ⚠️ The authoritative subsection list is the **template's `## Architecture`**, never a hand-written enumeration here — a hard-coded count goes stale the moment the template gains or loses a subsection (and a stale count silently mis-directs whoever reads it next). The chapter-level check is §5.8's job.
|
|
1080
|
+
|
|
1081
|
+
#### **5.5 Generate Project Structure Section** 🅼 **→ `specs/plan.md`**
|
|
1082
|
+
|
|
1083
|
+
**Progress**: 📋 [5.5/8] Generating Project Structure...
|
|
1084
|
+
|
|
1085
|
+
**Three rules for this section** (settled 2026-09-13; each comes from an observed failure):
|
|
1086
|
+
|
|
1087
|
+
1. **Granularity — directories and path patterns, never file names.** File names are an implementation choice and belong to whoever implements. A plan that enumerates them goes stale the moment anything is renamed or merged, and a stale placement list **looks like a fact** — in one project the tree still showed the protocol core under `commonMain` long after it had landed in `jvmMain`, which made a constitution-level deviation read as compliant.
|
|
1088
|
+
2. **Single authority for the shared/platform boundary.** `## Architecture → ### Shared/Platform Boundary Declaration` is the **only** place that states which layer owns which code; that table is what the Pass M audit checks against the build. This section records **repository module layout only** and MUST NOT restate the boundary — two descriptions of the same boundary means one of them is unaudited, and the unaudited one will be the one that lies.
|
|
1089
|
+
3. **Currency — state that this is a point-in-time convention.** Once implementation lands, the authoritative placement is the **build config and the actual repository**. Say so in the section, and tell downstream Location grounding to prefer build config and existing sibling files.
|
|
1090
|
+
|
|
1091
|
+
**a. Documentation Structure**:
|
|
1092
|
+
- ⚠️ **不要写 "Copy from plan-template.md"**(T171):该模板的 `## Project Structure` 下**只有**
|
|
1093
|
+
`### Source Code (repository root)`,**没有** Documentation Structure 一节 ⇒ 照它抄会抄到一个
|
|
1094
|
+
不存在的东西。本节的内容**按下面两行现列**,并从 `spec.md` / `contracts/` 的**实际**产物取
|
|
1095
|
+
- List all spec files
|
|
1096
|
+
- List contracts/ directory
|
|
1097
|
+
|
|
1098
|
+
**b. Source Code Structure**:
|
|
1099
|
+
- Determine project type from Technical Context:
|
|
1100
|
+
* Single project → "Option 1: Single project"
|
|
1101
|
+
* Web application → "Option 2: Web application"
|
|
1102
|
+
* Mobile + API → "Option 3: Mobile + API"
|
|
1103
|
+
- Remove unused options
|
|
1104
|
+
- Fill in real module/package names
|
|
1105
|
+
|
|
1106
|
+
**c. Structure Decision**:
|
|
1107
|
+
- Document selected type and reasoning
|
|
1108
|
+
|
|
1109
|
+
**d. Test Module Structure Design** ✨ NEW (generic lessons from real project experience):
|
|
1110
|
+
|
|
1111
|
+
**Purpose**: Test locations decided here directly constrain task file paths in tasks.md.
|
|
1112
|
+
A test placed in a directory without build configuration can NEVER be executed by the build system.
|
|
1113
|
+
|
|
1114
|
+
**Test Module Placement Decision** (choose one, document in Structure Decision):
|
|
1115
|
+
|
|
1116
|
+
| Strategy | Layout | When to Use |
|
|
1117
|
+
|----------|--------|-------------|
|
|
1118
|
+
| **In-module tests** (DEFAULT) | `<module>/src/test/...` following the module's OWN build type | Small projects, few test types |
|
|
1119
|
+
| **Separated test modules** | `tests/<type>-test/` as independent build modules | Test types need independent CI execution, independent dependencies, or merged coverage reports |
|
|
1120
|
+
|
|
1121
|
+
**Test Type Module Separation** (for separated strategy):
|
|
1122
|
+
- `tests/unit-test/` (or `core-test/`) — fast, mock-based, run on every commit
|
|
1123
|
+
- `tests/contract-test/` — API contract verification, run on every PR
|
|
1124
|
+
- `tests/integration-test/` — component integration using mocks, CI-friendly (<30s per suite)
|
|
1125
|
+
- `tests/e2e-test/` — real external systems, may require container environment, nightly/weekly runs
|
|
1126
|
+
|
|
1127
|
+
**Layer ownership note**: which test LAYER each module hosts follows the "Typical module" conventions in `/specpro-test-plan` Layer Assignment Rules — the authoritative layer semantics. One module may host multiple layers (e.g. `tests/e2e-test/` hosts CE real-peer packages and the AE app package) and one layer may span modules (IT in `tests/integration-test/` and `tests/contract-test/`). This section decides LAYOUT MECHANICS only (in-module vs separated strategy, module registration, source-set correctness); it does not redefine layer semantics.
|
|
1128
|
+
|
|
1129
|
+
**Parent Test Module Shared Configuration** (for separated strategy):
|
|
1130
|
+
- Central test framework setup, execution logging, and coverage tool configuration in the `tests/` parent build script (applied to all submodules)
|
|
1131
|
+
- Provide a merged coverage report task aggregating all submodules
|
|
1132
|
+
|
|
1133
|
+
**⚠️ CRITICAL Rules (each from a real build failure)**:
|
|
1134
|
+
1. **Standard source directories per build type** — NEVER copy source-set conventions from sibling modules with a different build type:
|
|
1135
|
+
* Single-platform build plugins use `src/test/...` style directories
|
|
1136
|
+
* Multi-platform build plugins use per-target source sets (e.g., `src/jvmTest/`, `src/commonTest/`) that DO NOT exist in single-platform builds — reusing them causes silent `NO-SOURCE` (tests never run) or build errors
|
|
1137
|
+
* Other ecosystems: Maven `src/test/java`, pytest `tests/test_*.py`, Go `*_test.go` alongside source, Rust top-level `tests/`, Jest `__tests__/` — always follow the chosen build system's own convention
|
|
1138
|
+
2. **Build module registration** — every new test module MUST be registered in the workspace/project manifest (settings file / workspace config / solution file), otherwise it is invisible to the build
|
|
1139
|
+
3. **No version re-declaration in submodules** — build plugin versions declared at the root MUST NOT be re-declared with a version number in submodules (causes classpath conflicts)
|
|
1140
|
+
4. **No mixed test framework adapters** — do not combine test adapters targeting different engine generations in one module (causes capability conflicts)
|
|
1141
|
+
5. **Task locations follow this decision** — test file paths generated later in tasks.md MUST resolve to a registered build module with the correct source directory; otherwise `/specpro-implement` will create tests that compile nowhere
|
|
1142
|
+
|
|
1143
|
+
**Concrete Example: a multi-target project** (illustrates the rules above; principles apply to any build system):
|
|
1144
|
+
|
|
1145
|
+
```text
|
|
1146
|
+
# Rule 1 illustration — source sets differ by build plugin type:
|
|
1147
|
+
|
|
1148
|
+
core/ # KMP plugin module → per-target source sets
|
|
1149
|
+
└── src/
|
|
1150
|
+
├── commonMain/kotlin/ # shared code
|
|
1151
|
+
├── commonTest/kotlin/ # shared tests (KMP plugin ONLY)
|
|
1152
|
+
└── jvmTest/kotlin/ # JVM-target tests (KMP plugin ONLY)
|
|
1153
|
+
|
|
1154
|
+
tests/integration-test/ # plain single-target JVM plugin module → standard source sets
|
|
1155
|
+
└── src/
|
|
1156
|
+
├── test/kotlin/ # ✅ CORRECT: executed by `gradle test`
|
|
1157
|
+
└── jvmTest/kotlin/ # ❌ WRONG: copied from core/ convention
|
|
1158
|
+
# → "KotlinSourceSet 'jvmTest' not found" build error,
|
|
1159
|
+
# or silent NO-SOURCE (tests never run)
|
|
1160
|
+
```
|
|
1161
|
+
|
|
1162
|
+
*Typical failure pattern*: a test placed at `src/jvmTest/kotlin/...` inside a
|
|
1163
|
+
plain JVM-plugin module is invisible to the build — it either triggers a
|
|
1164
|
+
"KotlinSourceSet not found" build error or silently reports `NO-SOURCE` with
|
|
1165
|
+
zero tests executed. The fix is to place it at `src/test/kotlin/...`, matching
|
|
1166
|
+
that module's build type.
|
|
1167
|
+
|
|
1168
|
+
```text
|
|
1169
|
+
# Rules 2-4 illustration — separated test modules in a KMP project:
|
|
1170
|
+
|
|
1171
|
+
# settings.gradle.kts (workspace manifest — Rule 2: register every test module):
|
|
1172
|
+
include(":core") // KMP plugin, per-target source sets
|
|
1173
|
+
include(":tests:core-test") // plain JVM plugin
|
|
1174
|
+
include(":tests:contract-test") // plain JVM plugin
|
|
1175
|
+
include(":tests:integration-test") // plain JVM plugin
|
|
1176
|
+
include(":tests:e2e-test") // plain JVM plugin
|
|
1177
|
+
|
|
1178
|
+
# tests/build.gradle.kts (parent module — shared config: framework, logging, Jacoco;
|
|
1179
|
+
# plus a jacocoMergedReport task aggregating all submodules)
|
|
1180
|
+
|
|
1181
|
+
# tests/integration-test/build.gradle.kts (Rule 3 + 4):
|
|
1182
|
+
plugins {
|
|
1183
|
+
kotlin("jvm") // ✅ no version — root already declares it
|
|
1184
|
+
// kotlin("jvm") version "1.9.23" // ❌ "plugin already on the classpath" error
|
|
1185
|
+
}
|
|
1186
|
+
dependencies {
|
|
1187
|
+
testImplementation(kotlin("test")) // ✅ single engine
|
|
1188
|
+
// + kotlin-test-junit AND kotlin-test-junit5 ❌ capability conflict error
|
|
1189
|
+
}
|
|
1190
|
+
```
|
|
1191
|
+
|
|
1192
|
+
**Validation**: Both documentation and source code structure included; test module strategy documented and all future test paths will resolve to configured, executable locations
|
|
1193
|
+
|
|
1194
|
+
#### **5.6 Generate Implementation Plan Section** 🅷 **→ `specs/plan-overview.md`**
|
|
1195
|
+
|
|
1196
|
+
**Progress**: 📋 [5.6/8] Generating Implementation Plan...
|
|
1197
|
+
|
|
1198
|
+
**a. Phase Overview**:
|
|
1199
|
+
- Define phases (typically 0-2 for initial plan)
|
|
1200
|
+
- For each phase in table:
|
|
1201
|
+
* Phase number and name
|
|
1202
|
+
* Goal
|
|
1203
|
+
* Key Deliverables
|
|
1204
|
+
* Estimate (weeks)
|
|
1205
|
+
* Dependencies
|
|
1206
|
+
|
|
1207
|
+
**b. Detailed Phase Breakdown** 🅷 **[Part II · Human-Read]** ⚠️ [NO CHECKBOXES — settled 2026-09-13]:
|
|
1208
|
+
|
|
1209
|
+
> **This subsection replaced the old per-phase checkbox lists.** Two independent findings forced the change:
|
|
1210
|
+
>
|
|
1211
|
+
> 1. **A checkbox here has no possible owner.** Whatever it would show is either (a) already carried by `spec.md`'s `[plan:*]` field, or (b) a **downstream** fact (is the code written? is coverage met?) whose source of truth is a later artifact. Case (a) is a redundant re-render of a field; case (b) cannot be maintained from here at all — this stage does not read downstream artifacts, so the box freezes at whatever it said when written while downstream consumers act on a stale value. In one project 226 boxes sat unticked against FRs that were all `processed`, and the maintenance rule (which keyed off `[plan:*]`) had never once run on them.
|
|
1212
|
+
> 2. **The criteria were the wrong thing to track anyway.** Of the unticked leftovers in that project, most were not tasks but **acceptance criteria** (coverage thresholds, latency budgets, an audit) — and criteria had no judge.
|
|
1213
|
+
|
|
1214
|
+
For each phase:
|
|
1215
|
+
|
|
1216
|
+
* **Goal**: What this phase achieves
|
|
1217
|
+
|
|
1218
|
+
* **Acceptance Criteria and Judges**: a table — **one row per criterion**:
|
|
1219
|
+
|
|
1220
|
+
| Criterion | Judge | State lives in |
|
|
1221
|
+
|-----------|-------|----------------|
|
|
1222
|
+
| [what must hold — a verifiable proposition] | [the command or role that decides it] | [the judge's own artifact] |
|
|
1223
|
+
|
|
1224
|
+
- **Every criterion MUST name its judge.** A criterion you cannot assign to a judge is **not yet a criterion** — it is a gap. Record it as one (`[plan]` issue) rather than leaving an unjudgeable line in the plan.
|
|
1225
|
+
- **No checkboxes. No ✅/⚠️/❌. No "status" column.** The judge holds the state in its own artifact; this file MUST NOT carry acceptance state.
|
|
1226
|
+
- A **human role is an acceptable judge** when the criterion is not mechanically decidable — what is *not* acceptable is leaving it blank. Do not manufacture a fake judge to avoid "TBD": if nobody can decide it yet, say so explicitly.
|
|
1227
|
+
- Common judges: coverage acceptance → `/specpro-implement` §14; performance / integration → `/specpro-test-plan` → `/specpro-test-implement`; this plan's own steps → `/specpro-plan`.
|
|
1228
|
+
|
|
1229
|
+
* **Key Activities**: Numbered list — an **activity description, not a task queue**.
|
|
1230
|
+
- **No checkboxes.**
|
|
1231
|
+
- **MUST NOT restate an acceptance criterion** ⚠️ [settled 2026-09-13]: the two subsections have different jobs — a **criterion** states a verifiable proposition ("coverage ≥90%"), an **activity** states an action ("write the protocol unit tests"). A line that could sit in either place means the split has collapsed: one of them is now a second copy that will drift, and neither has a single owner. The failure this rule prevents: an earlier revision required the *same six strings* in both subsections of a phase, so every generated plan carried each of them twice, verbatim.
|
|
1232
|
+
- **Gating is by `lifecycle_cache`, not by anything ticked here**: an activity is stale when the FR state it serves is `create`/`update`; skip it when that FR is `processed`. Do **not** re-introduce a per-deliverable checklist to decide this — that is exactly the unmaintainable state described above.
|
|
1233
|
+
|
|
1234
|
+
* **Estimate**: Weeks
|
|
1235
|
+
* **Dependencies**: Prerequisites
|
|
1236
|
+
* **Risks**: Potential issues
|
|
1237
|
+
* **Mitigation**: How to address
|
|
1238
|
+
|
|
1239
|
+
**⚠️ FR-anchor rule for everything written in this subsection** (settled 2026-09-13): **anything phrased as "to be done" MUST carry an FR anchor, or live in a task queue** (`specs/tasks.md` / `test-tasks.md` / `fix-tasks.md`). An item with no FR anchor has no legitimate owner: no command will ever pick it up, yet it reads as pending. In one project three such deliverables (push notifications, iOS APNs, a security audit) sat in the plan with no FR behind them — unmatchable to any requirement and permanently unattachable. **When you cannot anchor an item, that is the signal to register it as an issue against the appropriate stage — not to write it here.**
|
|
1240
|
+
|
|
1241
|
+
**Validation**: every phase has all subsections; **no checkbox syntax (`- [ ]` / `- [x]`) appears anywhere in this section**; every acceptance criterion has a non-empty judge; every "to be done" item traces to an FR or a task queue.
|
|
1242
|
+
|
|
1243
|
+
**c. Dependencies and Critical Path**:
|
|
1244
|
+
- Dependency graph or table
|
|
1245
|
+
- Identify critical path
|
|
1246
|
+
- Specify duration in weeks
|
|
1247
|
+
- Identify parallel opportunities
|
|
1248
|
+
|
|
1249
|
+
**d. Risk Management**:
|
|
1250
|
+
- Tables: Technical Risks, Project Risks, Quality Risks
|
|
1251
|
+
- For each: Description, Probability, Impact, Mitigation
|
|
1252
|
+
|
|
1253
|
+
**e. Milestones**:
|
|
1254
|
+
- Table with: Name, Target, Deliverables, Acceptance Criteria
|
|
1255
|
+
|
|
1256
|
+
**Validation**: every subsection this step defines is present and non-empty. ⚠️ The authoritative subsection list is the **template's `## Implementation Plan`** — not a count written here (see §5.8 Check 1 for why).
|
|
1257
|
+
|
|
1258
|
+
#### **5.7 Generate Complexity Tracking Section** (CONDITIONAL) 🅷 **→ `specs/plan-overview.md`**
|
|
1259
|
+
|
|
1260
|
+
**Progress**: 📋 [5.7/8] Generating Complexity Tracking (if violations or justified decisions)...
|
|
1261
|
+
|
|
1262
|
+
**Scope — wider than "violations"** (settled 2026-09-13): this section records **design complexity that needs justifying**, which is two cases, not one:
|
|
1263
|
+
1. **A constitutional principle violation** that must be justified.
|
|
1264
|
+
2. **A decision that rejected a simpler alternative** — the question it answers is the same one: *why wasn't the simpler route enough?* In one project this section carried a TLS-wiring route decision of exactly this kind, placed here deliberately by the issue that dispatched it — so the practice was already wider than the rule, and the rule was corrected to match rather than the other way round.
|
|
1265
|
+
|
|
1266
|
+
- Generate when **either** case applies — not only on ❌ FAIL.
|
|
1267
|
+
- For each entry:
|
|
1268
|
+
* **Violation / Decision**: which principle, or what the decision was
|
|
1269
|
+
* **Why Needed**: business/technical justification
|
|
1270
|
+
* **Simpler Alternative Rejected Because**: what was rejected and why it was insufficient
|
|
1271
|
+
- **If neither case applies**: omit the section, or write `Not applicable`.
|
|
1272
|
+
- **Recording a technology or architecture change** (e.g. "swap the network library"): this section is the place — see **`**Standing rule 2 — change propagation**`** (this file, where the rule is actually stated). ⚠️ This pointer used to name *"§5.8's 'Change propagation' note"* — **§5.8 is Chapter Validation and carries no such note** (`T229` ②): the pointer named a section that does not hold the rule, so a reader following it lands somewhere that cannot answer the question. The entry is the record that the change happened; the FR state update is what makes `tasks` act on it.
|
|
1273
|
+
|
|
1274
|
+
**Validation**: every entry names either a violated principle or an explicitly rejected alternative; no entry is a bare description with no "why not the simpler way".
|
|
1275
|
+
|
|
1276
|
+
#### **5.8 Chapter Validation** 🅼 **→ both files**
|
|
1277
|
+
|
|
1278
|
+
**Progress**: 📋 [5.8/8] Validating plan.md completeness...
|
|
1279
|
+
|
|
1280
|
+
After generating plan.md, validate — **against the template, not against a list written here**:
|
|
1281
|
+
|
|
1282
|
+
> ⚠️ **Why the checklist below is not an enumeration** (settled 2026-09-13): a hand-written list of sections goes stale the moment the template gains or loses one, and it fails **silently** — the validator keeps passing while a whole section goes unchecked. In one project `## Quality Targets`, the section consumed by more downstream commands than any other, was missing from this checklist from the day it was introduced: nothing ever validated it, and unrelated content accumulated there unnoticed for months. **The template's top-level section list is the authority — read the template and iterate that.**
|
|
1283
|
+
|
|
1284
|
+
**Check 1 — section presence (template-driven, BOTH files)**: iterate each template's top-level sections and check the corresponding **file**:
|
|
1285
|
+
- `.specpro/templates/plan-template.md` → `specs/plan.md`
|
|
1286
|
+
- `.specpro/templates/plan-overview-template.md` → `specs/plan-overview.md`
|
|
1287
|
+
|
|
1288
|
+
Each section from each template MUST be present in its file with all of *its* defined subsections present and non-empty. **Both checks are required** — checking only one file leaves the other half unvalidated, which is the same silent-pass shape as the missing-section gap described above. Conditional sections are checked for the right condition, not for presence. **Do not iterate a list from memory.**
|
|
1289
|
+
|
|
1290
|
+
**Check 1b — the split is structural, verify it held** ⚠️:
|
|
1291
|
+
- `specs/plan.md` MUST NOT contain any `##` section belonging to `plan-overview-template.md` (Summary / System Overview / Constitution Check / Implementation Plan / Documentation Layout / Complexity Tracking), and vice versa.
|
|
1292
|
+
- `specs/plan.md` MUST NOT reference any `plan-overview.md` section name (file-path references are fine).
|
|
1293
|
+
- If either fails, the split leaked — the file boundary is the enforcement point for "implement never reads the human half", and a leaked section silently returns to being read.
|
|
1294
|
+
|
|
1295
|
+
**Check 2 — per-section content rules**: each generation step §5.1–§5.7 states its own `**Validation**`; run those. In particular:
|
|
1296
|
+
- Technical Context: all 9 fields filled (may contain NEEDS CLARIFICATION)
|
|
1297
|
+
- Constitution Check: all applicable principles evaluated, each with a stated basis
|
|
1298
|
+
- Implementation Plan: every acceptance criterion names a judge; **no checkbox syntax anywhere in the section**
|
|
1299
|
+
- Complexity Tracking: present only when there is a violation or a rejected-simpler-alternative decision
|
|
1300
|
+
- **Standing rule 0 — `*Purpose · Consumers*`**: **every `##` and `###` section of BOTH files opens
|
|
1301
|
+
with that one-line note**, naming the consumers concretely (§5 "Standing rule 0").
|
|
1302
|
+
⚠️ **This check is new, and it closes a rule that had no reader** (T171 / audit finding: 「`Purpose ·
|
|
1303
|
+
Consumers` 全文档仅此 1 处,§5.8 的三项检查都不读它」). A MUST with no check is a declaration
|
|
1304
|
+
(宪法 I) — the rule was written, the generator was told to obey it, and **nothing ever looked**.
|
|
1305
|
+
⚠️ Cover **sub-sections too**: `§4.i-1..i-4` / `§4.j-1..j-3` extract *per subsection*, and a
|
|
1306
|
+
top-level-only check is blind to exactly the ones they read.
|
|
1307
|
+
|
|
1308
|
+
**Check 3 — cross-section consistency** ⚠️ [structurally invisible to per-section validation]:
|
|
1309
|
+
- Sections MUST NOT contradict one another. Specifically: the layer division in `## System Overview` (runtime component stack) and in `### Layered Architecture` (source-set ownership) MUST NOT be readable as two competing models — each MUST carry its view-semantics line; any section stating a count or scope MUST agree with the section that enumerates it.
|
|
1310
|
+
- **A contradiction between two sections passes every per-section check by construction** — each section is internally coherent. That is exactly why this check exists separately, and why it cannot be delegated to the per-section validations.
|
|
1311
|
+
|
|
1312
|
+
**If validation fails**:
|
|
1313
|
+
- Re-generate missing chapter
|
|
1314
|
+
- Or mark "INCOMPLETE" and continue with warning
|
|
1315
|
+
|
|
1316
|
+
---
|
|
1317
|
+
|
|
1318
|
+
### **Phase 0: Research**
|
|
1319
|
+
|
|
1320
|
+
**Progress**: 📋 [6/8] Executing Phase 0: Research...
|
|
1321
|
+
|
|
1322
|
+
#### **Phase 0: Research**
|
|
1323
|
+
|
|
1324
|
+
**0.1 Extract unknowns from Technical Context**:
|
|
1325
|
+
- For each NEEDS CLARIFICATION → research task
|
|
1326
|
+
- For each dependency → best practices task
|
|
1327
|
+
- For each integration → patterns task
|
|
1328
|
+
|
|
1329
|
+
**0.2 Generate and dispatch research agents**:
|
|
1330
|
+
```text
|
|
1331
|
+
For each unknown:
|
|
1332
|
+
Task: "Research {unknown} for {feature context}"
|
|
1333
|
+
For each technology:
|
|
1334
|
+
Task: "Find best practices for {tech} in {domain}"
|
|
1335
|
+
```
|
|
1336
|
+
|
|
1337
|
+
**0.3 Consolidate findings** in `research.md`:
|
|
1338
|
+
- Decision: What was chosen
|
|
1339
|
+
- Rationale: Why chosen
|
|
1340
|
+
- Alternatives considered: What else evaluated
|
|
1341
|
+
|
|
1342
|
+
**Output**: research.md with all NEEDS CLARIFICATION resolved
|
|
1343
|
+
|
|
1344
|
+
**Progress**: ✓ Phase 0 complete: research.md generated
|
|
1345
|
+
|
|
1346
|
+
---
|
|
1347
|
+
|
|
1348
|
+
### **Step 6.5: Backfill everything that depends on research.md** ✨ NEW (CRITICAL FIX)
|
|
1349
|
+
|
|
1350
|
+
**Purpose**: After Phase 0 research completes, update plan.md Technical Context with decisions
|
|
1351
|
+
|
|
1352
|
+
**Progress**: 📋 [6.5/8] Updating Technical Context from research.md...
|
|
1353
|
+
|
|
1354
|
+
**Why This Step Is Critical**:
|
|
1355
|
+
- The whole §5.x block runs **before** Phase 0 Research
|
|
1356
|
+
- At that time, research.md doesn't exist yet (in initial mode)
|
|
1357
|
+
- Technical Context lives in **plan.md**, not research.md — plan.md is the single source of truth for the technology stack
|
|
1358
|
+
- If Technical Context isn't updated, agents get empty/incorrect tech stack
|
|
1359
|
+
|
|
1360
|
+
**⚠️ Backfill ALL research-dependent sections, not just Technical Context** (settled 2026-09-13):
|
|
1361
|
+
|
|
1362
|
+
> This step was originally scoped to Technical Context alone — and that narrow scoping was the defect. The root cause ("this section's input doesn't exist yet when the section is written") is a **class**, not an instance, so patching it section-by-section guarantees the next member of the class is missed. Two were: `§5.1 Summary` paragraph 2 is specified as coming "from research.md after Phase 0", and `§5.4c Architecture Patterns` requires each pattern to carry a `**See**: research.md section` anchor. Neither had a backfill step.
|
|
1363
|
+
|
|
1364
|
+
**Backfill list** (keep this list in sync — a new section that takes research.md as input MUST be added here when it is introduced; that obligation is part of this step):
|
|
1365
|
+
|
|
1366
|
+
| Section | What to backfill |
|
|
1367
|
+
|---------|------------------|
|
|
1368
|
+
| **Technical Context** (§5.2) | all 9 fields — technology choices, versions, best practices |
|
|
1369
|
+
| **Summary** (§5.1) | paragraph 2 (technical approach) — it is specified as sourced from research.md, which does not exist when §5.1 first runs |
|
|
1370
|
+
| **Architecture Patterns** (§5.4c) | each pattern's `**See**: research.md section` anchor — the anchor cannot be written before the section exists |
|
|
1371
|
+
|
|
1372
|
+
Then continue with 6.5.b onward for the Technical Context field mapping.
|
|
1373
|
+
|
|
1374
|
+
**6.5.a Read research.md**:
|
|
1375
|
+
```markdown
|
|
1376
|
+
Read specs/research.md
|
|
1377
|
+
Extract all decisions:
|
|
1378
|
+
- Technology choices (Language, Framework, Storage, etc.)
|
|
1379
|
+
- Versions selected
|
|
1380
|
+
- Best practices identified
|
|
1381
|
+
```
|
|
1382
|
+
|
|
1383
|
+
**6.5.b Map research decisions to Technical Context fields**:
|
|
1384
|
+
```markdown
|
|
1385
|
+
For each decision in research.md:
|
|
1386
|
+
→ Update corresponding field in plan.md Technical Context
|
|
1387
|
+
|
|
1388
|
+
Example mappings:
|
|
1389
|
+
- "Decision: [Language] [version]"
|
|
1390
|
+
→ **Language/Version**: [Language] [version]
|
|
1391
|
+
|
|
1392
|
+
- "Decision: [framework] [version] for the plugin layer"
|
|
1393
|
+
→ **Primary Dependencies**: [framework] [version], [Language] [version]
|
|
1394
|
+
|
|
1395
|
+
- "Decision: [database] with the [driver] driver"
|
|
1396
|
+
→ **Storage**: [database] [version] with the [driver] driver
|
|
1397
|
+
|
|
1398
|
+
- "Decision: [UI toolkit] [version]"
|
|
1399
|
+
→ **Primary Dependencies**: Add [UI toolkit] [version]
|
|
1400
|
+
```
|
|
1401
|
+
|
|
1402
|
+
**6.5.c Update plan.md Technical Context**:
|
|
1403
|
+
```markdown
|
|
1404
|
+
For each field in Technical Context:
|
|
1405
|
+
1. Read plan.md Technical Context field
|
|
1406
|
+
2. If value is "NEEDS CLARIFICATION":
|
|
1407
|
+
- Find corresponding decision in research.md
|
|
1408
|
+
- Update field with decision text
|
|
1409
|
+
3. If value already filled:
|
|
1410
|
+
- Compare with research.md decision
|
|
1411
|
+
- Update if different (research is authoritative)
|
|
1412
|
+
4. Mark field as updated
|
|
1413
|
+
```
|
|
1414
|
+
|
|
1415
|
+
**6.5.d Validation**:
|
|
1416
|
+
```markdown
|
|
1417
|
+
After update:
|
|
1418
|
+
1. Count "NEEDS CLARIFICATION" remaining in Technical Context
|
|
1419
|
+
2. If > 0:
|
|
1420
|
+
- WARNING: "X Technical Context fields still unresolved"
|
|
1421
|
+
- List unresolved fields
|
|
1422
|
+
- Check if corresponding decisions exist in research.md
|
|
1423
|
+
3. If 0:
|
|
1424
|
+
- ✓ SUCCESS: "All Technical Context fields resolved"
|
|
1425
|
+
```
|
|
1426
|
+
|
|
1427
|
+
**6.5.e Report update summary**:
|
|
1428
|
+
```markdown
|
|
1429
|
+
## Technical Context Update Summary
|
|
1430
|
+
|
|
1431
|
+
**Fields Updated**: N
|
|
1432
|
+
- Language/Version: NEEDS CLARIFICATION → [Language] [version]
|
|
1433
|
+
- Primary Dependencies: NEEDS CLARIFICATION → [framework] [version], [UI toolkit] [version]
|
|
1434
|
+
- Storage: NEEDS CLARIFICATION → [database] [version] with the [driver] driver
|
|
1435
|
+
|
|
1436
|
+
**Fields Unresolved**: M
|
|
1437
|
+
- Testing: NEEDS CLARIFICATION (no decision found in research.md)
|
|
1438
|
+
- Performance Goals: NEEDS CLARIFICATION (needs clarification)
|
|
1439
|
+
|
|
1440
|
+
✓ Technical Context ready for Phase 1 Design
|
|
1441
|
+
```
|
|
1442
|
+
|
|
1443
|
+
**Progress**: ✓ Technical Context updated with N research decisions
|
|
1444
|
+
|
|
1445
|
+
---
|
|
1446
|
+
|
|
1447
|
+
### **Step 6.6: Phase 0 Completion Checkpoint** ✨ NEW
|
|
1448
|
+
|
|
1449
|
+
**Purpose**: Verify Phase 0 research quality before proceeding to Phase 1
|
|
1450
|
+
|
|
1451
|
+
**Progress**: 📋 [6.6/8] Verifying Phase 0 completion...
|
|
1452
|
+
|
|
1453
|
+
**6.6.a research.md completeness check**:
|
|
1454
|
+
```markdown
|
|
1455
|
+
Verify research.md contains:
|
|
1456
|
+
- [ ] All NEEDS CLARIFICATION items from Technical Context resolved
|
|
1457
|
+
- [ ] Technology stack decisions documented
|
|
1458
|
+
- [ ] Version numbers specified
|
|
1459
|
+
- [ ] Rationale for each decision
|
|
1460
|
+
- [ ] Alternatives considered
|
|
1461
|
+
- [ ] Trade-offs documented
|
|
1462
|
+
|
|
1463
|
+
If any missing:
|
|
1464
|
+
WARNING: "research.md incomplete, missing: [list missing items]"
|
|
1465
|
+
Recommendation: "Review research.md and ensure all decisions are documented"
|
|
1466
|
+
Choice: "Continue anyway (yes/no)"
|
|
1467
|
+
```
|
|
1468
|
+
|
|
1469
|
+
**6.6.b Technical Context consistency check**:
|
|
1470
|
+
```markdown
|
|
1471
|
+
Verify consistency between research.md and plan.md Technical Context:
|
|
1472
|
+
- For each decision in research.md:
|
|
1473
|
+
- Corresponding Technical Context field updated?
|
|
1474
|
+
- Values match (or at least consistent)?
|
|
1475
|
+
|
|
1476
|
+
If inconsistency found:
|
|
1477
|
+
WARNING: "Inconsistency detected: research.md says 'X', Technical Context says 'Y'"
|
|
1478
|
+
Recommendation: "Update Technical Context to match research.md"
|
|
1479
|
+
```
|
|
1480
|
+
|
|
1481
|
+
**6.6.c Gate check**:
|
|
1482
|
+
```markdown
|
|
1483
|
+
Preliminary gate evaluation (before Phase 1):
|
|
1484
|
+
- Check if any Constitution violations introduced by technology choices
|
|
1485
|
+
- Early detection of issues
|
|
1486
|
+
```
|
|
1487
|
+
|
|
1488
|
+
**Checkpoint Result**:
|
|
1489
|
+
```markdown
|
|
1490
|
+
✓ Phase 0 completion verified
|
|
1491
|
+
- research.md: Complete
|
|
1492
|
+
- Technical Context: Updated and consistent
|
|
1493
|
+
- Constitution: No new violations
|
|
1494
|
+
|
|
1495
|
+
Proceeding to Phase 1...
|
|
1496
|
+
```
|
|
1497
|
+
|
|
1498
|
+
**Progress**: ✓ Phase 0 checkpoint passed
|
|
1499
|
+
|
|
1500
|
+
---
|
|
1501
|
+
|
|
1502
|
+
### **Phase 1: Design & Contracts** ✨ OPTIMIZED
|
|
1503
|
+
|
|
1504
|
+
**Prerequisites**: research.md complete, Technical Context updated
|
|
1505
|
+
|
|
1506
|
+
**Progress**: 📐 [7/8] Phase 1: Generating design artifacts...
|
|
1507
|
+
|
|
1508
|
+
**1.0 Extract entities** → `data-model.md` ✨ ENHANCED (Incremental Update):
|
|
1509
|
+
|
|
1510
|
+
**a. Detect operation mode**:
|
|
1511
|
+
```markdown
|
|
1512
|
+
⚠️ UPDATE_MODE is DERIVED, not passed in (settled 2026-09-13): it was previously read in five places and
|
|
1513
|
+
assigned nowhere, so which path ran was left to the executor's guess — and the initial path regenerates
|
|
1514
|
+
`data-model.md` from scratch. Derive it from the shared rerun rule at the top of this command:
|
|
1515
|
+
|
|
1516
|
+
[ -s specs/data-model.md ] → UPDATE_MODE = true (incremental: evolve the existing model)
|
|
1517
|
+
absent / empty → UPDATE_MODE = false (initial: generate from scratch)
|
|
1518
|
+
|
|
1519
|
+
When it already exists, the SAME confirmation as the shared rule applies: the initial path runs on an
|
|
1520
|
+
existing artifact only on explicit request, re-confirmed.
|
|
1521
|
+
|
|
1522
|
+
- IF UPDATE_MODE = false (initial specification):
|
|
1523
|
+
→ Generate complete data-model.md from scratch
|
|
1524
|
+
→ Proceed to Step 1.b
|
|
1525
|
+
|
|
1526
|
+
- IF UPDATE_MODE = true (evolution iteration):
|
|
1527
|
+
→ Check which User Stories are modified
|
|
1528
|
+
→ Apply incremental update strategy
|
|
1529
|
+
→ Proceed to Step 1.c
|
|
1530
|
+
```
|
|
1531
|
+
|
|
1532
|
+
**b. Generate complete data-model.md** (INITIAL MODE):
|
|
1533
|
+
```markdown
|
|
1534
|
+
Extract all entities from spec.md:
|
|
1535
|
+
- Entity name, fields, relationships
|
|
1536
|
+
- Validation rules from requirements
|
|
1537
|
+
- State transitions if applicable
|
|
1538
|
+
- Map entities to User Stories
|
|
1539
|
+
|
|
1540
|
+
**From Acceptance Scenarios - Edge Cases** 🆕:
|
|
1541
|
+
- Identify boundary conditions → validation rules and constraints
|
|
1542
|
+
- Map each Edge Case to data model fields:
|
|
1543
|
+
* "Account locked after 5 attempts"
|
|
1544
|
+
→ User.failed_attempts (int, max_value=5)
|
|
1545
|
+
→ User.locked_until (timestamp, nullable)
|
|
1546
|
+
→ User.status (enum: active, locked)
|
|
1547
|
+
* "Token expires in 30 days"
|
|
1548
|
+
→ Session.created_at (timestamp)
|
|
1549
|
+
→ Session.expires_at (timestamp, +30 days)
|
|
1550
|
+
* "Connection timeout within 3 seconds"
|
|
1551
|
+
→ Connection.timeout (int, 3000ms)
|
|
1552
|
+
- Document state transitions if applicable
|
|
1553
|
+
|
|
1554
|
+
**From Acceptance Scenarios - Error Scenarios** 🆕:
|
|
1555
|
+
- Identify error conditions → status fields and error handling
|
|
1556
|
+
- Map each Error Scenario to data model needs:
|
|
1557
|
+
* "Network disconnect detected within 10 seconds"
|
|
1558
|
+
→ ConnectionState.last_heartbeat (timestamp)
|
|
1559
|
+
→ ConnectionMonitor.timeout (int, 10000ms)
|
|
1560
|
+
* "Plugin initialization fails gracefully"
|
|
1561
|
+
→ PluginState enum: CREATED, RESOLVED, STARTED, FAILED
|
|
1562
|
+
→ Plugin.error_message (string, nullable)
|
|
1563
|
+
* "Invalid server address"
|
|
1564
|
+
→ ConnectionResult.error_code (enum)
|
|
1565
|
+
→ ConnectionResult.user_message (string)
|
|
1566
|
+
|
|
1567
|
+
**From Acceptance Scenarios - Permission Scenarios** 🆕:
|
|
1568
|
+
- Identify access control needs → ownership and role fields
|
|
1569
|
+
- Map each Permission Scenario to data model:
|
|
1570
|
+
* "User can only access own data"
|
|
1571
|
+
→ Resource.user_id (foreign key, indexed)
|
|
1572
|
+
→ Resource.is_public (boolean, default=false)
|
|
1573
|
+
* "Admin can access all data"
|
|
1574
|
+
→ User.role (enum: user, admin, super_admin)
|
|
1575
|
+
* "Password-protected server"
|
|
1576
|
+
→ Connection.requires_auth (boolean)
|
|
1577
|
+
→ Connection.auth_password (encrypted, nullable)
|
|
1578
|
+
|
|
1579
|
+
- Create file: specs/data-model.md
|
|
1580
|
+
|
|
1581
|
+
**Progress**: 📐 [1/4] data-model.md generated (initial)...
|
|
1582
|
+
```
|
|
1583
|
+
|
|
1584
|
+
**c. Incremental entity updates** ✨ NEW (EVOLUTION MODE):
|
|
1585
|
+
```markdown
|
|
1586
|
+
**Purpose**: Update only modified User Story entities, preserve unchanged ones
|
|
1587
|
+
|
|
1588
|
+
**1. Identify modified User Stories**:
|
|
1589
|
+
- Read lifecycle_cache
|
|
1590
|
+
- Filter User Stories where planStatus = "update"
|
|
1591
|
+
- Extract associated entities
|
|
1592
|
+
|
|
1593
|
+
**2. Smart merge strategy**:
|
|
1594
|
+
For each entity in data-model.md:
|
|
1595
|
+
- **Preserve**: Entities from unchanged User Stories (planStatus = "processed")
|
|
1596
|
+
- **Update**: Entities from modified User Stories (planStatus = "update")
|
|
1597
|
+
* Add new fields from new FRs
|
|
1598
|
+
* Update validation rules if changed
|
|
1599
|
+
* Add new relationships
|
|
1600
|
+
* Mark as [Updated] in change log
|
|
1601
|
+
- **Add**: New entities from new User Stories (planStatus = "create")
|
|
1602
|
+
* Mark as [New] in change log
|
|
1603
|
+
- **Remove**: Entities from deprecated User Stories (planStatus = "deprecated")
|
|
1604
|
+
* Mark as [Removed] in change log
|
|
1605
|
+
|
|
1606
|
+
**3. Change tracking**:
|
|
1607
|
+
Add section to data-model.md:
|
|
1608
|
+
```markdown
|
|
1609
|
+
## Entity Changes (v{NEW_VERSION})
|
|
1610
|
+
|
|
1611
|
+
### New Entities
|
|
1612
|
+
- [New] XxxSubEncoding (from FR-xxxB)
|
|
1613
|
+
→ Added for sub-encoding format support
|
|
1614
|
+
|
|
1615
|
+
### Updated Entities
|
|
1616
|
+
- [Updated] EncodingType (from FR-xxxA, FR-xxxB)
|
|
1617
|
+
→ Added JPEG, PNG, ZLIB sub-encodings
|
|
1618
|
+
|
|
1619
|
+
### Removed Entities
|
|
1620
|
+
- [Removed] LegacyAuth (deprecated in v0.3)
|
|
1621
|
+
→ Replaced by OAuth2
|
|
1622
|
+
```
|
|
1623
|
+
|
|
1624
|
+
**4. Preserve completed entity status**:
|
|
1625
|
+
- Keep [x] markers for implemented entities
|
|
1626
|
+
- Mark new/updated entities as [ ]
|
|
1627
|
+
- Update entity relationships
|
|
1628
|
+
|
|
1629
|
+
**5. Validation**:
|
|
1630
|
+
- Validate entity relationships after updates
|
|
1631
|
+
- Ensure no orphaned references
|
|
1632
|
+
- Check for duplicate fields
|
|
1633
|
+
|
|
1634
|
+
**Progress**: 📐 [1/4] data-model.md updated (incremental)...
|
|
1635
|
+
```
|
|
1636
|
+
|
|
1637
|
+
**Benefits**:
|
|
1638
|
+
- ✅ Avoid full overwrite of data-model.md
|
|
1639
|
+
- ✅ Preserve completed status of implemented entities
|
|
1640
|
+
- ✅ Update only changed sections
|
|
1641
|
+
- ✅ Clear change tracking
|
|
1642
|
+
|
|
1643
|
+
**1.5 Generate Database Schema Files** ✨ NEW (Database Evolution):
|
|
1644
|
+
|
|
1645
|
+
**Purpose**: Auto-generate database schema files (.sq) and initial migration from data-model.md entities
|
|
1646
|
+
|
|
1647
|
+
**Progress**: 📐 [1.25/4] Database schema files generated...
|
|
1648
|
+
|
|
1649
|
+
**Why This Step Is Critical**:
|
|
1650
|
+
- Converts entity definitions into executable SQL schema
|
|
1651
|
+
- Provides version-controlled database schema (V1__InitialSchema.sq)
|
|
1652
|
+
- Enables Database Evolution with migration files
|
|
1653
|
+
- Follows the project's chosen database framework's schema conventions
|
|
1654
|
+
|
|
1655
|
+
**1.5.a Detect Database Requirement**:
|
|
1656
|
+
```markdown
|
|
1657
|
+
Check Technical Context → Storage field:
|
|
1658
|
+
- IF Storage contains "SQLDelight" OR "SQLite" OR "PostgreSQL" OR "MySQL":
|
|
1659
|
+
→ Database required, proceed to Step 1.5.b
|
|
1660
|
+
- ELSE:
|
|
1661
|
+
→ Skip this step (no database needed)
|
|
1662
|
+
→ Proceed to Step 2.0
|
|
1663
|
+
```
|
|
1664
|
+
|
|
1665
|
+
**1.5.b Generate .sq Schema Files** (INITIAL MODE):
|
|
1666
|
+
```markdown
|
|
1667
|
+
**Purpose**: Generate the schema files (.sq) from data-model.md entities using the project's database framework
|
|
1668
|
+
|
|
1669
|
+
**For each entity in data-model.md**:
|
|
1670
|
+
1. **Extract entity metadata**:
|
|
1671
|
+
- Entity name (e.g., "Plugin", "Connection", "Session")
|
|
1672
|
+
- Fields with types (e.g., "id: TEXT", "created_at: INTEGER")
|
|
1673
|
+
- Primary key (usually "id" field)
|
|
1674
|
+
- Foreign keys (relationships between entities)
|
|
1675
|
+
- Indexes (for query optimization)
|
|
1676
|
+
- Constraints (UNIQUE, NOT NULL, DEFAULT)
|
|
1677
|
+
|
|
1678
|
+
2. **Generate .sq file content**:
|
|
1679
|
+
- File path: `shared/commonMain/sqldelight/com/example/db/[Entity].sq`
|
|
1680
|
+
- Content format:
|
|
1681
|
+
```sql
|
|
1682
|
+
CREATE TABLE [EntityName] (
|
|
1683
|
+
[FieldName] [DataType]([Size]) [Constraints],
|
|
1684
|
+
...
|
|
1685
|
+
PRIMARY KEY ([PrimaryKeyField]),
|
|
1686
|
+
FOREIGN KEY ([ForeignKeyField]) REFERENCES [RelatedEntity]([RelatedField])
|
|
1687
|
+
);
|
|
1688
|
+
|
|
1689
|
+
CREATE INDEX idx_[EntityName]_[FieldName] ON [EntityName]([FieldName]);
|
|
1690
|
+
|
|
1691
|
+
-- Sample queries
|
|
1692
|
+
selectAll:
|
|
1693
|
+
SELECT * FROM [EntityName];
|
|
1694
|
+
|
|
1695
|
+
selectById:
|
|
1696
|
+
SELECT * FROM [EntityName] WHERE id = ?;
|
|
1697
|
+
|
|
1698
|
+
insert:
|
|
1699
|
+
INSERT INTO [EntityName] VALUES (?, ?, ...);
|
|
1700
|
+
|
|
1701
|
+
update:
|
|
1702
|
+
UPDATE [EntityName] SET [field1] = ?, [field2] = ? WHERE id = ?;
|
|
1703
|
+
|
|
1704
|
+
delete:
|
|
1705
|
+
DELETE FROM [EntityName] WHERE id = ?;
|
|
1706
|
+
```
|
|
1707
|
+
|
|
1708
|
+
3. **Create directory structure** (if not exists):
|
|
1709
|
+
- `shared/commonMain/sqldelight/com/example/db/`
|
|
1710
|
+
|
|
1711
|
+
4. **Write .sq files**:
|
|
1712
|
+
- Create file: `[EntityName].sq`
|
|
1713
|
+
- Add table definition
|
|
1714
|
+
- Add indexes (for frequently queried fields)
|
|
1715
|
+
- Add common queries (SELECT, INSERT, UPDATE, DELETE)
|
|
1716
|
+
|
|
1717
|
+
5. **Validate generated schemas**:
|
|
1718
|
+
- Check all entities have .sq files
|
|
1719
|
+
- Verify foreign key relationships are valid
|
|
1720
|
+
- Verify indexes are created for indexed fields
|
|
1721
|
+
- Check for SQL syntax errors
|
|
1722
|
+
```
|
|
1723
|
+
|
|
1724
|
+
**1.5.c Generate Initial Migration V1__InitialSchema.sq**:
|
|
1725
|
+
```markdown
|
|
1726
|
+
**Purpose**: Generate versioned initial migration file
|
|
1727
|
+
|
|
1728
|
+
**Migration file**:
|
|
1729
|
+
- File path: `shared/commonMain/sqldelight/com/example/db/migrations/V1__InitialSchema.sq`
|
|
1730
|
+
- Content format:
|
|
1731
|
+
```sql
|
|
1732
|
+
-- V1__InitialSchema
|
|
1733
|
+
-- Generated: [DATE]
|
|
1734
|
+
-- Purpose: Initial database schema for [FEATURE_NAME]
|
|
1735
|
+
|
|
1736
|
+
-- Create all tables
|
|
1737
|
+
CREATE TABLE plugin (
|
|
1738
|
+
id TEXT PRIMARY KEY,
|
|
1739
|
+
name TEXT NOT NULL,
|
|
1740
|
+
version TEXT NOT NULL,
|
|
1741
|
+
enabled INTEGER NOT NULL DEFAULT 1,
|
|
1742
|
+
created_at INTEGER NOT NULL
|
|
1743
|
+
);
|
|
1744
|
+
|
|
1745
|
+
CREATE TABLE vnc_connection (
|
|
1746
|
+
id TEXT PRIMARY KEY,
|
|
1747
|
+
name TEXT NOT NULL,
|
|
1748
|
+
host TEXT NOT NULL,
|
|
1749
|
+
port INTEGER NOT NULL DEFAULT 5900,
|
|
1750
|
+
password TEXT,
|
|
1751
|
+
created_at INTEGER NOT NULL
|
|
1752
|
+
);
|
|
1753
|
+
|
|
1754
|
+
CREATE TABLE session (
|
|
1755
|
+
id TEXT PRIMARY KEY,
|
|
1756
|
+
connection_id TEXT NOT NULL,
|
|
1757
|
+
started_at INTEGER NOT NULL,
|
|
1758
|
+
ended_at INTEGER,
|
|
1759
|
+
status TEXT NOT NULL,
|
|
1760
|
+
FOREIGN KEY (connection_id) REFERENCES vnc_connection(id) ON DELETE CASCADE
|
|
1761
|
+
);
|
|
1762
|
+
|
|
1763
|
+
-- Create indexes
|
|
1764
|
+
CREATE INDEX idx_plugin_enabled ON plugin(enabled);
|
|
1765
|
+
CREATE INDEX idx_session_connection ON session(connection_id);
|
|
1766
|
+
CREATE INDEX idx_session_status ON session(status);
|
|
1767
|
+
|
|
1768
|
+
-- Migration complete
|
|
1769
|
+
```
|
|
1770
|
+
|
|
1771
|
+
**Versioning convention**:
|
|
1772
|
+
- V1__InitialSchema.sq (first version)
|
|
1773
|
+
- V2__AddPasswordField.sq (schema evolution)
|
|
1774
|
+
- V3__RenameStatusColumn.sq (schema evolution)
|
|
1775
|
+
See Step 1.5.e for schema evolution
|
|
1776
|
+
```
|
|
1777
|
+
|
|
1778
|
+
**1.5.d Schema Evolution Detection** (EVOLUTION MODE):
|
|
1779
|
+
```markdown
|
|
1780
|
+
**Purpose**: Detect entity changes and generate schema evolution migrations
|
|
1781
|
+
|
|
1782
|
+
**Trigger**: UPDATE_MODE = true AND data-model.md has entity changes
|
|
1783
|
+
|
|
1784
|
+
**For each changed entity** (from Step 1.c "Entity Changes"):
|
|
1785
|
+
1. **Compare old vs new schema**:
|
|
1786
|
+
- Old schema: Existing .sq file content
|
|
1787
|
+
- New schema: New entity definition from updated data-model.md
|
|
1788
|
+
|
|
1789
|
+
2. **Detect change types**:
|
|
1790
|
+
- **NEW field added**: Generate ALTER TABLE ADD COLUMN migration
|
|
1791
|
+
- **REMOVED field**: Generate ALTER TABLE DROP COLUMN migration
|
|
1792
|
+
- **RENAMED field**: Generate ALTER TABLE RENAME COLUMN migration
|
|
1793
|
+
- **TYPE changed**: Generate ALTER TABLE ALTER COLUMN migration
|
|
1794
|
+
- **NEW table added**: Generate CREATE TABLE migration
|
|
1795
|
+
- **DROPPED table**: Generate DROP TABLE migration
|
|
1796
|
+
|
|
1797
|
+
3. **Generate schema evolution migration file**:
|
|
1798
|
+
- File: `V{N}__[ChangeDescription].sq`
|
|
1799
|
+
- Example: `V2__AddPluginAuthorField.sq`
|
|
1800
|
+
- Example: `V3__RenameStatusToState.sq`
|
|
1801
|
+
- Content format:
|
|
1802
|
+
```sql
|
|
1803
|
+
-- V{N}__{ChangeDescription}
|
|
1804
|
+
-- Generated: [DATE]
|
|
1805
|
+
-- Purpose: {Explanation of change}
|
|
1806
|
+
|
|
1807
|
+
ALTER TABLE plugin ADD COLUMN author TEXT;
|
|
1808
|
+
-- or
|
|
1809
|
+
ALTER TABLE session RENAME COLUMN status TO state;
|
|
1810
|
+
-- or
|
|
1811
|
+
CREATE INDEX idx_plugin_author ON plugin(author);
|
|
1812
|
+
```
|
|
1813
|
+
|
|
1814
|
+
4. **Update .sq files**:
|
|
1815
|
+
- Overwrite existing .sq files with new schema
|
|
1816
|
+
- Preserve migration files (V1, V2, V3...)
|
|
1817
|
+
```
|
|
1818
|
+
|
|
1819
|
+
**1.5.e Database Evolution vs Data Migration - Terminology**:
|
|
1820
|
+
```markdown
|
|
1821
|
+
**IMPORTANT CLARIFICATION**:
|
|
1822
|
+
|
|
1823
|
+
**Database Evolution** (or **Schema Evolution**):
|
|
1824
|
+
- Definition: Modifying database schema within the SAME database system
|
|
1825
|
+
- Examples:
|
|
1826
|
+
* Adding a new field to existing table (SQL: ALTER TABLE ADD COLUMN)
|
|
1827
|
+
* Renaming a column (SQL: ALTER TABLE RENAME COLUMN)
|
|
1828
|
+
* Changing data type (SQL: ALTER TABLE ALTER COLUMN)
|
|
1829
|
+
* Adding new table (SQL: CREATE TABLE)
|
|
1830
|
+
* Adding index (SQL: CREATE INDEX)
|
|
1831
|
+
- Migration files: V1__InitialSchema.sq, V2__AddField.sq, V3__RenameColumn.sq
|
|
1832
|
+
- Framework: SQLDelight, Flyway, Liquibase
|
|
1833
|
+
- Purpose: Evolve database schema incrementally as application grows
|
|
1834
|
+
|
|
1835
|
+
**Data Migration** (or **System Migration**):
|
|
1836
|
+
- Definition: Moving data from ONE database system to ANOTHER database system
|
|
1837
|
+
- Examples:
|
|
1838
|
+
* Oracle → PostgreSQL
|
|
1839
|
+
* MySQL → SQLite
|
|
1840
|
+
* SQL Server → MongoDB
|
|
1841
|
+
* On-premises → Cloud database
|
|
1842
|
+
- Tools: ETL tools, custom export/import scripts
|
|
1843
|
+
- Purpose: Change database technology stack
|
|
1844
|
+
|
|
1845
|
+
**DO NOT confuse these terms**:
|
|
1846
|
+
- ❌ "Database migration" for adding a field → Use "Schema evolution" instead
|
|
1847
|
+
- ✅ "Database migration" for Oracle → PostgreSQL → Correct usage
|
|
1848
|
+
|
|
1849
|
+
**Why terminology matters**:
|
|
1850
|
+
- "Schema evolution" clearly indicates incremental changes within same system
|
|
1851
|
+
- "Data migration" clearly indicates system-wide technology change
|
|
1852
|
+
- Different concepts require different tools and approaches
|
|
1853
|
+
```
|
|
1854
|
+
|
|
1855
|
+
**1.5.f Generate Database Setup Documentation**:
|
|
1856
|
+
```markdown
|
|
1857
|
+
**Purpose**: Add database setup section to quickstart.md (see Step 4.3)
|
|
1858
|
+
|
|
1859
|
+
**Database Setup section content**:
|
|
1860
|
+
- Prerequisites (database framework version, database driver)
|
|
1861
|
+
- Schema files location (`shared/commonMain/sqldelight/`)
|
|
1862
|
+
- Migration files location (`shared/commonMain/sqldelight/com/example/db/migrations/`)
|
|
1863
|
+
- Initial database setup commands (if applicable)
|
|
1864
|
+
- Schema evolution workflow (how to add V2, V3 migrations)
|
|
1865
|
+
- Verification steps (how to verify schema is correct)
|
|
1866
|
+
```
|
|
1867
|
+
|
|
1868
|
+
**Progress**: 📐 [1.25/4] Database schema files generated...
|
|
1869
|
+
|
|
1870
|
+
**Example Output**:
|
|
1871
|
+
```markdown
|
|
1872
|
+
## Database Schema Files Generated
|
|
1873
|
+
|
|
1874
|
+
**.sq Schema Files**: N files
|
|
1875
|
+
- shared/commonMain/sqldelight/com/example/db/Plugin.sq
|
|
1876
|
+
- shared/commonMain/sqldelight/com/example/db/Connection.sq
|
|
1877
|
+
- shared/commonMain/sqldelight/com/example/db/Session.sq
|
|
1878
|
+
|
|
1879
|
+
**Migration Files**: 1 file
|
|
1880
|
+
- shared/commonMain/sqldelight/com/example/db/migrations/V1__InitialSchema.sq
|
|
1881
|
+
|
|
1882
|
+
**Schema Evolution Files**: M files (if UPDATE_MODE = true)
|
|
1883
|
+
- shared/commonMain/sqldelight/com/example/db/migrations/V2__AddPluginAuthorField.sq
|
|
1884
|
+
- shared/commonMain/sqldelight/com/example/db/migrations/V3__RenameStatusToState.sq
|
|
1885
|
+
|
|
1886
|
+
**Database Setup Section**: Added to quickstart.md (Step 4.3)
|
|
1887
|
+
```
|
|
1888
|
+
|
|
1889
|
+
**1.5.g Update Technical Context**:
|
|
1890
|
+
```markdown
|
|
1891
|
+
Add to Technical Context → Storage:
|
|
1892
|
+
- **Schema Files**: Path to .sq files
|
|
1893
|
+
- **Migration Framework**: [the project's database framework] (or other)
|
|
1894
|
+
- **Initial Schema**: V1__InitialSchema.sq
|
|
1895
|
+
- **Schema Evolution**: V2, V3... migration files location
|
|
1896
|
+
```
|
|
1897
|
+
|
|
1898
|
+
**2.0 Pre-generation Contract Coverage Check** ✨ NEW (OPTIMIZATION):
|
|
1899
|
+
|
|
1900
|
+
**Purpose**: Generate ONLY missing contracts, avoid regeneration
|
|
1901
|
+
|
|
1902
|
+
**a. Scan existing contracts/**:
|
|
1903
|
+
```markdown
|
|
1904
|
+
Scan specs/contracts/ directory:
|
|
1905
|
+
- List all existing .md files
|
|
1906
|
+
- Parse to identify which User Stories they cover
|
|
1907
|
+
```
|
|
1908
|
+
|
|
1909
|
+
**b. Calculate current coverage** ✨ ENHANCED (Modified User Story detection):
|
|
1910
|
+
```markdown
|
|
1911
|
+
For each User Story in spec.md:
|
|
1912
|
+
- Check if dedicated contract exists in specs/contracts/
|
|
1913
|
+
- **NEW**: Check User Story's planStatus from lifecycle_cache
|
|
1914
|
+
* planStatus = "processed" → Contract exists, check if needs update
|
|
1915
|
+
* planStatus = "update" → **Contract needs regeneration** ⚠️
|
|
1916
|
+
* planStatus = "create" → Contract missing, needs generation
|
|
1917
|
+
* planStatus = "deprecated" → Skip (User Story deprecated)
|
|
1918
|
+
- Categorize by priority:
|
|
1919
|
+
* P1 User Stories: Need 100% coverage
|
|
1920
|
+
* P2 User Stories: Need 70% coverage
|
|
1921
|
+
* P3 User Stories: Need 30% coverage
|
|
1922
|
+
|
|
1923
|
+
Current coverage:
|
|
1924
|
+
- P1: X/Y contracts (Z%)
|
|
1925
|
+
- P2: A/B contracts (C%)
|
|
1926
|
+
- P3: D/E contracts (F%)
|
|
1927
|
+
|
|
1928
|
+
**NEW**: Modified Items (need contract regeneration):
|
|
1929
|
+
- US2: remote-viewing.md (planStatus=update, 5 new FRs added)
|
|
1930
|
+
- US3: multi-view-grid.md (planStatus=update, performance requirements updated)
|
|
1931
|
+
|
|
1932
|
+
**c. Source-reference staleness** ⚠️ [the second, independent trigger]:
|
|
1933
|
+
|
|
1934
|
+
A contract is written against *facts that come from somewhere*. When those somewhere's change, the contract silently goes stale — its User Story can be untouched while a fact it asserts has moved. Regenerating by User Story alone therefore misses exactly the drift that matters most: a contract still stating a value its source no longer says.
|
|
1935
|
+
|
|
1936
|
+
Detect per **contract section**, not per contract file: a contract typically anchors different sections to different sources, and only the affected sections are stale.
|
|
1937
|
+
|
|
1938
|
+
```markdown
|
|
1939
|
+
For each contract under specs/contracts/:
|
|
1940
|
+
- Read its source attributions (the per-fact source layer + version markers)
|
|
1941
|
+
- Resolve each attribution to its source artifact:
|
|
1942
|
+
* L1 / spec-sourced fact → the cited FR (or spec section)
|
|
1943
|
+
* L2 implementation-sourced fact → the cited implementation and version
|
|
1944
|
+
* L3 capture-sourced fact → the cited capture record
|
|
1945
|
+
- Flag the SECTION when any of these hold:
|
|
1946
|
+
* the cited FR's planStatus is create/update (its content moved) → stale
|
|
1947
|
+
* the cited implementation's version no longer matches the attribution → stale
|
|
1948
|
+
* an asserted fact carries no attribution at all → unverifiable, not merely stale
|
|
1949
|
+
- Report stale sections alongside the User-Story-driven regeneration list; both feed the same
|
|
1950
|
+
regeneration pass, and non-stale sections are preserved verbatim
|
|
1951
|
+
```
|
|
1952
|
+
|
|
1953
|
+
An unattributed asserted fact is the worse case: it cannot go stale because it was never tied to anything — it can only be wrong. Report it as a finding, not as a regeneration item.
|
|
1954
|
+
```
|
|
1955
|
+
|
|
1956
|
+
**c. Identify missing AND modified contracts** ✨ ENHANCED:
|
|
1957
|
+
```markdown
|
|
1958
|
+
Missing P1 Contracts (MUST generate):
|
|
1959
|
+
- US1: plugin-lifecycle.md (planStatus=create, new User Story)
|
|
1960
|
+
- US2: connection-manager.md (planStatus=create, new User Story)
|
|
1961
|
+
|
|
1962
|
+
Modified P1 Contracts (MUST regenerate):
|
|
1963
|
+
- US3: multi-view-grid.md (planStatus=update, 4 new FRs added)
|
|
1964
|
+
→ Existing contract exists but needs update for new FRs
|
|
1965
|
+
|
|
1966
|
+
Missing P2 Contracts (SHOULD generate):
|
|
1967
|
+
- US6: authentication-security.md (planStatus=create)
|
|
1968
|
+
|
|
1969
|
+
Missing P3 Contracts (MAY generate):
|
|
1970
|
+
- US4: remote-control-input.md (planStatus=create)
|
|
1971
|
+
|
|
1972
|
+
**Summary**:
|
|
1973
|
+
- Missing: 4 contracts (need initial generation)
|
|
1974
|
+
- Modified: 1 contract (needs regeneration) ⚠️
|
|
1975
|
+
- Total to generate: 5 contracts
|
|
1976
|
+
```
|
|
1977
|
+
|
|
1978
|
+
**d. Report and confirm** ✨ ENHANCED:
|
|
1979
|
+
```markdown
|
|
1980
|
+
## Contract Pre-Generation Coverage Report
|
|
1981
|
+
|
|
1982
|
+
**Current Coverage**:
|
|
1983
|
+
- P1: 67% (2/3) - 1 missing, 1 modified
|
|
1984
|
+
- P2: 0% (0/1) - 1 missing
|
|
1985
|
+
- P3: 0% (0/3) - 1 missing
|
|
1986
|
+
|
|
1987
|
+
**Contracts to Generate**:
|
|
1988
|
+
|
|
1989
|
+
### Missing Contracts (Initial Generation)
|
|
1990
|
+
- [P1] US1: plugin-lifecycle.md (MUST)
|
|
1991
|
+
- [P1] US2: connection-manager.md (MUST)
|
|
1992
|
+
- [P2] US6: authentication-security.md (SHOULD)
|
|
1993
|
+
- [P3] US4: remote-control-input.md (OPTIONAL)
|
|
1994
|
+
|
|
1995
|
+
### Modified Contracts (Regeneration Required) ⚠️
|
|
1996
|
+
- [P1] US3: multi-view-grid.md
|
|
1997
|
+
→ Reason: 4 new FRs added (FR-xxxA~FR-xxxD)
|
|
1998
|
+
→ Impact: New APIs and performance requirements
|
|
1999
|
+
→ Action: Regenerate with new content
|
|
2000
|
+
|
|
2001
|
+
**Action Plan**:
|
|
2002
|
+
1. Generate missing P1 contracts (required)
|
|
2003
|
+
2. Regenerate modified P1 contracts (required) ⚠️ NEW
|
|
2004
|
+
3. Generate missing P2 contracts (recommended)
|
|
2005
|
+
4. Generate P3 contracts (optional, may skip)
|
|
2006
|
+
|
|
2007
|
+
Generate missing + modified P1 + P2 contracts now? (yes/no)
|
|
2008
|
+
```
|
|
2009
|
+
|
|
2010
|
+
**Progress**: 📐 [2/4] Contract pre-validation complete...
|
|
2011
|
+
|
|
2012
|
+
**2.1 Generate ONLY Missing AND Modified Contracts** ✨ ENHANCED:
|
|
2013
|
+
|
|
2014
|
+
**a. Foundational Contracts** (shared infrastructure):
|
|
2015
|
+
```markdown
|
|
2016
|
+
Generate if NOT exists:
|
|
2017
|
+
- plugin-api.md
|
|
2018
|
+
- ui-components.md
|
|
2019
|
+
- wire-protocol.md
|
|
2020
|
+
|
|
2021
|
+
Skip if already exists (preserve existing contracts)
|
|
2022
|
+
```
|
|
2023
|
+
|
|
2024
|
+
**b. Domain-Specific Contracts** (PER USER STORY) ✨ ENHANCED:
|
|
2025
|
+
```markdown
|
|
2026
|
+
Generate contracts identified in Step 2.0.c:
|
|
2027
|
+
|
|
2028
|
+
**Category 1: Missing Contracts** (Initial Generation)
|
|
2029
|
+
For each missing contract (planStatus = "create"):
|
|
2030
|
+
- Extract API surfaces from Functional Requirements
|
|
2031
|
+
- Map acceptance scenarios to contract methods
|
|
2032
|
+
- **Extract performance requirements from quantified FRs**
|
|
2033
|
+
- Define validation rules and edge cases
|
|
2034
|
+
- Create file: specs/contracts/[user-story-name].md
|
|
2035
|
+
|
|
2036
|
+
**Category 2: Modified Contracts** (Regeneration) ⚠️ NEW
|
|
2037
|
+
For each modified contract (planStatus = "update"):
|
|
2038
|
+
- **Backup existing contract**: cp old.md old.md.bak
|
|
2039
|
+
- **Smart merge strategy**:
|
|
2040
|
+
* Preserve: Existing structure, non-obsolete APIs
|
|
2041
|
+
* Update: Add new APIs from new FRs
|
|
2042
|
+
* Update: Add new performance requirements
|
|
2043
|
+
* Remove: Obsolete APIs (if FR deprecated)
|
|
2044
|
+
- **Regenerate**: Create updated contract with merged content
|
|
2045
|
+
- **Validate**: Ensure all new FRs are covered
|
|
2046
|
+
- Overwrite: specs/contracts/[user-story-name].md
|
|
2047
|
+
- Remove backup: rm old.md.bak (if successful)
|
|
2048
|
+
|
|
2049
|
+
**Skip**: Unchanged contracts (planStatus = "processed")
|
|
2050
|
+
```
|
|
2051
|
+
|
|
2052
|
+
**c. Cross-Cutting Contracts** (shared concerns):
|
|
2053
|
+
```markdown
|
|
2054
|
+
Generate for features used by multiple User Stories:
|
|
2055
|
+
- event-bus.md (plugins)
|
|
2056
|
+
- memory-management.md (viewing, grid)
|
|
2057
|
+
```
|
|
2058
|
+
|
|
2059
|
+
**d. Contract Content Requirements**:
|
|
2060
|
+
Each contract MUST include:
|
|
2061
|
+
- **API Signatures**: Method/function signatures with types
|
|
2062
|
+
- **Return Types**: Explicit return types and error conditions
|
|
2063
|
+
- **Performance Requirements** (from spec.md quantified FRs):
|
|
2064
|
+
* Extract: "within 200ms", "<100ms", "30-60 FPS"
|
|
2065
|
+
* Encode as: "MUST complete within X ms" or "MUST maintain Y FPS"
|
|
2066
|
+
|
|
2067
|
+
**Fact-source attribution** 🌐 [MANDATORY for every asserted fact]:
|
|
2068
|
+
|
|
2069
|
+
A contract item is one of two kinds, and the contract MUST make the difference visible:
|
|
2070
|
+
|
|
2071
|
+
| Kind | Examples | Attribution |
|
|
2072
|
+
|------|----------|-------------|
|
|
2073
|
+
| **Design choice** — the contract's own decision | API signatures; decomposition into methods; naming; which codes this implementation advertises; error-message wording | NOT required — the decision is legible as the contract's own |
|
|
2074
|
+
| **Asserted fact** — a claim about how the world is | protocol type codes; field widths; control-byte bit allocation; wire order; version-dependent behaviour; what a peer requires or tolerates; "is/is not supported"; "compatible with X" | **REQUIRED** — a reader must be able to check it without trusting the author |
|
|
2075
|
+
|
|
2076
|
+
The distinction matters because an unattributed assertion is indistinguishable from a guess. A reader cannot tell whether a value was read from a source or recalled — and a wrong value, once in a contract, is copied downstream as though authoritative.
|
|
2077
|
+
|
|
2078
|
+
**Where attribution lives — inline, never in a collected section** ⚠️:
|
|
2079
|
+
|
|
2080
|
+
An attribution MUST sit **immediately above the fact (or fact block) it covers**, in the same section. A collected "sources" table at the end of the file is **not acceptable**: it separates each fact from its source, and that distance is exactly where drift happens — editing one of the two no longer forces addressing the other, so a stale pairing survives review. Inline placement makes the fact/source relation visible at the point of reading and forces both to be touched together.
|
|
2081
|
+
|
|
2082
|
+
**Format**:
|
|
2083
|
+
|
|
2084
|
+
```markdown
|
|
2085
|
+
> Source: <L1 standard §<section> | L2 <implementation> <version> [<file/section>] | L3 <capture: peer + version>>
|
|
2086
|
+
```
|
|
2087
|
+
|
|
2088
|
+
- **Area of effect**: the marker covers the block that immediately follows it, up to the next marker or section heading — one fact list, one table, one code block. A second marker is required when the source changes.
|
|
2089
|
+
- **No marker = no attribution.** A fact block carrying no marker is unattributed by definition — that is the N1 finding, not a formatting preference.
|
|
2090
|
+
- A bare protocol name does not satisfy the marker (see the non-satisfying list below): the marker must reach a section or a versioned implementation.
|
|
2091
|
+
- Where the base standard does not define the detail (sub-encoding layouts, packing rules, continuation chains), the marker MUST point at the authoritative implementation — a standard citation for something the standard omits is itself a finding.
|
|
2092
|
+
|
|
2093
|
+
**Worked example** (the shape generated contracts MUST follow — a table of values, preceded by its source):
|
|
2094
|
+
|
|
2095
|
+
```markdown
|
|
2096
|
+
### Encoding Types
|
|
2097
|
+
|
|
2098
|
+
> Source: L2 <reference implementation> <version> (`src/…/<file>.c`)
|
|
2099
|
+
|
|
2100
|
+
| Type | Meaning |
|
|
2101
|
+
|------|---------|
|
|
2102
|
+
| `0` | Raw |
|
|
2103
|
+
| `1` | Solid |
|
|
2104
|
+
| `2–127` | Palette-coded (`numColors = type + 2`) |
|
|
2105
|
+
```
|
|
2106
|
+
|
|
2107
|
+
Contract prose, reasoning and design decisions need no marker — only facts do.
|
|
2108
|
+
|
|
2109
|
+
**Attribution content** — record the source layer and version.
|
|
2110
|
+
|
|
2111
|
+
The three-layer model is **domain-agnostic** — it is not specific to one protocol. Any domain a contract asserts facts about has the same shape, and the same obligations:
|
|
2112
|
+
|
|
2113
|
+
| Layer | What it is | Protocol example | WebRTC example | Platform-API example |
|
|
2114
|
+
|-------|-----------|------------------|----------------|----------------------|
|
|
2115
|
+
| **L1** | A published standard (numbered, immutable) | the standard, cited by section | RFC 8829 (JSEP), RFC 6716 (Opus) | — (platform APIs are not standardised across vendors) |
|
|
2116
|
+
| **L2** | A named reference implementation, **with version** | the reference implementation, with its version | the deployed peer implementation, per FR-nnn | Windows Graphics Capture API (Windows 10+) |
|
|
2117
|
+
| **L3** | A captured stream from a real peer | a capture from one peer | browser ↔ peer capture | runtime measurement |
|
|
2118
|
+
|
|
2119
|
+
Choose the layer by *where the fact was actually read from*, not by convenience: a fact taken from an implementation's behaviour is L2, even when an L1 standard also exists and says something similar — the two can disagree, and the attribution must name the one that was used. A domain with no L1 coverage (platform APIs) still has L2 and L3 available; what it does not have is the option to assert without either.
|
|
2120
|
+
|
|
2121
|
+
For protocol-bearing claims, `.specpro/templates/protocol-golden-bytes-guide.md` §2 gives the same model in fuller form.
|
|
2122
|
+
|
|
2123
|
+
- An implementation-sourced fact MUST name the implementation **and its version**; without a version the fact is not checkable against a later version of the same source. An immutable published document (a numbered standard) is the one exception: its number *is* its version, so cite it by number and section — `L1 RFC 6143 §7.5.1`. Mutable documents (living specs, vendor docs) follow the implementation rule and MUST carry a version or retrieval date.
|
|
2124
|
+
|
|
2125
|
+
**Sources that do NOT satisfy the requirement**:
|
|
2126
|
+
|
|
2127
|
+
- "common knowledge" / no attribution at all;
|
|
2128
|
+
- an assertion sourced from the implementing code itself — the implementation cannot witness its own correctness (same rule as §2's anchor prohibition);
|
|
2129
|
+
- "obvious" / "standard practice" — these read as claims but cannot be checked;
|
|
2130
|
+
- **a bare protocol name or version** — naming the protocol (or a version of it) identifies *which protocol*, not *which part of it* or *how it was read*. The attribution MUST resolve to a section of the standard, or to a named implementation with its version. A reader given only a protocol name still cannot check the claim without re-deriving it from the whole document.
|
|
2131
|
+
|
|
2132
|
+
**Cross-contract references are acceptable sources — under an audit condition**: a contract may source a fact by pointing at another contract, provided **the referenced section is itself audited** (its own facts carry resolving attributions, and it is covered by the contract-fact audit). A chain that terminates in an unattributed section is not a source — it merely relocates the unverified claim. Where a contract is the designated authority for a fact class (e.g. the wire-protocol contract for message layouts), dependants SHOULD point at that contract's specific section rather than restating the fact, so the fact has one place to be right.
|
|
2133
|
+
|
|
2134
|
+
**Peer-behaviour assertions**: a claim that a named peer requires, tolerates, or rejects something is admissible only with a measured row in the Peer Diversity Registry (see the protocol rules' peer-diversity requirement). Absent that row, record the item as unverified rather than asserting it.
|
|
2135
|
+
|
|
2136
|
+
**From Acceptance Scenarios - API Responses** 🆕:
|
|
2137
|
+
- **For each Happy Path Scenario**:
|
|
2138
|
+
* Success response with all observable results from Independent Test
|
|
2139
|
+
* Response body structure
|
|
2140
|
+
* Status code: 200 or 201
|
|
2141
|
+
|
|
2142
|
+
- **For each Error Scenario**:
|
|
2143
|
+
* Error condition (from scenario)
|
|
2144
|
+
* Error response body:
|
|
2145
|
+
- error: string (specific error code)
|
|
2146
|
+
- message: string (user-friendly message from scenario)
|
|
2147
|
+
- suggested_action: string (actionable suggestion from scenario)
|
|
2148
|
+
* Status code: 400, 401, 403, 404, 408, 423, etc.
|
|
2149
|
+
* Include error recovery guidance if applicable
|
|
2150
|
+
|
|
2151
|
+
- **For each Edge Scenario**:
|
|
2152
|
+
* Special handling response
|
|
2153
|
+
* Constraint validation messages
|
|
2154
|
+
* Boundary condition handling
|
|
2155
|
+
* Status code: 200 (with warning), 206, etc.
|
|
2156
|
+
|
|
2157
|
+
- **For each Permission Scenario**:
|
|
2158
|
+
* Authentication requirements
|
|
2159
|
+
* Authorization checks
|
|
2160
|
+
* Redirect URLs (if applicable)
|
|
2161
|
+
* Status code: 401, 403, 302, etc.
|
|
2162
|
+
|
|
2163
|
+
Example mapping:
|
|
2164
|
+
Scenario: "Given an invalid address is entered, When Connect is clicked, Then a friendly error message appears within 5 seconds"
|
|
2165
|
+
→ Error Response:
|
|
2166
|
+
```json
|
|
2167
|
+
{
|
|
2168
|
+
"error": "CONNECTION_FAILED",
|
|
2169
|
+
"message": "Cannot connect to the server. Please check: 1) the server address, 2) that the server is running, 3) the network connection",
|
|
2170
|
+
"suggested_action": "Verify the server address and network connection, then retry"
|
|
2171
|
+
}
|
|
2172
|
+
```
|
|
2173
|
+
Status: 408 (Request Timeout)
|
|
2174
|
+
|
|
2175
|
+
- **Validation Rules**: Preconditions, postconditions, invariants
|
|
2176
|
+
- **Edge Cases**: Error handling, boundary conditions
|
|
2177
|
+
- **References**: Link to spec.md User Stories and FRs
|
|
2178
|
+
|
|
2179
|
+
**Progress**: 📐 [2.5/4] contracts generated (P1: 100%, P2: 70%, P3: 30%)...
|
|
2180
|
+
|
|
2181
|
+
**3. Post-generation Coverage Validation**:
|
|
2182
|
+
|
|
2183
|
+
**a. Re-calculate coverage**:
|
|
2184
|
+
```markdown
|
|
2185
|
+
After generation:
|
|
2186
|
+
- P1 User Stories: 100% coverage required ✓
|
|
2187
|
+
- P2 User Stories: 70% coverage recommended
|
|
2188
|
+
- P3 User Stories: 30% coverage optional
|
|
2189
|
+
```
|
|
2190
|
+
|
|
2191
|
+
**b. Display final report**:
|
|
2192
|
+
```markdown
|
|
2193
|
+
## Final Contract Coverage Report
|
|
2194
|
+
|
|
2195
|
+
**P1 Coverage**: 100% (3/3) ✅
|
|
2196
|
+
**P2 Coverage**: 70% (1/1) ✅
|
|
2197
|
+
**P3 Coverage**: 33% (1/3) ⚠️
|
|
2198
|
+
|
|
2199
|
+
**Overall**: 87% coverage
|
|
2200
|
+
|
|
2201
|
+
✓ P1 coverage requirement met
|
|
2202
|
+
✓ All performance requirements contract-verified
|
|
2203
|
+
```
|
|
2204
|
+
|
|
2205
|
+
**c. Handle insufficient P1 coverage**:
|
|
2206
|
+
- If P1 < 100%:
|
|
2207
|
+
```markdown
|
|
2208
|
+
❌ P1 Coverage Below 100%
|
|
2209
|
+
|
|
2210
|
+
Missing P1 Contracts:
|
|
2211
|
+
- US1: plugin-lifecycle.md
|
|
2212
|
+
- US2: connection-manager.md
|
|
2213
|
+
|
|
2214
|
+
This violates Constitution Article III (Test-First).
|
|
2215
|
+
Generate missing P1 contracts now? (yes/no)
|
|
2216
|
+
```
|
|
2217
|
+
- If yes: Generate, re-validate
|
|
2218
|
+
- If no: Display warning, continue (user assumes risk)
|
|
2219
|
+
|
|
2220
|
+
**Progress**: 📐 [3/4] Contract coverage validated...
|
|
2221
|
+
|
|
2222
|
+
**4.0 Constitution Gate Evaluation** ✨ NEW (CRITICAL):
|
|
2223
|
+
|
|
2224
|
+
**Purpose**: Evaluate all Constitution violations and reject unjustified ones
|
|
2225
|
+
|
|
2226
|
+
**Progress**: 📐 [3.5/4] Evaluating Constitution gates...
|
|
2227
|
+
|
|
2228
|
+
**Why This Step Is Critical**:
|
|
2229
|
+
- Initial Constitution Check (Step 5.3) was done **before** Phase 1 design
|
|
2230
|
+
- Phase 1 may have introduced new design decisions that violate principles
|
|
2231
|
+
- Must verify all violations have explicit justification
|
|
2232
|
+
- Unjustified violations must be rejected or fixed
|
|
2233
|
+
|
|
2234
|
+
**4.0.a Load Constitution Check**:
|
|
2235
|
+
```markdown
|
|
2236
|
+
Read the `## Constitution Check` section — ⚠️ **它在 `specs/plan-overview.md`,不在 `plan.md`** (T171)
|
|
2237
|
+
Extract all items whose **Status is `❌ FAIL`**
|
|
2238
|
+
```
|
|
2239
|
+
⚠️ **这条闸门读的取值曾是一个没有生产者的字面量**(`T229` ④):它此前写 `Extract all items marked ⚠️ VIOLATION`,而**全工具链没有任何东西产出 `VIOLATION`** —— `grep -rn 'VIOLATION' templates/ commands/`(除本文件外)**零命中**;本命令的 `§5.3.c` 写的是「Document status: **✅ PASS or ❌ FAIL**;**If FAIL: Provide justification**」,`plan-overview-template.md` 的 `## Constitution Check` 写的是「status (**PASS / PARTIAL / FAIL**)」。⇒ 照旧取值提取,**恒为空**,而"没有违规"与"没读到违规"在报告上同形。**取值以 `§5.3` 为准,本处不另立词汇。**
|
|
2240
|
+
⚠️ **`⚠️ PARTIAL` 不归这条闸门**:它不是"违规",而是"设计层面满足、集成层留有缺口" ⇒ 由 **`§5.3.e`** 要求**把层级写明**(原理行与总体行各写一次),不是要一份 justification。
|
|
2241
|
+
|
|
2242
|
+
**4.0.b Evaluate Each Failing Item**:
|
|
2243
|
+
```markdown
|
|
2244
|
+
For each `❌ FAIL` item:
|
|
2245
|
+
1. Check Justification field exists
|
|
2246
|
+
2. Validate Justification completeness:
|
|
2247
|
+
- ✅ Contains "Why" (business justification)
|
|
2248
|
+
- ✅ Contains "Alternatives Considered"
|
|
2249
|
+
- ✅ Contains "Trade-offs"
|
|
2250
|
+
- ✅ Contains "Reversibility"
|
|
2251
|
+
3. If Justification missing or incomplete:
|
|
2252
|
+
- ERROR: "Unjustified violation: [PRINCIPLE_NAME]"
|
|
2253
|
+
- Display violation details
|
|
2254
|
+
- Display what's missing from justification
|
|
2255
|
+
- ABORT or require user confirmation
|
|
2256
|
+
```
|
|
2257
|
+
|
|
2258
|
+
**4.0.c Gate Evaluation Logic** (Pseudo-code):
|
|
2259
|
+
> ⚠️ **围栏是 `text` 而非 `bash`,这是更正不是降级**:本块**自己写着 "(Pseudo-code)"**,而内容里
|
|
2260
|
+
> `for each principle in constitution:` **不是合法 shell**。⇒ 标签与内容不符的是**围栏**,不是内容。
|
|
2261
|
+
> 按 `bash` 标签它会以 shell 的身份受检,而它**从来不是** shell —— 判据的对象是"文档里内嵌的 shell 片段",
|
|
2262
|
+
> 这一块不在其中。⇒ 改为 `text`:**它不再被检,也不再被误读作可执行代码**(`T168`)。
|
|
2263
|
+
```text
|
|
2264
|
+
VIOLATION_COUNT=0
|
|
2265
|
+
UNJUSTIFIED_COUNT=0
|
|
2266
|
+
|
|
2267
|
+
for each principle in constitution:
|
|
2268
|
+
if check_status == "FAIL": # ⚠️ §5.3 产的取值是 PASS / PARTIAL / FAIL —— 此前比的是没有生产者的 "VIOLATION" (T229 ④)
|
|
2269
|
+
VIOLATION_COUNT=$((VIOLATION_COUNT + 1))
|
|
2270
|
+
justification=$(get_justification $principle)
|
|
2271
|
+
|
|
2272
|
+
if is_empty "$justification"; then
|
|
2273
|
+
UNJUSTIFIED_COUNT=$((UNJUSTIFIED_COUNT + 1))
|
|
2274
|
+
echo "❌ FAIL: $principle"
|
|
2275
|
+
echo " Reason: No justification provided"
|
|
2276
|
+
echo " Action: Fix design or provide justification"
|
|
2277
|
+
elif ! is_justification_complete "$justification"; then
|
|
2278
|
+
UNJUSTIFIED_COUNT=$((UNJUSTIFIED_COUNT + 1))
|
|
2279
|
+
echo "❌ FAIL: $principle"
|
|
2280
|
+
echo " Reason: Justification incomplete"
|
|
2281
|
+
echo " Missing: $(get_missing_fields $justification)"
|
|
2282
|
+
echo " Action: Complete justification or fix design"
|
|
2283
|
+
fi
|
|
2284
|
+
fi
|
|
2285
|
+
|
|
2286
|
+
if [ $UNJUSTIFIED_COUNT -gt 0 ]; then
|
|
2287
|
+
echo "❌ GATE EVALUATION FAILED"
|
|
2288
|
+
echo "Found $UNJUSTIFIED_COUNT unjustified violations"
|
|
2289
|
+
echo "Total violations: $VIOLATION_COUNT"
|
|
2290
|
+
echo ""
|
|
2291
|
+
echo "Options:"
|
|
2292
|
+
echo "1. Fix unjustified violations and re-evaluate"
|
|
2293
|
+
echo "2. Provide justifications and re-evaluate"
|
|
2294
|
+
echo "3. Abort and review design"
|
|
2295
|
+
echo ""
|
|
2296
|
+
echo "Your choice (1/2/3):"
|
|
2297
|
+
|
|
2298
|
+
# Read user choice
|
|
2299
|
+
# If 1 or 2: Allow fixes, then re-run gate evaluation
|
|
2300
|
+
# If 3: ABORT workflow
|
|
2301
|
+
exit 1
|
|
2302
|
+
else
|
|
2303
|
+
echo "✅ GATE EVALUATION PASSED"
|
|
2304
|
+
echo "All $VIOLATION_COUNT violations have sufficient justification"
|
|
2305
|
+
echo "Proceeding to next step..."
|
|
2306
|
+
fi
|
|
2307
|
+
```
|
|
2308
|
+
|
|
2309
|
+
**4.0.d Gate Evaluation Result**:
|
|
2310
|
+
```markdown
|
|
2311
|
+
## Constitution Gate Evaluation Result
|
|
2312
|
+
|
|
2313
|
+
**Total Violations**: N
|
|
2314
|
+
**Unjustified Violations**: M
|
|
2315
|
+
|
|
2316
|
+
If M > 0:
|
|
2317
|
+
❌ GATE EVALUATION FAILED
|
|
2318
|
+
Blocking workflow. Fix violations or provide justifications.
|
|
2319
|
+
|
|
2320
|
+
If M = 0:
|
|
2321
|
+
✅ GATE EVALUATION PASSED
|
|
2322
|
+
All violations justified. Proceeding...
|
|
2323
|
+
```
|
|
2324
|
+
|
|
2325
|
+
**Progress**: 📐 [3.75/4] Gate evaluation complete
|
|
2326
|
+
|
|
2327
|
+
---
|
|
2328
|
+
|
|
2329
|
+
**4.1 Re-evaluate Constitution Check** ✨ NEW:
|
|
2330
|
+
|
|
2331
|
+
**Purpose**: After Phase 1 design complete, check for new Constitution violations
|
|
2332
|
+
|
|
2333
|
+
**Progress**: 📐 [3.8/4] Re-evaluating Constitution compliance...
|
|
2334
|
+
|
|
2335
|
+
**Why This Step Is Critical**:
|
|
2336
|
+
- Initial Constitution Check (Step 5.3) was done **before** Phase 1
|
|
2337
|
+
- Phase 1 generated data-model.md and contracts/
|
|
2338
|
+
- These design artifacts may introduce new violations
|
|
2339
|
+
- Must re-evaluate with actual design, not just plan
|
|
2340
|
+
|
|
2341
|
+
**4.1.a Load Design Artifacts**:
|
|
2342
|
+
```markdown
|
|
2343
|
+
Read:
|
|
2344
|
+
- data-model.md (entities, relationships, validation rules)
|
|
2345
|
+
- specs/contracts/*.md (API contracts, error responses, validation)
|
|
2346
|
+
- plan.md Architecture section
|
|
2347
|
+
```
|
|
2348
|
+
|
|
2349
|
+
**4.1.b Re-evaluate Each Principle**:
|
|
2350
|
+
```markdown
|
|
2351
|
+
For each principle in constitution:
|
|
2352
|
+
1. Check initial evaluation (from Step 5.3)
|
|
2353
|
+
2. Evaluate against new design artifacts:
|
|
2354
|
+
- data-model.md: Check entities, relationships
|
|
2355
|
+
- contracts/: Check API responses, error handling
|
|
2356
|
+
- Architecture: Check technology choices
|
|
2357
|
+
3. Compare with initial evaluation
|
|
2358
|
+
4. If status changed:
|
|
2359
|
+
- Document new evaluation
|
|
2360
|
+
- Update the `## Constitution Check` section in `plan-overview.md`
|
|
2361
|
+
5. If new violation found:
|
|
2362
|
+
- Require justification
|
|
2363
|
+
- Add to the `## Constitution Check` section in `plan-overview.md`
|
|
2364
|
+
```
|
|
2365
|
+
|
|
2366
|
+
**4.1.c Re-evaluation Example**:
|
|
2367
|
+
```markdown
|
|
2368
|
+
### II. User Experience & Accessibility
|
|
2369
|
+
|
|
2370
|
+
**Initial Evaluation** (Step 5.3):
|
|
2371
|
+
- Status: ✅ PASS
|
|
2372
|
+
- Reason: "spec.md mentions desktop and mobile support"
|
|
2373
|
+
|
|
2374
|
+
**Re-evaluation after Phase 1**:
|
|
2375
|
+
- Check data-model.md: ✅ No issues
|
|
2376
|
+
- Check contracts/:
|
|
2377
|
+
- ❌ FOUND: Error responses lack user-friendly messages
|
|
2378
|
+
- contracts/connection-manager.md line 45: "error: CONN_FAILED"
|
|
2379
|
+
- Missing: User-friendly message and suggested action
|
|
2380
|
+
- Status: ❌ FAIL
|
|
2381
|
+
- Justification Required:
|
|
2382
|
+
- Why: Technical constraints (error codes mandated by the wire protocol)
|
|
2383
|
+
- Alternatives: Considered mapping table (rejected: too complex)
|
|
2384
|
+
- Trade-offs: Protocol compliance vs UX clarity
|
|
2385
|
+
- Reversibility: Can add client-side mapping later
|
|
2386
|
+
|
|
2387
|
+
**Action**: Update Constitution Check with new violation
|
|
2388
|
+
```
|
|
2389
|
+
|
|
2390
|
+
**4.1.d Update Constitution Check Section**:
|
|
2391
|
+
```markdown
|
|
2392
|
+
If new violations found:
|
|
2393
|
+
1. Add to the `## Constitution Check` section in `specs/plan-overview.md`
|
|
2394
|
+
2. Mark as ❌ FAIL
|
|
2395
|
+
3. Add Justification (if available)
|
|
2396
|
+
4. If no justification:
|
|
2397
|
+
- WARNING: "New violation found, justification required"
|
|
2398
|
+
- Prompt user to provide justification
|
|
2399
|
+
|
|
2400
|
+
If existing violations resolved:
|
|
2401
|
+
1. Update status from ❌ FAIL to ✅ PASS
|
|
2402
|
+
2. Note: "Resolved in Phase 1 design"
|
|
2403
|
+
```
|
|
2404
|
+
|
|
2405
|
+
**4.1.e Re-evaluation Summary**:
|
|
2406
|
+
```markdown
|
|
2407
|
+
## Constitution Re-evaluation Summary
|
|
2408
|
+
|
|
2409
|
+
**Initial Violations**: N (from Step 5.3)
|
|
2410
|
+
**New Violations**: M (found during re-evaluation)
|
|
2411
|
+
**Resolved Violations**: K (fixed during Phase 1)
|
|
2412
|
+
|
|
2413
|
+
**Net Change**: M - K violations
|
|
2414
|
+
|
|
2415
|
+
If M > K:
|
|
2416
|
+
⚠️ WARNING: "Phase 1 introduced $(M-K) new violations"
|
|
2417
|
+
Review new violations and provide justifications
|
|
2418
|
+
|
|
2419
|
+
If M = K:
|
|
2420
|
+
✅ SUCCESS: "No new violations introduced"
|
|
2421
|
+
All design decisions are Constitution-compliant
|
|
2422
|
+
```
|
|
2423
|
+
|
|
2424
|
+
**Progress**: 📐 [3.9/4] Constitution re-evaluation complete
|
|
2425
|
+
|
|
2426
|
+
---
|
|
2427
|
+
|
|
2428
|
+
**4.2 Generate scenarios.md (Acceptance Test Scenarios)** — INITIAL RUN ONLY ✨
|
|
2429
|
+
|
|
2430
|
+
**Condition** ⚠️: run this step **only when `specs/scenarios.md` is absent**. On every later run, skip it and note in the summary: `scenarios.md not touched — refresh with /specpro-scenarios when needed`.
|
|
2431
|
+
|
|
2432
|
+
**Action**: generate it by following `/specpro-scenarios` — that command holds the template, the scenario type-coverage rules, the validation steps and the report format, and it rebuilds the file in full from `spec.md` on every run. **This command keeps no copy of them**: one definition, one owner. Read the `/specpro-scenarios` command document — resolve it by name through the agent's own command resolution, **never by a hardcoded install path** (the install layout is a deployment concern and may change; skills-form installs do not keep the old path) — and execute its Steps 2, 4, 5 and 6 against the scenarios already extracted in Step 2.b of this run.
|
|
2433
|
+
|
|
2434
|
+
**Why the split** ⚠️: `spec.md` keeps evolving after planning ends. While this step was owned by `plan`, the only way to refresh the scenario view was to re-run the whole planning stage — so in practice nobody did, and the file silently aged (a presentation view that nobody re-runs drifts arbitrarily far behind its source, while downstream consumers keep preferring it). Ownership passes to `/specpro-scenarios` the moment this step creates the file; `plan` never rewrites it afterwards.
|
|
2435
|
+
|
|
2436
|
+
**This is the presentation layer, NOT an execution document** — manual scenario execution lives in `specs/manual-test-tasks.md` (via `/specpro-manual-test`); end-user acceptance lives in `specs/acceptance.md` (generated only at the acceptance gate); coverage obligations live in `specs/test-tasks.md` (via `/specpro-test-plan`).
|
|
2437
|
+
|
|
2438
|
+
**Progress**: 📐 [3.95/4] Generating scenarios.md (initial run only)...
|
|
2439
|
+
|
|
2440
|
+
---
|
|
2441
|
+
|
|
2442
|
+
**4.3 Generate quickstart.md (Developer Guide)** ✨ NEW
|
|
2443
|
+
|
|
2444
|
+
**Purpose**: Create developer quickstart guide for environment setup, building, and running
|
|
2445
|
+
|
|
2446
|
+
**Progress**: 📐 [3.99/4] Generating quickstart.md...
|
|
2447
|
+
|
|
2448
|
+
**Why This Step Is Critical**:
|
|
2449
|
+
- Helps new developers get started quickly
|
|
2450
|
+
- Documents environment setup and build process
|
|
2451
|
+
- Provides essential commands for daily development
|
|
2452
|
+
- Reduces onboarding time for contributors
|
|
2453
|
+
|
|
2454
|
+
**Target Audience**:
|
|
2455
|
+
- New developers joining the project
|
|
2456
|
+
- DevOps engineers setting up CI/CD
|
|
2457
|
+
- Contributors building from source
|
|
2458
|
+
- Anyone setting up development environment
|
|
2459
|
+
|
|
2460
|
+
**4.3.a Extract Technical Context**:
|
|
2461
|
+
From plan.md Section "Technical Context":
|
|
2462
|
+
- **Language/Version**: (e.g., Kotlin 1.9.22+, Python 3.11+)
|
|
2463
|
+
- **Primary Dependencies**: (e.g., Compose Multiplatform, Ktor, Django)
|
|
2464
|
+
- **Build System**: (e.g., Gradle, npm, cargo)
|
|
2465
|
+
- **Target Platforms**: (e.g., Android, iOS, Web, Desktop)
|
|
2466
|
+
|
|
2467
|
+
**4.3.b quickstart.md Template**:
|
|
2468
|
+
```markdown
|
|
2469
|
+
# Quick Start Guide: [FEATURE_NAME]
|
|
2470
|
+
|
|
2471
|
+
**Feature**: [feature-name]
|
|
2472
|
+
**Last Updated**: [DATE]
|
|
2473
|
+
**Tech Stack**: [Language] + [Framework]
|
|
2474
|
+
|
|
2475
|
+
## Overview
|
|
2476
|
+
|
|
2477
|
+
This guide provides step-by-step instructions for setting up, building, and running [FEATURE_NAME].
|
|
2478
|
+
|
|
2479
|
+
**Prerequisites**:
|
|
2480
|
+
- [Language/Version] (e.g., Kotlin 1.9.22+)
|
|
2481
|
+
- [Build Tool] (e.g., Gradle 8.5+)
|
|
2482
|
+
- [Platform-specific tools] (e.g., Android Studio, Xcode)
|
|
2483
|
+
|
|
2484
|
+
---
|
|
2485
|
+
|
|
2486
|
+
## Prerequisites
|
|
2487
|
+
|
|
2488
|
+
### Required Software
|
|
2489
|
+
|
|
2490
|
+
| Software | Minimum Version | Recommended | Purpose |
|
|
2491
|
+
|----------|----------------|-------------|---------|
|
|
2492
|
+
| **[Language]** | [min] | [recommended] | Development |
|
|
2493
|
+
| **[Build Tool]** | [min] | [recommended] | Build system |
|
|
2494
|
+
| **[IDE]** | [min] | [recommended] | Development |
|
|
2495
|
+
|
|
2496
|
+
### Platform-Specific Requirements
|
|
2497
|
+
|
|
2498
|
+
[If applicable, list platform-specific requirements]
|
|
2499
|
+
|
|
2500
|
+
---
|
|
2501
|
+
|
|
2502
|
+
## 1. Project Setup
|
|
2503
|
+
|
|
2504
|
+
### Clone Repository
|
|
2505
|
+
|
|
2506
|
+
```bash
|
|
2507
|
+
git clone <repository-url> [project-name]
|
|
2508
|
+
cd [project-name]
|
|
2509
|
+
```
|
|
2510
|
+
|
|
2511
|
+
### Install Dependencies
|
|
2512
|
+
|
|
2513
|
+
```bash
|
|
2514
|
+
[Install command based on build system]
|
|
2515
|
+
# Example for Gradle:
|
|
2516
|
+
./gradlew dependencies
|
|
2517
|
+
|
|
2518
|
+
# Example for npm:
|
|
2519
|
+
npm install
|
|
2520
|
+
|
|
2521
|
+
# Example for Python:
|
|
2522
|
+
pip install -r requirements.txt
|
|
2523
|
+
```
|
|
2524
|
+
|
|
2525
|
+
### Configure Environment
|
|
2526
|
+
|
|
2527
|
+
```bash
|
|
2528
|
+
# Create configuration file
|
|
2529
|
+
cp .env.example .env
|
|
2530
|
+
|
|
2531
|
+
# Edit .env with your settings
|
|
2532
|
+
vim .env
|
|
2533
|
+
```
|
|
2534
|
+
|
|
2535
|
+
---
|
|
2536
|
+
|
|
2537
|
+
## 2. Building the Project
|
|
2538
|
+
|
|
2539
|
+
### Build All Targets
|
|
2540
|
+
|
|
2541
|
+
```bash
|
|
2542
|
+
[Build command]
|
|
2543
|
+
# Example:
|
|
2544
|
+
./gradlew build
|
|
2545
|
+
```
|
|
2546
|
+
|
|
2547
|
+
### Build Specific Platform
|
|
2548
|
+
|
|
2549
|
+
[If applicable]
|
|
2550
|
+
|
|
2551
|
+
**Platform A**:
|
|
2552
|
+
```bash
|
|
2553
|
+
[command]
|
|
2554
|
+
```
|
|
2555
|
+
|
|
2556
|
+
**Platform B**:
|
|
2557
|
+
```bash
|
|
2558
|
+
[command]
|
|
2559
|
+
```
|
|
2560
|
+
|
|
2561
|
+
---
|
|
2562
|
+
|
|
2563
|
+
## 3. Database Setup 🆕 (Conditional)
|
|
2564
|
+
|
|
2565
|
+
> **NOTE**: This section is included ONLY if Technical Context → Storage contains database (SQLDelight, SQLite, PostgreSQL, MySQL)
|
|
2566
|
+
|
|
2567
|
+
### Database Overview
|
|
2568
|
+
|
|
2569
|
+
[FEATURE_NAME] uses [Database Name] for persistent storage.
|
|
2570
|
+
|
|
2571
|
+
**Database Framework**: [e.g., SQLDelight X.Y.Z, SQLAlchemy, Django ORM]
|
|
2572
|
+
|
|
2573
|
+
**Schema Files Location**:
|
|
2574
|
+
```
|
|
2575
|
+
[Path to schema files]
|
|
2576
|
+
# Example:
|
|
2577
|
+
shared/commonMain/sqldelight/com/example/db/
|
|
2578
|
+
├── Plugin.sq
|
|
2579
|
+
├── Connection.sq
|
|
2580
|
+
├── Session.sq
|
|
2581
|
+
└── migrations/
|
|
2582
|
+
├── V1__InitialSchema.sq
|
|
2583
|
+
├── V2__AddPluginAuthorField.sq (schema evolution)
|
|
2584
|
+
└── V3__RenameStatusToState.sq (schema evolution)
|
|
2585
|
+
```
|
|
2586
|
+
|
|
2587
|
+
### Initial Database Setup
|
|
2588
|
+
|
|
2589
|
+
**First-time setup** (creates database from initial schema):
|
|
2590
|
+
|
|
2591
|
+
```bash
|
|
2592
|
+
[Database initialization command]
|
|
2593
|
+
# Example for SQLDelight:
|
|
2594
|
+
./gradlew generateSqlDelightInterface
|
|
2595
|
+
|
|
2596
|
+
# Example for Django:
|
|
2597
|
+
python manage.py migrate
|
|
2598
|
+
|
|
2599
|
+
# Example for Node.js with Prisma:
|
|
2600
|
+
npx prisma migrate dev --name init
|
|
2601
|
+
```
|
|
2602
|
+
|
|
2603
|
+
**Verify database created**:
|
|
2604
|
+
```bash
|
|
2605
|
+
[Verification command]
|
|
2606
|
+
# Example:
|
|
2607
|
+
ls -la .database/data.db
|
|
2608
|
+
# or
|
|
2609
|
+
psql -c "\dt" [database_name]
|
|
2610
|
+
```
|
|
2611
|
+
|
|
2612
|
+
### Schema Evolution (Adding V2, V3 Migrations)
|
|
2613
|
+
|
|
2614
|
+
> **IMPORTANT**: Use "Schema Evolution" terminology, NOT "database migration"
|
|
2615
|
+
|
|
2616
|
+
**When to create schema evolution**:
|
|
2617
|
+
- Adding new field to existing table
|
|
2618
|
+
- Renaming column
|
|
2619
|
+
- Changing data type
|
|
2620
|
+
- Adding new table
|
|
2621
|
+
- Adding index
|
|
2622
|
+
|
|
2623
|
+
**Schema evolution workflow**:
|
|
2624
|
+
```bash
|
|
2625
|
+
# 1. Modify entity in data-model.md
|
|
2626
|
+
# 2. Re-run plan to generate schema evolution migration
|
|
2627
|
+
# 3. New migration file created: V{N}__{Description}.sq
|
|
2628
|
+
|
|
2629
|
+
# Example:
|
|
2630
|
+
# V2__AddPluginAuthorField.sq
|
|
2631
|
+
# V3__RenameStatusToState.sq
|
|
2632
|
+
|
|
2633
|
+
# Apply schema evolution
|
|
2634
|
+
./gradlew generateSqlDelightInterface # Regenerates database code
|
|
2635
|
+
./gradlew migrate # Applies new migrations
|
|
2636
|
+
```
|
|
2637
|
+
|
|
2638
|
+
**Verify schema evolution applied**:
|
|
2639
|
+
```bash
|
|
2640
|
+
[Verification command]
|
|
2641
|
+
# Example:
|
|
2642
|
+
sqlite3 .database/data.db ".schema plugin"
|
|
2643
|
+
```
|
|
2644
|
+
|
|
2645
|
+
### Database Evolution vs Data Migration - Terminology 📖
|
|
2646
|
+
|
|
2647
|
+
**Schema Evolution** (what we do here):
|
|
2648
|
+
- Modifying database schema **within the SAME database system**
|
|
2649
|
+
- Examples: ALTER TABLE ADD COLUMN, RENAME COLUMN, CREATE INDEX
|
|
2650
|
+
- Files: V2__AddField.sq, V3__RenameColumn.sq
|
|
2651
|
+
- Framework: SQLDelight, Flyway, Liquibase
|
|
2652
|
+
|
|
2653
|
+
**Data Migration** (different concept):
|
|
2654
|
+
- Moving data **from ONE database system to ANOTHER**
|
|
2655
|
+
- Examples: Oracle → PostgreSQL, MySQL → SQLite
|
|
2656
|
+
- Tools: ETL tools, custom export/import scripts
|
|
2657
|
+
|
|
2658
|
+
**Do NOT confuse**:
|
|
2659
|
+
- ❌ "Database migration" for adding a field → Use "Schema evolution" instead
|
|
2660
|
+
- ✅ "Database migration" for Oracle → PostgreSQL → Correct usage
|
|
2661
|
+
|
|
2662
|
+
### Common Database Issues
|
|
2663
|
+
|
|
2664
|
+
**Issue**: Schema version mismatch
|
|
2665
|
+
```
|
|
2666
|
+
Error: Schema version 2 required, but version 1 found
|
|
2667
|
+
```
|
|
2668
|
+
**Solution**: Run pending schema evolution migrations
|
|
2669
|
+
```bash
|
|
2670
|
+
./gradlew migrate
|
|
2671
|
+
```
|
|
2672
|
+
|
|
2673
|
+
**Issue**: Foreign key constraint error
|
|
2674
|
+
```
|
|
2675
|
+
Error: FOREIGN KEY constraint failed
|
|
2676
|
+
```
|
|
2677
|
+
**Solution**: Ensure related records exist before inserting
|
|
2678
|
+
|
|
2679
|
+
**Issue**: Migration file not found
|
|
2680
|
+
```
|
|
2681
|
+
Error: V2__AddField.sq not found
|
|
2682
|
+
```
|
|
2683
|
+
**Solution**: Re-run plan to regenerate schema files
|
|
2684
|
+
|
|
2685
|
+
---
|
|
2686
|
+
|
|
2687
|
+
## 4. Running the Application
|
|
2688
|
+
|
|
2689
|
+
### Development Mode
|
|
2690
|
+
|
|
2691
|
+
```bash
|
|
2692
|
+
[Run command]
|
|
2693
|
+
# Example:
|
|
2694
|
+
./gradlew run
|
|
2695
|
+
|
|
2696
|
+
# Example:
|
|
2697
|
+
npm run dev
|
|
2698
|
+
```
|
|
2699
|
+
|
|
2700
|
+
Visit [URL] (e.g., http://localhost:5173)
|
|
2701
|
+
|
|
2702
|
+
### Production Build
|
|
2703
|
+
|
|
2704
|
+
```bash
|
|
2705
|
+
[Build command]
|
|
2706
|
+
# Example:
|
|
2707
|
+
./gradlew assembleRelease
|
|
2708
|
+
npm run build
|
|
2709
|
+
```
|
|
2710
|
+
|
|
2711
|
+
---
|
|
2712
|
+
|
|
2713
|
+
## 5. Development Workflow
|
|
2714
|
+
|
|
2715
|
+
### Run Tests
|
|
2716
|
+
|
|
2717
|
+
```bash
|
|
2718
|
+
[Test command]
|
|
2719
|
+
# Example:
|
|
2720
|
+
./gradlew test
|
|
2721
|
+
|
|
2722
|
+
npm test
|
|
2723
|
+
|
|
2724
|
+
pytest
|
|
2725
|
+
```
|
|
2726
|
+
|
|
2727
|
+
### Code Style
|
|
2728
|
+
|
|
2729
|
+
```bash
|
|
2730
|
+
[Format command]
|
|
2731
|
+
# Example:
|
|
2732
|
+
./gradlew ktlintFormat
|
|
2733
|
+
|
|
2734
|
+
npm run format
|
|
2735
|
+
```
|
|
2736
|
+
|
|
2737
|
+
### Hot Reload
|
|
2738
|
+
|
|
2739
|
+
[Describe hot-reload capabilities]
|
|
2740
|
+
|
|
2741
|
+
---
|
|
2742
|
+
|
|
2743
|
+
## 6. Project Structure
|
|
2744
|
+
|
|
2745
|
+
```
|
|
2746
|
+
[project-name]/
|
|
2747
|
+
├── src/ # Source code
|
|
2748
|
+
├── tests/ # Test files
|
|
2749
|
+
├── docs/ # Documentation
|
|
2750
|
+
├── build.gradle.kts # Build configuration
|
|
2751
|
+
└── README.md # Project overview
|
|
2752
|
+
```
|
|
2753
|
+
|
|
2754
|
+
---
|
|
2755
|
+
|
|
2756
|
+
## 7. Common Issues
|
|
2757
|
+
|
|
2758
|
+
### Issue: [Common problem 1]
|
|
2759
|
+
|
|
2760
|
+
**Solution**: [Fix]
|
|
2761
|
+
|
|
2762
|
+
### Issue: [Common problem 2]
|
|
2763
|
+
|
|
2764
|
+
**Solution**: [Fix]
|
|
2765
|
+
|
|
2766
|
+
---
|
|
2767
|
+
|
|
2768
|
+
## 8. Next Steps
|
|
2769
|
+
|
|
2770
|
+
1. Read the [feature spec](./spec.md) for requirements
|
|
2771
|
+
2. Review the [data model](./data-model.md) for entities
|
|
2772
|
+
3. Check [implementation plan](./plan.md) for architecture
|
|
2773
|
+
4. Start with [first task](./tasks.md)
|
|
2774
|
+
|
|
2775
|
+
---
|
|
2776
|
+
|
|
2777
|
+
## 9. Additional Resources
|
|
2778
|
+
|
|
2779
|
+
- **Documentation**: [link to docs]
|
|
2780
|
+
- **API Reference**: [link to API docs]
|
|
2781
|
+
- **Contributing**: [link to CONTRIBUTING.md]
|
|
2782
|
+
|
|
2783
|
+
---
|
|
2784
|
+
|
|
2785
|
+
**Last Updated**: [DATE]
|
|
2786
|
+
**Status**: Ready for Development
|
|
2787
|
+
```
|
|
2788
|
+
|
|
2789
|
+
**4.3.c Generate File**:
|
|
2790
|
+
```markdown
|
|
2791
|
+
Create file: specs/quickstart.md
|
|
2792
|
+
Content:
|
|
2793
|
+
- Overview and prerequisites
|
|
2794
|
+
- Project setup instructions
|
|
2795
|
+
- Building and running commands
|
|
2796
|
+
- Database setup 🆕 (conditional - only if Storage = SQLDelight/SQLite/PostgreSQL/MySQL)
|
|
2797
|
+
* Database overview
|
|
2798
|
+
* Initial database setup
|
|
2799
|
+
* Schema evolution workflow (V2, V3 migrations)
|
|
2800
|
+
* Database Evolution vs Data Migration terminology
|
|
2801
|
+
* Common database issues
|
|
2802
|
+
- Development workflow
|
|
2803
|
+
- Project structure
|
|
2804
|
+
- Troubleshooting guide
|
|
2805
|
+
- Additional resources
|
|
2806
|
+
```
|
|
2807
|
+
|
|
2808
|
+
**4.3.d Validation**:
|
|
2809
|
+
```markdown
|
|
2810
|
+
After generation:
|
|
2811
|
+
1. Verify all prerequisite software listed
|
|
2812
|
+
2. Check all commands are accurate
|
|
2813
|
+
3. Ensure platform-specific sections included (if applicable)
|
|
2814
|
+
4. Validate build/run commands work
|
|
2815
|
+
5. Confirm database setup section included (if project uses database) 🆕
|
|
2816
|
+
6. Verify schema evolution workflow documented (if applicable) 🆕
|
|
2817
|
+
7. Confirm troubleshooting section covers common issues
|
|
2818
|
+
```
|
|
2819
|
+
|
|
2820
|
+
**Progress**: 📐 [4/4] quickstart.md generated (developer guide)
|
|
2821
|
+
|
|
2822
|
+
---
|
|
2823
|
+
|
|
2824
|
+
**4.4 Agent context check**:
|
|
2825
|
+
Check the AI-agent context file for the detected terminal (`CLAUDE.md` for Claude Code; `AGENTS.md` / `.cursorrules` / equivalent for others). Timing: after plan.md is written — run this check on EVERY `/specpro-plan` run that produces or updates plan.md (NOT limited to the first run; the check is idempotent — equivalent content is left untouched). Logic is inlined here; NO external update script.
|
|
2826
|
+
|
|
2827
|
+
- **a. File missing or empty** → CREATE it from **`.specpro/templates/agent-context-template.md`** (read that file for the full template, rendering rules, and content discipline). Rule summary:
|
|
2828
|
+
* Structural anchors stay in English as written; prose rendered in the project's Artifact Language
|
|
2829
|
+
* The ONLY project-specific content is the Project Overview sentence (application scope + "built with SDD") — the generated file contains NO other project-internal references
|
|
2830
|
+
* The Project Navigation section links `docs/implement/PROJECT_NAVIGATION.md` — **may not exist** (created by `/specpro-implement` up-front or with the first technical document); include it only when the file is present
|
|
2831
|
+
* NO module lists, NO directory trees, NO tech-stack detail — they rot into misinformation, and AI agents can explore the repo / read plan.md themselves. Technology architecture single source: plan.md
|
|
2832
|
+
|
|
2833
|
+
- **b. File exists** → CHECK whether its content is equivalent to **`.specpro/templates/agent-context-template.md`** (project overview with application scope + SDD statement, specpro-workflow coding rules, specs/-as-source-of-truth pointer, Project Navigation when present). Equivalent → leave the file untouched. Entries missing or contradictory → add/fix ONLY those entries; never restructure, never rewrite user-authored content.
|
|
2834
|
+
|
|
2835
|
+
- **c. NEVER append machine-maintained sections** — "Active Technologies" / "Recent Changes" style incremental logs are forbidden. The agent context file stays a thin, human-owned pointer.
|
|
2836
|
+
|
|
2837
|
+
**Progress**: 📐 [4/4] agent context checked (created if missing)
|
|
2838
|
+
|
|
2839
|
+
**Output**:
|
|
2840
|
+
- ✓ data-model.md
|
|
2841
|
+
- ✓ Database schema files (.sq) and migrations 🆕
|
|
2842
|
+
* Schema files: shared/commonMain/sqldelight/com/example/db/*.sq
|
|
2843
|
+
* Initial migration: V1__InitialSchema.sq
|
|
2844
|
+
* Schema evolution files: V2, V3... (if UPDATE_MODE=true)
|
|
2845
|
+
- ✓ specs/contracts/* (P1: 100%, P2: 70%, P3: 30%)
|
|
2846
|
+
- ✓ specs/scenarios.md (N scenarios, M User Stories) ✨ (initial run only — refresh on demand with /specpro-scenarios)
|
|
2847
|
+
- ✓ specs/quickstart.md (developer guide with database setup) ✨ NEW
|
|
2848
|
+
- ✓ agent context file (checked; created if missing)
|
|
2849
|
+
- ✓ Constitution re-evaluated ✨ NEW
|
|
2850
|
+
- ✓ Technical Context updated ✨ NEW
|
|
2851
|
+
|
|
2852
|
+
**Progress**: ✓ Phase 1 complete: All design artifacts generated
|
|
2853
|
+
|
|
2854
|
+
---
|
|
2855
|
+
|
|
2856
|
+
### **Step 7: Update Lifecycle Fields** ✨ ENHANCED
|
|
2857
|
+
|
|
2858
|
+
**Progress**: 📋 [7/8] Updating Lifecycle fields...
|
|
2859
|
+
|
|
2860
|
+
**6.a Update spec.md with new PlanStatus**:
|
|
2861
|
+
```markdown
|
|
2862
|
+
For each processed item in lifecycle_cache.needsProcessing():
|
|
2863
|
+
IF specStatus IN ("create", "update"):
|
|
2864
|
+
- Update planStatus to "processed"
|
|
2865
|
+
- Update tasksStatus to "update" (signals tasks need regeneration)
|
|
2866
|
+
- Format: **Lifecycle**: [specify:create|update][plan:processed][tasks:update]
|
|
2867
|
+
- specifyStatus preserved
|
|
2868
|
+
|
|
2869
|
+
ELSE IF specStatus = "delete":
|
|
2870
|
+
- Ensure planStatus = "deprecated"
|
|
2871
|
+
- Ensure tasksStatus = "delete" ← Keep delete until Tasks processes it
|
|
2872
|
+
- Remove all design content from plan.md
|
|
2873
|
+
- Lifecycle remains: **Lifecycle**: [specify:delete][plan:deprecated][tasks:delete]
|
|
2874
|
+
```
|
|
2875
|
+
|
|
2876
|
+
**6.b Write updated spec.md**:
|
|
2877
|
+
```markdown
|
|
2878
|
+
- Update Lifecycle fields for all processed items
|
|
2879
|
+
- Preserve all other spec content
|
|
2880
|
+
- Atomic write (overwrite entire file)
|
|
2881
|
+
```
|
|
2882
|
+
|
|
2883
|
+
**6.c Handle deprecated items in plan.md**:
|
|
2884
|
+
```markdown
|
|
2885
|
+
Remove all design sections related to deprecated items:
|
|
2886
|
+
- Remove Data Model entities
|
|
2887
|
+
- Remove API contracts
|
|
2888
|
+
- Remove architectural discussions
|
|
2889
|
+
|
|
2890
|
+
Add deprecation notice (if needed):
|
|
2891
|
+
## Deprecated Items
|
|
2892
|
+
The following items were deprecated and removed from the plan:
|
|
2893
|
+
- FR-XXX: [Title] (deprecated in spec v0.X)
|
|
2894
|
+
- USY: [Title] (deprecated in spec v0.X)
|
|
2895
|
+
```
|
|
2896
|
+
|
|
2897
|
+
**Validation**: All processed items have updated planStatus
|
|
2898
|
+
|
|
2899
|
+
---
|
|
2900
|
+
|
|
2901
|
+
### **Step 8: Report & Next Steps** ✨ COMPLETELY REWRITTEN
|
|
2902
|
+
|
|
2903
|
+
**Progress**: 📋 [8/8] Generating completion report...
|
|
2904
|
+
|
|
2905
|
+
#### **7.1 Generated Artifacts Report** ✨ NEW
|
|
2906
|
+
|
|
2907
|
+
```markdown
|
|
2908
|
+
## ✅ Phase 0 & 1 Complete
|
|
2909
|
+
|
|
2910
|
+
### Phase 0: Research
|
|
2911
|
+
- ✅ research.md generated
|
|
2912
|
+
→ Resolved N NEEDS CLARIFICATION items from Technical Context
|
|
2913
|
+
→ Documented technology stack decisions
|
|
2914
|
+
→ Identified best practices for dependencies
|
|
2915
|
+
|
|
2916
|
+
### Phase 1: Design & Contracts
|
|
2917
|
+
- ✅ data-model.md generated
|
|
2918
|
+
→ Defined M entities with relationships
|
|
2919
|
+
→ Documented validation rules
|
|
2920
|
+
→ Specified state transitions
|
|
2921
|
+
|
|
2922
|
+
- ✅ contracts/ generated (P1: 100%, P2: 70%, P3: 30%)
|
|
2923
|
+
→ Generated K new contracts (details below)
|
|
2924
|
+
→ All P1 User Stories covered (100% ✓)
|
|
2925
|
+
→ Performance requirements contract-verified
|
|
2926
|
+
|
|
2927
|
+
- ✅ scenarios.md generated (initial run only — this command never rewrites it again)
|
|
2928
|
+
→ Acceptance test scenarios (Given-When-Then format)
|
|
2929
|
+
→ N scenarios across M User Stories
|
|
2930
|
+
→ Scenario type distribution (Happy, Error, Edge, Permission)
|
|
2931
|
+
→ Related Requirements mapping
|
|
2932
|
+
→ Later refreshes: /specpro-scenarios
|
|
2933
|
+
|
|
2934
|
+
- ✅ quickstart.md generated
|
|
2935
|
+
→ Developer quickstart guide
|
|
2936
|
+
→ Setup instructions
|
|
2937
|
+
→ Build and run commands
|
|
2938
|
+
→ Development workflow
|
|
2939
|
+
→ Troubleshooting guide
|
|
2940
|
+
|
|
2941
|
+
- ✅ Agent context checked
|
|
2942
|
+
→ CLAUDE.md or agent-specific file
|
|
2943
|
+
→ created if missing (thin pointer: application scope + SDD statement + specs/ links)
|
|
2944
|
+
→ left untouched when equivalent content already present
|
|
2945
|
+
→ no incremental log sections ever (legacy behavior removed)
|
|
2946
|
+
|
|
2947
|
+
### Plan.md Structure
|
|
2948
|
+
⚠️ **This list is `specs/plan.md` (Part I, machine-read) ONLY** — `T229` ①。它此前混进了三个**属于 `plan-overview.md`(Part II)**的节名,而 `§5.8` 的 **Check 1b** 明令它们 **MUST NOT** 出现在 `plan.md` 里:照那份清单核对,会把一份**违规的**产物判成合规。子节集合的**真源是 `templates/plan-template.md`**(`grep -nE '^#{2,3} ' templates/plan-template.md`),本清单只列**节的种类**、不重述其内容。
|
|
2949
|
+
- ✅ Technical Context (9 fields)
|
|
2950
|
+
- ✅ Quality Targets (Project Type Classification · Risk-Based Coverage Targets · Risk Classification · Constitution Compliance · Quality Validation Strategy) —— ⚠️ **此前整节漏列**,而它是 `tasks` §4.j-2 的**机器输入**(每 FR 的风险等级就从这里读)。
|
|
2951
|
+
- ✅ Architecture — **4 个无条件子节**:Layered Architecture · Component Interaction · Architecture Patterns · Critical Constraints;**另有 3 个条件子节**(有宪法条款 / 构建与声明不一致 / 激活门为 ACTIVE 时才产):Shared/Platform Boundary Declaration · Shared-Layer Relocation Design · Protocol Codec Design Artifacts。
|
|
2952
|
+
- ✅ Project Structure (docs + source code)
|
|
2953
|
+
- ✅ Deprecated Items (Z items)
|
|
2954
|
+
|
|
2955
|
+
**MUST NOT appear in `plan.md`**(均为 `plan-overview.md` 的节,`§5.8` Check 1b):
|
|
2956
|
+
- 🅷 Summary · 🅷 Constitution Check · 🅷 Implementation Plan · 🅷 Complexity Tracking
|
|
2957
|
+
⚠️ **`Constitution Check` 尤其容易写错**:它是 §5.3 的产物、且 `Step 4.0` 的宪法门要读它 —— 但**读的位置是 `specs/plan-overview.md`**(`T171`)。把它放进 `plan.md` 既违规,也会让那个门去读一份不存在的东西。
|
|
2958
|
+
|
|
2959
|
+
### Lifecycle Updates
|
|
2960
|
+
- ✅ N items: planStatus "create" → "processed", tasksStatus → "update"
|
|
2961
|
+
- ✅ M items: planStatus "update" → "processed", tasksStatus → "update"
|
|
2962
|
+
- ✅ Z items: planStatus → "deprecated", tasksStatus → "deprecated"
|
|
2963
|
+
- ✅ K items: Preserved with [x] marking (already processed)
|
|
2964
|
+
|
|
2965
|
+
**Files Modified**:
|
|
2966
|
+
- specs/spec.md (Lifecycle fields updated)
|
|
2967
|
+
- specs/plan.md (incrementally updated)
|
|
2968
|
+
- specs/research.md (generated)
|
|
2969
|
+
- specs/data-model.md (generated)
|
|
2970
|
+
- specs/contracts/* (K contracts generated)
|
|
2971
|
+
- specs/quickstart.md (generated)
|
|
2972
|
+
- [agent-specific context file] (updated)
|
|
2973
|
+
```
|
|
2974
|
+
|
|
2975
|
+
#### **7.2 Next Options** ✨ NEW (CLEAR USER GUIDANCE)
|
|
2976
|
+
|
|
2977
|
+
```markdown
|
|
2978
|
+
**Upstream status reconciliation** ⚠️ [MANDATORY before any "ready to continue" — Constraint 6 / FR-045]
|
|
2979
|
+
|
|
2980
|
+
**"Ready to continue" is a claim about the whole chain, not about the stage speaking.** So
|
|
2981
|
+
before this report states any "can continue / ready" conclusion, it MUST **read** each upstream
|
|
2982
|
+
stage's pending status on the entries that stage produced, and **state** what it found. The
|
|
2983
|
+
over-declaration this replaces: `/specpro-tasks` closed with "✅ Ready to continue
|
|
2984
|
+
implementation" while the design side had not taken a single step (`specs/plan.md` → Constraint 6).
|
|
2985
|
+
|
|
2986
|
+
**Two things, neither optional**:
|
|
2987
|
+
|
|
2988
|
+
1. **Say it when the status is clean too.** "Nothing was mentioned" and "nothing is pending"
|
|
2989
|
+
are different statements, and the first cannot be told apart from "forgot to look".
|
|
2990
|
+
2. **Skipped and processed counts are listed separately** — never merged into one "handled" number.
|
|
2991
|
+
|
|
2992
|
+
**Report shape** — every upstream gets a line, **including when it has nothing pending**
|
|
2993
|
+
(indented, not fenced: several of these blocks sit inside an enclosing fence, and a nested
|
|
2994
|
+
fence would close the outer one early):
|
|
2995
|
+
|
|
2996
|
+
Upstream reconciliation (Constraint 6)
|
|
2997
|
+
<upstream>: N pending · M processed
|
|
2998
|
+
Verdict: <clear to continue | upstream debts listed above>
|
|
2999
|
+
|
|
3000
|
+
⚠️ **Report — do not block.** The mechanism self-heals: an upstream that completes marks its
|
|
3001
|
+
downstream `update`. Blocking would need a judgement of "what counts as a debt", and that
|
|
3002
|
+
judgement *is* the downstream reading its upstreams — reporting is its only legitimate form.
|
|
3003
|
+
|
|
3004
|
+
⚠️ **Copied verbatim across `specpro.{specify,plan,tasks,test-plan,test-implement}.md`** (five
|
|
3005
|
+
sites; do not exist as one because each command document is deployed and read on its own).
|
|
3006
|
+
Only the "This stage's upstreams" line below differs per file — **change all five together**.
|
|
3007
|
+
|
|
3008
|
+
**This stage's upstreams**: `specify` — pending means an entry's `[plan: ]` marker is not
|
|
3009
|
+
`processed`, or an entry was not yet broken down.
|
|
3010
|
+
|
|
3011
|
+
## 🎯 Next Steps
|
|
3012
|
+
|
|
3013
|
+
Your planning phase is complete! Choose your next action:
|
|
3014
|
+
|
|
3015
|
+
### Option 1: Continue Planning (Recommended) ⭐
|
|
3016
|
+
Generate detailed Implementation Plan (Phase 2-7) with breakdown of all deliverables.
|
|
3017
|
+
|
|
3018
|
+
```bash
|
|
3019
|
+
/specpro-plan --continue
|
|
3020
|
+
```
|
|
3021
|
+
|
|
3022
|
+
**What this does**:
|
|
3023
|
+
- Expands Phase 2-7 with detailed deliverables
|
|
3024
|
+
- Creates comprehensive timeline with milestones
|
|
3025
|
+
- Adds risk management and mitigation strategies
|
|
3026
|
+
- Suitable for: Large projects, team coordination, project management
|
|
3027
|
+
|
|
3028
|
+
**Estimated time**: 5-10 minutes
|
|
3029
|
+
|
|
3030
|
+
---
|
|
3031
|
+
|
|
3032
|
+
### Option 2: Start Task Breakdown (Fast Track) ⚡
|
|
3033
|
+
Skip detailed planning, directly break down User Stories into actionable tasks.
|
|
3034
|
+
|
|
3035
|
+
```bash
|
|
3036
|
+
/specpro-tasks
|
|
3037
|
+
```
|
|
3038
|
+
|
|
3039
|
+
**What this does**:
|
|
3040
|
+
- Breaks User Stories into dependency-ordered tasks
|
|
3041
|
+
- Creates tasks.md with T001, T002, etc.
|
|
3042
|
+
- Identifies critical path and parallel opportunities
|
|
3043
|
+
- Suitable for: Small to medium projects, individual developers
|
|
3044
|
+
|
|
3045
|
+
**Estimated time**: 3-5 minutes
|
|
3046
|
+
|
|
3047
|
+
---
|
|
3048
|
+
|
|
3049
|
+
### Option 3: Review & Adjust (Manual) 🔍
|
|
3050
|
+
Review generated artifacts before proceeding.
|
|
3051
|
+
|
|
3052
|
+
```bash
|
|
3053
|
+
# Review the plan
|
|
3054
|
+
cat specs/plan.md
|
|
3055
|
+
|
|
3056
|
+
# Review technical decisions
|
|
3057
|
+
cat specs/research.md
|
|
3058
|
+
|
|
3059
|
+
# Review contracts
|
|
3060
|
+
ls specs/contracts/
|
|
3061
|
+
cat specs/contracts/plugin-lifecycle.md
|
|
3062
|
+
|
|
3063
|
+
# Review data model
|
|
3064
|
+
cat specs/data-model.md
|
|
3065
|
+
```
|
|
3066
|
+
|
|
3067
|
+
**After review**:
|
|
3068
|
+
- If satisfied: Choose Option 1 or Option 2
|
|
3069
|
+
- If adjustments needed: Update specs manually, then re-run `/specpro-plan`
|
|
3070
|
+
|
|
3071
|
+
**Estimated time**: 5-15 minutes (depending on depth of review)
|
|
3072
|
+
|
|
3073
|
+
---
|
|
3074
|
+
|
|
3075
|
+
### Recommended Path 🎯
|
|
3076
|
+
|
|
3077
|
+
Based on your project profile:
|
|
3078
|
+
- **Project Size**: Large (50+ FRs, 7 User Stories)
|
|
3079
|
+
- **Team**: Multi-person (needs coordination)
|
|
3080
|
+
- **Complexity**: High (plugin architecture, cross-platform)
|
|
3081
|
+
|
|
3082
|
+
**Recommended**:
|
|
3083
|
+
```
|
|
3084
|
+
1. Review artifacts (Option 3) - 10 minutes
|
|
3085
|
+
→ Verify technical decisions in research.md
|
|
3086
|
+
→ Check contract coverage meets requirements
|
|
3087
|
+
→ Confirm Architecture section reflects your vision
|
|
3088
|
+
|
|
3089
|
+
2. Continue planning (Option 1) - 10 minutes
|
|
3090
|
+
→ /specpro-plan --continue
|
|
3091
|
+
→ Generate detailed Phase 2-7 plan
|
|
3092
|
+
→ Review milestones and timeline
|
|
3093
|
+
|
|
3094
|
+
3. Break down tasks (Option 2) - 5 minutes
|
|
3095
|
+
→ /specpro-tasks
|
|
3096
|
+
→ Generate actionable task list
|
|
3097
|
+
→ Start implementation
|
|
3098
|
+
```
|
|
3099
|
+
|
|
3100
|
+
**Total estimated time**: 25 minutes to full task breakdown
|
|
3101
|
+
```
|
|
3102
|
+
|
|
3103
|
+
#### **7.3 Verification Checklist** ✨ NEW (QUALITY GATE)
|
|
3104
|
+
|
|
3105
|
+
```markdown
|
|
3106
|
+
## ✓ Pre-Continuation Verification
|
|
3107
|
+
|
|
3108
|
+
Before proceeding to Option 1, 2, or 3, verify:
|
|
3109
|
+
|
|
3110
|
+
### Critical Items (MUST verify)
|
|
3111
|
+
- [ ] **research.md resolved all NEEDS CLARIFICATION**
|
|
3112
|
+
→ Check Technical Context in plan.md
|
|
3113
|
+
→ All fields should have values (not "NEEDS CLARIFICATION")
|
|
3114
|
+
|
|
3115
|
+
- [ ] **contracts/ covers all P1 User Stories (100%)**
|
|
3116
|
+
→ 判据:把 `spec.md` 里 **P1** 的 US 逐个拿来,在 `specs/contracts/` 里找到**点名了它**的契约。
|
|
3117
|
+
⚠️ **此前这里写的是一条测不到该结论的命令**(`grep -c "P1" specs/contracts/*.md`):它数的是
|
|
3118
|
+
"契约文件里出现过 `P1` 这个字符串"——**既不知道有几个 P1 US,也不知道谁没被覆盖**,
|
|
3119
|
+
返回一个非零计数就"通过"了。**一条与它所声称的结论无关的判据,与没有判据同形**(T171)。
|
|
3120
|
+
|
|
3121
|
+
- [ ] **data-model.md defines all key entities**
|
|
3122
|
+
→ Check entity count matches spec.md Data Model Entities FRs (FR-xxx~FR-yyy)
|
|
3123
|
+
→ Relationships documented
|
|
3124
|
+
|
|
3125
|
+
- [ ] **Constitution Check has no ❌ FAIL** (or risk explicitly accepted)
|
|
3126
|
+
→ Review the `## Constitution Check` section in `specs/plan-overview.md` (not plan.md)
|
|
3127
|
+
→ If ❌ FAIL present, ensure risk was explicitly accepted
|
|
3128
|
+
|
|
3129
|
+
### Recommended Items (should verify)
|
|
3130
|
+
- [ ] **Architecture section reflects technical approach**
|
|
3131
|
+
→ System Overview matches your vision
|
|
3132
|
+
→ Technology Decisions align with your stack
|
|
3133
|
+
|
|
3134
|
+
- [ ] **Implementation Plan phases are realistic**
|
|
3135
|
+
→ Estimates (weeks) seem achievable
|
|
3136
|
+
→ Dependencies are correctly identified
|
|
3137
|
+
|
|
3138
|
+
- [ ] **Deprecated Items are correctly handled**
|
|
3139
|
+
→ If Z > 0, review Deprecated Items section
|
|
3140
|
+
→ Confirm migration paths are documented
|
|
3141
|
+
|
|
3142
|
+
### Optional Items (nice to verify)
|
|
3143
|
+
- [ ] **quickstart.md is accurate for your environment**
|
|
3144
|
+
- [ ] **Agent context file is a thin pointer** (application scope + SDD statement; NO stale module/tech lists)
|
|
3145
|
+
- [ ] **Project Structure matches your repository layout**
|
|
3146
|
+
|
|
3147
|
+
---
|
|
3148
|
+
|
|
3149
|
+
## ✅ Ready to Proceed? — **only after the upstream reconciliation above**
|
|
3150
|
+
|
|
3151
|
+
⚠️ "Ready to proceed" is a claim about the **chain**, not about this planning stage
|
|
3152
|
+
(Constraint 6 / FR-045). Before offering the choice below, **state** each upstream stage's
|
|
3153
|
+
pending status — **including when it has none** (silence cannot be told apart from
|
|
3154
|
+
"forgot to look"), with skipped and processed counts listed separately.
|
|
3155
|
+
|
|
3156
|
+
If all critical items verified, choose your next option:
|
|
3157
|
+
|
|
3158
|
+
**1.** /specpro-plan --continue (Generate detailed plan)
|
|
3159
|
+
**2.** /specpro-tasks (Break down into tasks)
|
|
3160
|
+
**3.** I'll review first (Manual review)
|
|
3161
|
+
|
|
3162
|
+
Your choice (1/2/3):
|
|
3163
|
+
```
|
|
3164
|
+
|
|
3165
|
+
#### **7.4 Execution Time Summary** ✨ NEW (PERFORMANCE MONITORING):
|
|
3166
|
+
|
|
3167
|
+
```markdown
|
|
3168
|
+
## ⏱️ Execution Summary
|
|
3169
|
+
|
|
3170
|
+
**Command**: /specpro-plan
|
|
3171
|
+
**Duration**: [TOTAL_TIME]
|
|
3172
|
+
**Timestamp**: [YYYY-MM-DD HH:MM:SS]
|
|
3173
|
+
|
|
3174
|
+
**Items Processed**:
|
|
3175
|
+
- New items: N (planStatus "create" → "processed", tasksStatus → "update")
|
|
3176
|
+
- Modified items: M (planStatus "update" → "processed", tasksStatus → "update")
|
|
3177
|
+
- Deprecated items: Z (planStatus → "deprecated", tasksStatus → "deprecated")
|
|
3178
|
+
- Skipped items: K (Already processed, preserved)
|
|
3179
|
+
|
|
3180
|
+
**Files Modified**:
|
|
3181
|
+
- specs/spec.md (Lifecycle fields)
|
|
3182
|
+
- specs/plan.md (incrementally updated)
|
|
3183
|
+
- specs/research.md (generated)
|
|
3184
|
+
- specs/data-model.md (generated/updated)
|
|
3185
|
+
- specs/contracts/* (K contracts)
|
|
3186
|
+
- specs/quickstart.md (generated)
|
|
3187
|
+
|
|
3188
|
+
**Performance Breakdown**:
|
|
3189
|
+
```
|
|
3190
|
+
┌──────────────────────────┬─────────────┬──────────────┐
|
|
3191
|
+
│ Step │ Time │ Percentage │
|
|
3192
|
+
├──────────────────────────┼─────────────┼──────────────┤
|
|
3193
|
+
│ Pre-flight Checks │ [T1] │ [P1]% │
|
|
3194
|
+
│ Load context files │ [T2] │ [P2]% │
|
|
3195
|
+
│ Quality gate │ [T3] │ [P3]% │
|
|
3196
|
+
│ Lifecycle parsing │ [T4] │ [P4]% │
|
|
3197
|
+
│ Phase 0 (Research) │ [T5] │ [P5]% │
|
|
3198
|
+
│ Phase 1 (Design) │ [T6] │ [P6]% │
|
|
3199
|
+
│ Lifecycle field updates │ [T7] │ [P7]% │
|
|
3200
|
+
│ Report generation │ [T8] │ [P8]% │
|
|
3201
|
+
└──────────────────────────┴─────────────┴──────────────┘
|
|
3202
|
+
```
|
|
3203
|
+
|
|
3204
|
+
**Bottlenecks**:
|
|
3205
|
+
- Slowest step: [STEP_NAME] ([TIME])
|
|
3206
|
+
- Recommendation: [OPTIMIZATION_SUGGESTION]
|
|
3207
|
+
|
|
3208
|
+
**Memory Usage**:
|
|
3209
|
+
- Lifecycle cache: [SIZE] items
|
|
3210
|
+
- Peak memory: ~[PEAK_MEMORY]
|
|
3211
|
+
|
|
3212
|
+
**Next Run Optimization**:
|
|
3213
|
+
- Incremental mode: YES (only 4 items to process)
|
|
3214
|
+
- Estimated next run time: [ESTIMATED_TIME]
|
|
3215
|
+
- Time saved: ~[SAVED_TIME] vs full regeneration
|
|
3216
|
+
```
|
|
3217
|
+
|
|
3218
|
+
**Benefits**:
|
|
3219
|
+
- ✅ Observable execution time
|
|
3220
|
+
- ✅ Performance bottleneck identification
|
|
3221
|
+
- ✅ Quantified optimization effects
|
|
3222
|
+
- ✅ Estimated next run time
|
|
3223
|
+
|
|
3224
|
+
## Phases (Reference)
|
|
3225
|
+
|
|
3226
|
+
### Phase 0: Research & Technology
|
|
3227
|
+
- Resolve NEEDS CLARIFICATION from Technical Context
|
|
3228
|
+
- Document technology stack decisions
|
|
3229
|
+
- Identify best practices
|
|
3230
|
+
|
|
3231
|
+
### Phase 1: Design & Contracts
|
|
3232
|
+
- Generate data-model.md
|
|
3233
|
+
- Generate API contracts (P1: 100%, P2: 70%, P3: 30%)
|
|
3234
|
+
- Check agent context (create if missing; never incrementally rewrite)
|
|
3235
|
+
|
|
3236
|
+
### Phase 2-7: Implementation Planning (via --continue)
|
|
3237
|
+
- Phase 2: Core Infrastructure
|
|
3238
|
+
- Phase 3: Core Plugins (P1)
|
|
3239
|
+
- Phase 4: Feature Plugins (P2)
|
|
3240
|
+
- Phase 5: Feature Plugins (P3)
|
|
3241
|
+
- Phase 6: Platform Integration
|
|
3242
|
+
- Phase 7: Testing & Hardening
|
|
3243
|
+
|
|
3244
|
+
---
|
|
3245
|
+
|
|
3246
|
+
## Key Rules ✨ OPTIMIZED
|
|
3247
|
+
|
|
3248
|
+
- ✅ **Fail Fast**: Pre-flight checks catch issues early
|
|
3249
|
+
- ✅ **One-Time Read**: Load Lifecycle once, cache for reuse
|
|
3250
|
+
- ✅ **Incremental Updates**: Only process PlanStatus != "Processed"
|
|
3251
|
+
- ✅ **Clear Next Steps**: Explicit guidance after Phase 2
|
|
3252
|
+
- ✅ **Quality Gates**: Clarifications + Checklist validation
|
|
3253
|
+
- ✅ **Contract Optimization**: Generate only missing contracts
|
|
3254
|
+
- ✅ **Progress Visibility**: Clear indicators throughout
|
|
3255
|
+
- ✅ **Error Recovery**: Max 3 clarification attempts, manual intervention after
|
|
3256
|
+
|
|
3257
|
+
---
|
|
3258
|
+
|
|
3259
|
+
## Optimization Benefits
|
|
3260
|
+
|
|
3261
|
+
| Metric | Before | After | Improvement |
|
|
3262
|
+
|--------|--------|-------|-------------|
|
|
3263
|
+
| **Setup reliability** | 85% | 99% (+14%) | Pre-flight catches issues |
|
|
3264
|
+
| **Incremental update speed** | Baseline | 20-30% faster | One-time Lifecycle read |
|
|
3265
|
+
| **Contract generation** | All regenerated | Only missing | Avoids redundant work |
|
|
3266
|
+
| **User clarity** | Unclear next steps | Explicit options | Reduced confusion |
|
|
3267
|
+
| **Error recovery** | Infinite loops | Max 3 attempts | Prevents hang |
|
|
3268
|
+
|
|
3269
|
+
---
|
|
3270
|
+
|
|
3271
|
+
**Status**: ✅ OPTIMIZED VERSION READY
|
|
3272
|
+
**Version**: 2.0
|
|
3273
|
+
**Last Updated**: 2026-01-28
|
|
3274
|
+
|
|
3275
|
+
---
|
|
3276
|
+
|
|
3277
|
+
## Protocol Codec Module Rules 🌐 [CONDITIONAL — wire-format / protocol modules only]
|
|
3278
|
+
|
|
3279
|
+
**Activation**: decided by the **Activation Gate** (`.specpro/templates/protocol-golden-bytes-guide.md` §6) — triggers T3/T4 (the design encodes/decodes a byte stream, or interoperates with a peer over a wire format). Consume the verdict recorded by `specify` (§6.4) rather than re-judging it; if this stage finds a trigger the earlier stage missed, record the discrepancy as a finding — do not silently override. Do not infer the gate from the presence of a network or a client/server split: those are transport, not wire format. When activated, the design output MUST contain the three items below, plus the verdict row.
|
|
3280
|
+
|
|
3281
|
+
- **Protocol-point inventory** (design output): field- and branch-level enumeration — control-byte bit semantics, run-length extension chains, bit-packing order, payload byte-count branches, stream lifecycle. Granularity is the branch, not the message type: message-level tests pass while a branch-level defect stays latent. Semantics that are ambiguous in prose (extension chains, packing order, control-byte bits) MUST be recorded as **byte-level examples**, not by name. Format: `.specpro/templates/protocol-golden-bytes-guide.md` §1.
|
|
3282
|
+
- **Golden-bytes strategy** (three-layer cross-anchoring): L1 specification (structure) → L2 reference-implementation source (bit-level semantics) → L3 captured stream (final arbitration). Every anchor records its source layer and the protocol version it came from; when the layers conflict, L3 wins and the corrected understanding is written back. An anchor whose source cannot be reached is recorded as a **GAP** (§6.3) — never as an invented byte sequence. See `.specpro/templates/protocol-golden-bytes-guide.md` §2.
|
|
3283
|
+
- **Stream-semantics comparison** (MANDATORY when one client speaks several encoders): produce a comparison of the stream semantics across the codecs that client supports — a continuous single stream in one codec vs an independent per-message stream in another. Its purpose is to stop a fix's lesson from being carried across codecs whose semantics are opposite.
|
|
3284
|
+
|