mindsystem-cc 4.4.0 → 4.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -8
- package/agents/ms-compounder.md +19 -7
- package/agents/ms-consolidator.md +11 -1
- package/commands/ms/config.md +23 -2
- package/commands/ms/doctor.md +1 -1
- package/commands/ms/help.md +3 -1
- package/commands/ms/new-milestone.md +8 -3
- package/mindsystem/references/knowledge-quality.md +89 -0
- package/mindsystem/templates/knowledge.md +18 -3
- package/package.json +1 -1
- package/scripts/ms-tools.py +186 -25
- package/mindsystem/workflows/transition.md +0 -460
package/README.md
CHANGED
|
@@ -2,21 +2,44 @@
|
|
|
2
2
|
|
|
3
3
|

|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
# Mindsystem
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
npx mindsystem-cc
|
|
9
|
-
```
|
|
7
|
+
Amplifies every step of the development workflow you already follow.
|
|
10
8
|
|
|
11
9
|
[](https://www.npmjs.com/package/mindsystem-cc)
|
|
10
|
+
[](https://www.npmjs.com/package/mindsystem-cc)
|
|
12
11
|
[](LICENSE)
|
|
12
|
+
[](https://docs.anthropic.com/en/docs/claude-code)
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
Discovery, research, design, planning, execution, verification — each one refined, parallelized, and compounded into persistent knowledge. Built for lean teams and solo builders who want to multiply their output without giving up control.
|
|
15
|
+
|
|
16
|
+
[Quick start](#quick-start) · [Walkthrough](#end-to-end-walkthrough) · [Features](#features) · [Commands](#command-reference)
|
|
15
17
|
|
|
16
18
|
</div>
|
|
17
19
|
|
|
18
20
|
---
|
|
19
21
|
|
|
22
|
+
## Quick start
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npx mindsystem-cc
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Then `/ms:new-project` to initialize. See the [full walkthrough](#end-to-end-walkthrough) for the complete feature-building loop, or `/ms:progress` to pick up where you left off.
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## What's new in v4.4
|
|
33
|
+
|
|
34
|
+
- **Knowledge quality gate** — consolidator and compounder filter extracted knowledge through signal density enforcement, eliminating noise entries that wouldn't change how an LLM implements code.
|
|
35
|
+
- **User journey browser verification** — end-to-end click/fill/submit testing instead of screenshot-only observation. Catches unreachable pages with no navigation path from the UI.
|
|
36
|
+
- **Single-plan mode (default)** — one plan per phase, eliminating multi-agent orchestration overhead with 1M context windows.
|
|
37
|
+
- **Full phase specification** for add-phase and insert-phase — both commands now derive goal, success criteria, and requirements mapping.
|
|
38
|
+
|
|
39
|
+
See [CHANGELOG.md](CHANGELOG.md) for the complete history.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
20
43
|
## Why Mindsystem
|
|
21
44
|
|
|
22
45
|
Fully autonomous coding tools take a spec and run until a product emerges. That works for prototypes. Mindsystem takes the opposite approach — it follows the workflow a thorough engineer already uses, and amplifies each step:
|
|
@@ -87,7 +110,7 @@ Execution happens in fresh subagent contexts, so each plan gets up to 200k token
|
|
|
87
110
|
|
|
88
111
|
### Project setup
|
|
89
112
|
|
|
90
|
-
Before building features, initialize the project once with `/ms:new-project`. For existing codebases, also run `/ms:map-codebase` (analyzes your stack, conventions, and architecture into 7 structured documents) and `/ms:doctor` (validates config and generates per-subsystem knowledge files from source code). See [
|
|
113
|
+
Before building features, initialize the project once with `/ms:new-project`. For existing codebases, also run `/ms:map-codebase` (analyzes your stack, conventions, and architecture into 7 structured documents) and `/ms:doctor` (validates config and generates per-subsystem knowledge files from source code). See [Getting started](#getting-started) for the exact sequences.
|
|
91
114
|
|
|
92
115
|
Everything below is the feature-building loop, identical for new and existing projects.
|
|
93
116
|
|
|
@@ -277,6 +300,10 @@ Requirements you want but haven't shipped yet are tracked in `PROJECT.md` with o
|
|
|
277
300
|
|
|
278
301
|
`/ms:add-todo` with Linear-inspired metadata: priority (1-4), estimate (XS-XL), inferred subsystem. Todos live as flat files in `.planning/todos/`. Address them later via `/ms:adhoc`, which reads the problem description, executes the work, and moves the todo to `done/`.
|
|
279
302
|
|
|
303
|
+
### Task tracker integration
|
|
304
|
+
|
|
305
|
+
Configure a Linear connection via `/ms:config` and pass ticket IDs directly to `/ms:adhoc` (e.g., `/ms:adhoc MIN-123`). The system auto-fetches the ticket's title and description as work context, tags commits with the ticket ID, and on completion posts a solution summary, attaches the commit, and marks the ticket done. Zero overhead when unconfigured — the integration is lazy-loaded only when a ticket ID is detected.
|
|
306
|
+
|
|
280
307
|
### Codebase mapping
|
|
281
308
|
|
|
282
309
|
`/ms:map-codebase` spawns 4 parallel agents producing 7 structured documents: stack, architecture, conventions, testing, integrations, directory structure, and concerns. Use on brownfield projects so Mindsystem respects your existing patterns.
|
|
@@ -297,7 +324,7 @@ Requirements you want but haven't shipped yet are tracked in `PROJECT.md` with o
|
|
|
297
324
|
|
|
298
325
|
---
|
|
299
326
|
|
|
300
|
-
##
|
|
327
|
+
## Getting started
|
|
301
328
|
|
|
302
329
|
### Project setup (one-time)
|
|
303
330
|
|
|
@@ -324,6 +351,7 @@ Once the project is set up, the workflow is the same for new and existing codeba
|
|
|
324
351
|
```
|
|
325
352
|
/ms:new-milestone # Discover what to build next
|
|
326
353
|
/ms:create-roadmap # Define requirements, map to phases
|
|
354
|
+
/ms:discuss-phase 1 # Gather context before planning
|
|
327
355
|
/ms:plan-phase 1 # Create detailed plan
|
|
328
356
|
/ms:execute-phase 1 # Run in fresh subagents
|
|
329
357
|
/ms:verify-work 1 # Manual acceptance testing
|
|
@@ -498,7 +526,7 @@ Full docs live in `/ms:help`.
|
|
|
498
526
|
| `/ms:execute-phase <number>` | Run all unexecuted plans in fresh subagents |
|
|
499
527
|
| `/ms:verify-work [number]` | Batched manual UAT with inline fixes |
|
|
500
528
|
| `/ms:debug [description]` | Structured debugging that survives `/clear` |
|
|
501
|
-
| `/ms:adhoc <description>` | Knowledge-aware execution for discovered work |
|
|
529
|
+
| `/ms:adhoc <description>` | Knowledge-aware execution for discovered work or Linear ticket IDs |
|
|
502
530
|
| `/ms:compound [input]` | Compound out-of-pipeline changes into knowledge files |
|
|
503
531
|
| `/ms:add-phase <description>` | Append a new phase to the roadmap |
|
|
504
532
|
| `/ms:insert-phase <after> <description>` | Insert urgent work between phases |
|
package/agents/ms-compounder.md
CHANGED
|
@@ -25,6 +25,10 @@ You are a Mindsystem knowledge compounder spawned by the compound workflow to up
|
|
|
25
25
|
|
|
26
26
|
</inputs>
|
|
27
27
|
|
|
28
|
+
<references>
|
|
29
|
+
@~/.claude/mindsystem/references/knowledge-quality.md
|
|
30
|
+
</references>
|
|
31
|
+
|
|
28
32
|
<extraction_guide>
|
|
29
33
|
|
|
30
34
|
## What to Extract From Raw Changes
|
|
@@ -59,15 +63,19 @@ ls .planning/knowledge/*.md 2>/dev/null
|
|
|
59
63
|
|
|
60
64
|
Read only the files matching confirmed affected subsystems. On first run, `.planning/knowledge/` may not exist — start fresh.
|
|
61
65
|
|
|
62
|
-
## Step 3: Extract Knowledge From Changes
|
|
66
|
+
## Step 3: Classify and Extract Knowledge From Changes
|
|
67
|
+
|
|
68
|
+
Classify each change signal before extraction:
|
|
63
69
|
|
|
64
|
-
|
|
70
|
+
| Signal Type | Action |
|
|
71
|
+
|------------|--------|
|
|
72
|
+
| Decision with rationale (chose X over Y because Z) | Extract |
|
|
73
|
+
| Structural pattern (how components connect, data flows) | Extract |
|
|
74
|
+
| Non-obvious pitfall or gotcha | Extract |
|
|
75
|
+
| Code-derivable detail (schema fields, component props, config values) | Skip |
|
|
76
|
+
| Implementation description without alternative considered | Skip |
|
|
65
77
|
|
|
66
|
-
|
|
67
|
-
- **Decisions with rationale** — not just "used X" but "used X because Y"
|
|
68
|
-
- **Structural patterns** — how components connect, data flows, API contracts
|
|
69
|
-
- **Gotchas discovered** — failure modes, workarounds, non-obvious behavior
|
|
70
|
-
- **Significant file changes** — new entry points, renamed modules, deleted code
|
|
78
|
+
Apply the extraction guide to change content that passes classification. Then apply the knowledge-quality.md filtering test — drop entries that fail. For entries that pass, check existing knowledge files for cross-subsystem duplication — use `(see {subsystem})` cross-references instead of duplicating.
|
|
71
79
|
|
|
72
80
|
## Step 4: Merge Into Existing Knowledge
|
|
73
81
|
|
|
@@ -81,6 +89,8 @@ For each affected subsystem, edit the knowledge file to reflect current state:
|
|
|
81
89
|
|
|
82
90
|
Use `Edit` for existing files — targeted changes preserve content you haven't inspected. Use `Write` only for new files (subsystem has no knowledge file yet).
|
|
83
91
|
|
|
92
|
+
While merging, review the touched file's existing entries through the same quality gate. Remove entries that are now code-derivable, superseded by new decisions, or duplicated in another subsystem's knowledge file. This is opportunistic maintenance during normal writes, not a full audit.
|
|
93
|
+
|
|
84
94
|
## Step 5: Update Knowledge Files and Return Report
|
|
85
95
|
|
|
86
96
|
```bash
|
|
@@ -142,4 +152,6 @@ If changes suggest a subsystem not in the confirmed list, note it as a proposal
|
|
|
142
152
|
- [ ] Report returned with update counts
|
|
143
153
|
- [ ] Empty sections omitted from knowledge files
|
|
144
154
|
- [ ] Existing knowledge files read for affected subsystems only
|
|
155
|
+
- [ ] Extracted entries pass the knowledge-quality.md filtering test
|
|
156
|
+
- [ ] No cross-subsystem duplication (cross-references used instead)
|
|
145
157
|
</success_criteria>
|
|
@@ -41,6 +41,10 @@ You are a Mindsystem knowledge consolidator spawned by execute-phase after plan
|
|
|
41
41
|
|
|
42
42
|
</inputs>
|
|
43
43
|
|
|
44
|
+
<references>
|
|
45
|
+
@~/.claude/mindsystem/references/knowledge-quality.md
|
|
46
|
+
</references>
|
|
47
|
+
|
|
44
48
|
<extraction_guide>
|
|
45
49
|
|
|
46
50
|
## What to Extract Per Artifact
|
|
@@ -68,7 +72,7 @@ You are a Mindsystem knowledge consolidator spawned by execute-phase after plan
|
|
|
68
72
|
| DESIGN Content | Target Knowledge Section |
|
|
69
73
|
|----------------|------------------------|
|
|
70
74
|
| Wireframe layouts, inline annotations | Design |
|
|
71
|
-
| Design
|
|
75
|
+
| Design reasoning (why this approach, not pixel values) | Design |
|
|
72
76
|
| Behavior notes, interaction patterns | Design |
|
|
73
77
|
| States tables, platform hints | Design |
|
|
74
78
|
|
|
@@ -135,6 +139,8 @@ Apply the extraction guide to each artifact:
|
|
|
135
139
|
|
|
136
140
|
Extract knowledge, not descriptions. "Using React" is not knowledge. "Using React over Vue because of ecosystem maturity and team familiarity" is knowledge.
|
|
137
141
|
|
|
142
|
+
Apply the knowledge-quality.md filtering test to each extracted entry before assigning it to a subsystem. Drop entries that fail. For entries that pass, check existing knowledge files for cross-subsystem duplication — use `(see {subsystem})` cross-references instead of duplicating.
|
|
143
|
+
|
|
138
144
|
## Step 6: Merge Into Knowledge Files
|
|
139
145
|
|
|
140
146
|
For each affected subsystem, edit the knowledge file to reflect current state:
|
|
@@ -147,6 +153,8 @@ For each affected subsystem, edit the knowledge file to reflect current state:
|
|
|
147
153
|
|
|
148
154
|
Use `Edit` for existing files — targeted changes preserve content you haven't inspected. Use `Write` only for new files (subsystem has no knowledge file yet).
|
|
149
155
|
|
|
156
|
+
While merging, review the touched file's existing entries through the same quality gate. Remove entries that are now code-derivable, superseded by new decisions, or duplicated in another subsystem's knowledge file. This is opportunistic maintenance during normal writes, not a full audit.
|
|
157
|
+
|
|
150
158
|
## Step 7: Update Knowledge Files
|
|
151
159
|
|
|
152
160
|
```bash
|
|
@@ -225,5 +233,7 @@ Use `+N` for new entries added, `updated` for sections rewritten with changes, `
|
|
|
225
233
|
- [ ] Empty sections omitted from knowledge files
|
|
226
234
|
- [ ] PLAN.md files deleted from phase directory
|
|
227
235
|
- [ ] CONTEXT.md, DESIGN.md, RESEARCH.md, SUMMARY.md preserved
|
|
236
|
+
- [ ] Extracted entries pass the knowledge-quality.md filtering test
|
|
237
|
+
- [ ] No cross-subsystem duplication (cross-references used instead)
|
|
228
238
|
- [ ] No commits made
|
|
229
239
|
</success_criteria>
|
package/commands/ms/config.md
CHANGED
|
@@ -53,7 +53,7 @@ git remote -v 2>/dev/null || echo "NO_REMOTE"
|
|
|
53
53
|
2. **Code reviewers** — adhoc: {value or "not set"}, phase: {value or "not set"}, milestone: {value or "not set"}
|
|
54
54
|
3. **Gitignore** — {current .planning/ patterns or "no .planning/ patterns"}
|
|
55
55
|
4. **Mockups** — open: {auto / ask / off}
|
|
56
|
-
5. **Browser verification** — {enabled / disabled}
|
|
56
|
+
5. **Browser verification** — {enabled / disabled}, web project: {yes / no / auto-detect}
|
|
57
57
|
6. **Plan mode** — {single plan (default) / multi-plan}
|
|
58
58
|
7. **Task tracker** — {type + cli path, or "none"}
|
|
59
59
|
```
|
|
@@ -198,9 +198,30 @@ Map selection:
|
|
|
198
198
|
Update config.json:
|
|
199
199
|
|
|
200
200
|
```bash
|
|
201
|
-
ms-tools config-set browser_verification --json '
|
|
201
|
+
ms-tools config-set browser_verification.enabled --json 'true' # or false
|
|
202
202
|
```
|
|
203
203
|
|
|
204
|
+
**If enabled**, detect and confirm web project status:
|
|
205
|
+
|
|
206
|
+
```bash
|
|
207
|
+
ms-tools detect-web
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Present the auto-detection result via AskUserQuestion:
|
|
211
|
+
- header: "Web project detection"
|
|
212
|
+
- question: "Is this a web project with a browser-renderable UI? Auto-detection returned: {detected result}"
|
|
213
|
+
- options:
|
|
214
|
+
- "Yes — this is a web project" (recommended if detected)
|
|
215
|
+
- "No — this is not a web project"
|
|
216
|
+
- "Auto-detect (don't persist)" — remove any existing override
|
|
217
|
+
|
|
218
|
+
Map selection:
|
|
219
|
+
- "Yes" → `ms-tools config-set browser_verification.web_project --json 'true'`
|
|
220
|
+
- "No" → `ms-tools config-set browser_verification.web_project --json 'false'`
|
|
221
|
+
- "Auto-detect" → `ms-tools config-delete browser_verification.web_project`
|
|
222
|
+
|
|
223
|
+
**If disabled**, skip the web_project question.
|
|
224
|
+
|
|
204
225
|
</step>
|
|
205
226
|
|
|
206
227
|
<step name="multi_plan">
|
package/commands/ms/doctor.md
CHANGED
|
@@ -145,7 +145,7 @@ If "Review each" → use AskUserQuestion for each failed check with its details
|
|
|
145
145
|
|
|
146
146
|
Apply fixes in dependency order: fix_subsystems → fix_milestone_dirs → fix_milestone_naming → fix_phase_archival → fix_plan_cleanup → fix_phase_dirs → fix_knowledge. Skip any fix whose check passed or was skipped by user.
|
|
147
147
|
|
|
148
|
-
Phase summaries are resolved by fix_phase_archival. CLI wrapper failures have specific fixes: bin dir not in PATH → restart Claude Code session; missing wrappers or bin dir → re-run `npx mindsystem-cc`; uv not found → `curl -LsSf https://astral.sh/uv/install.sh | sh`. WARN checks (Research API Keys, missing uv) are informational — no automated fix, only displayed in the report.
|
|
148
|
+
Phase summaries are resolved by fix_phase_archival. CLI wrapper failures have specific fixes: bin dir not in PATH → restart Claude Code session; missing wrappers or bin dir → re-run `npx mindsystem-cc`; uv not found → `curl -LsSf https://astral.sh/uv/install.sh | sh`. WARN checks (Research API Keys, missing uv) are informational — no automated fix, only displayed in the report. Research API Keys check provides platform-aware setup guidance (shell export on macOS/Linux, settings.json on Windows) and checks both environment variables and `~/.claude/settings.json` env section as fallback.
|
|
149
149
|
</step>
|
|
150
150
|
|
|
151
151
|
<step name="apply_fixes">
|
package/commands/ms/help.md
CHANGED
|
@@ -108,7 +108,7 @@ Initialize new project with brief and configuration.
|
|
|
108
108
|
Usage: `/ms:new-project`
|
|
109
109
|
|
|
110
110
|
**`/ms:config`**
|
|
111
|
-
Configure Mindsystem preferences — code reviewers, mockup preferences, browser verification, plan mode, gitignore patterns, git remote.
|
|
111
|
+
Configure Mindsystem preferences — code reviewers, mockup preferences, browser verification, plan mode, gitignore patterns, git remote, task tracker.
|
|
112
112
|
|
|
113
113
|
- Use when: you want to set up code review agents, mockup open behavior, manage which .planning/ artifacts are git-ignored, or push your repo to GitHub.
|
|
114
114
|
- Edits `.planning/config.json` and `.gitignore`
|
|
@@ -366,11 +366,13 @@ Execute discovered work with knowledge-aware planning and execution.
|
|
|
366
366
|
- Use when: you discover work mid-session that can be completed in a single context window without multi-phase orchestration.
|
|
367
367
|
- Bridges the gap between `/ms:add-todo` (capture for later) and `/ms:insert-phase` (multi-plan coordination)
|
|
368
368
|
- Knowledge-aware: loads relevant knowledge files before planning, consolidates learnings after execution
|
|
369
|
+
- Accepts Linear ticket IDs when task tracker is configured via `/ms:config` — auto-fetches context, tags commits, and finalizes the ticket on completion
|
|
369
370
|
- Spawns Explore agents for codebase understanding, ms-adhoc-planner for plan creation, ms-executor for execution
|
|
370
371
|
- Creates per-execution artifacts in `.planning/adhoc/{timestamp}-{slug}/`
|
|
371
372
|
- Updates knowledge files via ms-consolidator after execution
|
|
372
373
|
|
|
373
374
|
Usage: `/ms:adhoc Fix auth token not refreshing on 401`
|
|
375
|
+
Usage: `/ms:adhoc MIN-123` (Linear ticket — auto-fetches context, finalizes on completion)
|
|
374
376
|
Usage: `/ms:adhoc Refactor API error handling to use consistent format`
|
|
375
377
|
|
|
376
378
|
### Utility Commands
|
|
@@ -276,7 +276,9 @@ Milestone name: $ARGUMENTS (optional — will emerge during discovery if not pro
|
|
|
276
276
|
|
|
277
277
|
19. **Route to next step:**
|
|
278
278
|
|
|
279
|
-
|
|
279
|
+
Determine primary suggestion:
|
|
280
|
+
- Default: `/ms:research-milestone` — domain research improves roadmap quality for most milestones
|
|
281
|
+
- Only `/ms:create-roadmap` when domain is clearly familiar, no open questions surfaced, and no external APIs, new libraries, or unfamiliar patterns
|
|
280
282
|
|
|
281
283
|
```
|
|
282
284
|
Milestone [Name] initialized.
|
|
@@ -289,17 +291,20 @@ Milestone name: $ARGUMENTS (optional — will emerge during discovery if not pro
|
|
|
289
291
|
|
|
290
292
|
## ▶ Next Up
|
|
291
293
|
|
|
292
|
-
`/ms:
|
|
294
|
+
`/ms:{suggested}` — [one-line reason from conversation]
|
|
293
295
|
|
|
294
296
|
<sub>`/clear` first → fresh context window</sub>
|
|
295
297
|
|
|
296
298
|
---
|
|
297
299
|
|
|
298
|
-
**Also available:**
|
|
300
|
+
**Also available:**
|
|
301
|
+
- `/ms:{alternative}` — [brief reason]
|
|
299
302
|
|
|
300
303
|
---
|
|
301
304
|
```
|
|
302
305
|
|
|
306
|
+
`{suggested}` and `{alternative}` are always one of: `research-milestone`, `create-roadmap`.
|
|
307
|
+
|
|
303
308
|
</process>
|
|
304
309
|
|
|
305
310
|
<success_criteria>
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
<knowledge_quality>
|
|
2
|
+
|
|
3
|
+
Shared quality gate for knowledge extraction. Referenced by ms-consolidator and ms-compounder agents.
|
|
4
|
+
|
|
5
|
+
<filtering_principle>
|
|
6
|
+
|
|
7
|
+
**The single test:** "Would an LLM implement this incorrectly without this entry?"
|
|
8
|
+
|
|
9
|
+
If yes — the entry earns its place. If an LLM with access to the codebase would get it right anyway, the entry is noise.
|
|
10
|
+
|
|
11
|
+
What passes the test:
|
|
12
|
+
- Conventions that differ from LLM defaults or framework norms
|
|
13
|
+
- Failed experiments and why they failed (prevents re-discovery)
|
|
14
|
+
- Non-obvious bugs, gotchas, or workarounds
|
|
15
|
+
- Decisions where the alternative was reasonable (the "because" matters)
|
|
16
|
+
- Cross-cutting patterns not visible from a single file
|
|
17
|
+
|
|
18
|
+
</filtering_principle>
|
|
19
|
+
|
|
20
|
+
<fails_the_test>
|
|
21
|
+
|
|
22
|
+
These categories consistently fail the filtering test. Drop them during extraction.
|
|
23
|
+
|
|
24
|
+
| Category | Why It Fails | Example |
|
|
25
|
+
|----------|-------------|---------|
|
|
26
|
+
| Design tokens (colors, spacing, typography) | Readable from code/config files | "Primary: #6366F1, spacing-md: 16px" |
|
|
27
|
+
| Component API descriptions | Readable from component source | "SubscriptionCard accepts `plan`, `onSelect` props" |
|
|
28
|
+
| Schema/model field listings | Readable from schema files | "User has fields: id, email, name, createdAt" |
|
|
29
|
+
| Version pins without rationale | Readable from package.json/lockfile | "Using React 18.2.0" |
|
|
30
|
+
| Decisions without alternatives | No "because" = no reusable knowledge | "Using Tailwind for styling" (vs. what?) |
|
|
31
|
+
| Implementation descriptions | Restates what the code does | "Login endpoint hashes password and returns JWT" |
|
|
32
|
+
|
|
33
|
+
</fails_the_test>
|
|
34
|
+
|
|
35
|
+
<passes_the_test>
|
|
36
|
+
|
|
37
|
+
Concrete examples that earn their place — each would cause incorrect implementation without the entry.
|
|
38
|
+
|
|
39
|
+
1. **FieldMask casing (gRPC):** FieldMask paths must use camelCase in JSON, not snake_case — proto3 JSON mapping silently drops snake_case paths. LLMs default to snake_case matching proto definitions.
|
|
40
|
+
|
|
41
|
+
2. **keepAlive auto-dispose (Flutter):** Riverpod providers with `keepAlive()` in `autoDispose` family providers — calling `keepAlive()` inside `ref.onDispose` creates a retain cycle. Dispose callback never fires, provider leaks. Place `keepAlive()` in the provider body before any async gap.
|
|
42
|
+
|
|
43
|
+
3. **HiveField index stability:** HiveField indices are permanent storage keys — changing an index silently corrupts existing user data. New fields must use the next unused index, never reuse or reorder.
|
|
44
|
+
|
|
45
|
+
4. **do/while pagination (API):** Firestore `startAfter` cursor pagination requires do/while, not while — a while loop with an empty-page exit condition misses the last partial page when `limit` equals page size exactly.
|
|
46
|
+
|
|
47
|
+
5. **Payment timeout (Stripe):** Stripe webhook delivery retries for up to 72 hours. Payment confirmation UI must show "processing" state, not assume success/failure within a session.
|
|
48
|
+
|
|
49
|
+
6. **Interceptor ordering (Dio):** Dio interceptors run in addition order for requests but reverse order for responses/errors. Auth token injection must be added first to run last on error (so retry logic sees the refreshed token).
|
|
50
|
+
|
|
51
|
+
</passes_the_test>
|
|
52
|
+
|
|
53
|
+
<decision_quality_test>
|
|
54
|
+
|
|
55
|
+
Not every decision is knowledge. Apply this secondary filter:
|
|
56
|
+
|
|
57
|
+
**"Could a reasonable agent have chosen differently?"**
|
|
58
|
+
|
|
59
|
+
- **Pass:** "jose over jsonwebtoken — better TypeScript types and actively maintained" → Yes, jsonwebtoken is the more common choice. The rationale prevents revisiting.
|
|
60
|
+
- **Pass:** "httpOnly cookies over localStorage for JWT — XSS prevention" → Yes, localStorage is the LLM default. Without this entry, an LLM would likely use localStorage.
|
|
61
|
+
- **Fail:** "Using TypeScript for type safety" → No reasonable agent would choose plain JS for a new project. This is a default, not a decision.
|
|
62
|
+
- **Fail:** "Using ESLint for linting" → No alternative was seriously considered. Not knowledge.
|
|
63
|
+
|
|
64
|
+
</decision_quality_test>
|
|
65
|
+
|
|
66
|
+
<cross_subsystem_dedup>
|
|
67
|
+
|
|
68
|
+
Before writing an entry, check whether it already exists in another subsystem's knowledge file.
|
|
69
|
+
|
|
70
|
+
- If the entry belongs primarily to another subsystem, add a cross-reference: `(see {subsystem})` instead of duplicating.
|
|
71
|
+
- If the entry spans multiple subsystems equally, place it in the most upstream subsystem and cross-reference from others.
|
|
72
|
+
- If an existing duplicate is found during extraction, remove it from the less-relevant file and cross-reference.
|
|
73
|
+
|
|
74
|
+
</cross_subsystem_dedup>
|
|
75
|
+
|
|
76
|
+
<existing_content_review>
|
|
77
|
+
|
|
78
|
+
On every write to a knowledge file, review the touched file's existing entries:
|
|
79
|
+
|
|
80
|
+
- **Still relevant?** Remove entries for features/patterns that no longer exist.
|
|
81
|
+
- **Code-derivable now?** Remove entries that were non-obvious when written but are now self-evident from the codebase (e.g., a pattern that was novel is now standard in the project).
|
|
82
|
+
- **Superseded?** Update or remove entries contradicted by new decisions.
|
|
83
|
+
- **Duplicated?** Check against other knowledge files — deduplicate using cross-references.
|
|
84
|
+
|
|
85
|
+
This is opportunistic maintenance during normal writes, not a full audit.
|
|
86
|
+
|
|
87
|
+
</existing_content_review>
|
|
88
|
+
|
|
89
|
+
</knowledge_quality>
|
|
@@ -30,8 +30,8 @@ Template for `.planning/knowledge/{subsystem}.md` — per-subsystem knowledge fi
|
|
|
30
30
|
|
|
31
31
|
## Design
|
|
32
32
|
|
|
33
|
-
- {
|
|
34
|
-
- {
|
|
33
|
+
- {Design reasoning — why this approach, not alternatives}
|
|
34
|
+
- {Interaction pattern that differs from LLM defaults}
|
|
35
35
|
|
|
36
36
|
## Pitfalls
|
|
37
37
|
|
|
@@ -54,7 +54,7 @@ Template for `.planning/knowledge/{subsystem}.md` — per-subsystem knowledge fi
|
|
|
54
54
|
|---------|----------|-----------------|
|
|
55
55
|
| **Decisions** | Choices with rationale (the "because" part) | CONTEXT.md locked decisions, RESEARCH.md recommendations, PLAN.md approach rationale, SUMMARY.md key-decisions |
|
|
56
56
|
| **Architecture** | How the subsystem works, structural patterns | RESEARCH.md architecture patterns, PLAN.md implementation details, SUMMARY.md accomplishments |
|
|
57
|
-
| **Design** |
|
|
57
|
+
| **Design** | Design reasoning, non-obvious interaction patterns (reasoning only — not tokens or values readable from code) | DESIGN.md wireframe layouts, states tables, behavior notes |
|
|
58
58
|
| **Pitfalls** | What to watch out for, operational patterns | RESEARCH.md common pitfalls, SUMMARY.md issues/deviations, debug resolutions, adhoc learnings |
|
|
59
59
|
| **Key Files** | Important file paths for this subsystem | SUMMARY.md key-files, PLAN.md file targets |
|
|
60
60
|
|
|
@@ -96,4 +96,19 @@ The cross-reference is navigational, not essential. Each file is self-contained
|
|
|
96
96
|
- Fixed a bug in auth (description, not a reusable pattern)
|
|
97
97
|
- Missing import in login.ts (trivial, not worth persisting)
|
|
98
98
|
|
|
99
|
+
## What Doesn't Belong
|
|
100
|
+
|
|
101
|
+
Apply this test to every entry: **"Would an LLM implement this incorrectly without this entry?"** If the answer is no, the entry is noise.
|
|
102
|
+
|
|
103
|
+
Categories that consistently fail the test:
|
|
104
|
+
|
|
105
|
+
- **Design tokens** (colors, spacing, typography) — readable from code/config files
|
|
106
|
+
- **Component API descriptions** — readable from component source
|
|
107
|
+
- **Schema/model field listings** — readable from schema files
|
|
108
|
+
- **Version pins without rationale** — readable from package.json/lockfile
|
|
109
|
+
- **Decisions without alternatives** — no "because" = no reusable knowledge ("Using Tailwind" vs. what?)
|
|
110
|
+
- **Implementation descriptions** — restates what the code does
|
|
111
|
+
|
|
112
|
+
**Decision quality test:** "Could a reasonable agent have chosen differently?" If no, it's a default, not a decision. "Using TypeScript for type safety" fails. "jose over jsonwebtoken for better TypeScript types" passes — jsonwebtoken is the more common choice.
|
|
113
|
+
|
|
99
114
|
</guidelines>
|
package/package.json
CHANGED
package/scripts/ms-tools.py
CHANGED
|
@@ -614,6 +614,18 @@ def _get_claude_config_dir() -> Path:
|
|
|
614
614
|
return Path.home() / ".claude"
|
|
615
615
|
|
|
616
616
|
|
|
617
|
+
def _get_settings_env_var(key: str) -> str:
|
|
618
|
+
"""Read an env var from ~/.claude/settings.json env section."""
|
|
619
|
+
settings_path = _get_claude_config_dir() / "settings.json"
|
|
620
|
+
if not settings_path.is_file():
|
|
621
|
+
return ""
|
|
622
|
+
try:
|
|
623
|
+
settings = json.loads(settings_path.read_text(encoding="utf-8"))
|
|
624
|
+
return settings.get("env", {}).get(key, "")
|
|
625
|
+
except (json.JSONDecodeError, OSError):
|
|
626
|
+
return ""
|
|
627
|
+
|
|
628
|
+
|
|
617
629
|
WEB_FRAMEWORK_DEPS = {
|
|
618
630
|
"react", "react-dom", "vue", "next", "nuxt", "@angular/core",
|
|
619
631
|
"svelte", "@sveltejs/kit", "solid-js", "astro", "@remix-run/react",
|
|
@@ -625,6 +637,25 @@ WEB_CONFIG_FILES = [
|
|
|
625
637
|
"svelte.config.*", "astro.config.*", "remix.config.*",
|
|
626
638
|
]
|
|
627
639
|
|
|
640
|
+
SERVERSIDE_FRAMEWORK_FILES = [
|
|
641
|
+
"artisan", # Laravel
|
|
642
|
+
"config.ru", # Ruby Rack (Rails, Sinatra)
|
|
643
|
+
"wp-config.php", # WordPress
|
|
644
|
+
"wp-config-sample.php", # WordPress (fresh install)
|
|
645
|
+
]
|
|
646
|
+
|
|
647
|
+
SERVERSIDE_COMPOSER_DEPS = {
|
|
648
|
+
"yiisoft/yii2", "yiisoft/yii", "laravel/framework",
|
|
649
|
+
"symfony/framework-bundle", "symfony/symfony",
|
|
650
|
+
"cakephp/cakephp", "codeigniter4/framework",
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
SERVERSIDE_GEMFILE_KEYWORDS = ["rails", "sinatra"]
|
|
654
|
+
|
|
655
|
+
SERVERSIDE_PYTHON_KEYWORDS = ["django", "flask", "fastapi"]
|
|
656
|
+
|
|
657
|
+
SERVERSIDE_PYTHON_FILES = ["requirements.txt", "pyproject.toml", "Pipfile"]
|
|
658
|
+
|
|
628
659
|
|
|
629
660
|
def _detect_web_project(git_root: Path) -> tuple[bool, str]:
|
|
630
661
|
"""Detect if project is a web project. Returns (is_web, signal_description)."""
|
|
@@ -645,6 +676,46 @@ def _detect_web_project(git_root: Path) -> tuple[bool, str]:
|
|
|
645
676
|
if list(git_root.glob(pattern)):
|
|
646
677
|
return True, f"{pattern} found"
|
|
647
678
|
|
|
679
|
+
# Signal 2b: Server-side framework marker files
|
|
680
|
+
for marker in SERVERSIDE_FRAMEWORK_FILES:
|
|
681
|
+
if (git_root / marker).is_file():
|
|
682
|
+
return True, f"{marker} found"
|
|
683
|
+
|
|
684
|
+
# Signal 2c: composer.json deps
|
|
685
|
+
composer = git_root / "composer.json"
|
|
686
|
+
if composer.is_file():
|
|
687
|
+
try:
|
|
688
|
+
data = json.loads(composer.read_text(encoding="utf-8"))
|
|
689
|
+
all_deps = {**data.get("require", {}), **data.get("require-dev", {})}
|
|
690
|
+
found = SERVERSIDE_COMPOSER_DEPS & set(all_deps.keys())
|
|
691
|
+
if found:
|
|
692
|
+
return True, f"{', '.join(sorted(found))} in composer.json"
|
|
693
|
+
except (json.JSONDecodeError, OSError):
|
|
694
|
+
pass
|
|
695
|
+
|
|
696
|
+
# Signal 2d: Gemfile keywords
|
|
697
|
+
gemfile = git_root / "Gemfile"
|
|
698
|
+
if gemfile.is_file():
|
|
699
|
+
try:
|
|
700
|
+
content = gemfile.read_text(encoding="utf-8").lower()
|
|
701
|
+
for kw in SERVERSIDE_GEMFILE_KEYWORDS:
|
|
702
|
+
if kw in content:
|
|
703
|
+
return True, f"'{kw}' in Gemfile"
|
|
704
|
+
except OSError:
|
|
705
|
+
pass
|
|
706
|
+
|
|
707
|
+
# Signal 2e: Python dependency files
|
|
708
|
+
for pyfile in SERVERSIDE_PYTHON_FILES:
|
|
709
|
+
pypath = git_root / pyfile
|
|
710
|
+
if pypath.is_file():
|
|
711
|
+
try:
|
|
712
|
+
content = pypath.read_text(encoding="utf-8").lower()
|
|
713
|
+
for kw in SERVERSIDE_PYTHON_KEYWORDS:
|
|
714
|
+
if kw in content:
|
|
715
|
+
return True, f"'{kw}' in {pyfile}"
|
|
716
|
+
except OSError:
|
|
717
|
+
pass
|
|
718
|
+
|
|
648
719
|
# Signal 3: One level deep package.json (monorepo)
|
|
649
720
|
for child_pkg in git_root.glob("*/package.json"):
|
|
650
721
|
if "node_modules" in str(child_pkg):
|
|
@@ -663,7 +734,16 @@ def _detect_web_project(git_root: Path) -> tuple[bool, str]:
|
|
|
663
734
|
if project_md.is_file():
|
|
664
735
|
try:
|
|
665
736
|
content = project_md.read_text(encoding="utf-8").lower()
|
|
666
|
-
web_keywords = [
|
|
737
|
+
web_keywords = [
|
|
738
|
+
# JS frameworks
|
|
739
|
+
"react", "vue", "next.js", "nextjs", "nuxt", "angular", "svelte", "sveltekit", "astro", "remix",
|
|
740
|
+
# Server-side web frameworks
|
|
741
|
+
"yii", "laravel", "symfony", "codeigniter", "cakephp",
|
|
742
|
+
"django", "flask", "fastapi", "rails", "ruby on rails",
|
|
743
|
+
"spring boot", "spring mvc",
|
|
744
|
+
"asp.net", "blazor",
|
|
745
|
+
"wordpress",
|
|
746
|
+
]
|
|
667
747
|
for kw in web_keywords:
|
|
668
748
|
if kw in content:
|
|
669
749
|
return True, f"'{kw}' mentioned in PROJECT.md"
|
|
@@ -718,9 +798,25 @@ def cmd_browser_check(args: argparse.Namespace) -> None:
|
|
|
718
798
|
|
|
719
799
|
# 2. Web project check
|
|
720
800
|
print("\n=== Web Project Detection ===")
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
801
|
+
web_project_override = None
|
|
802
|
+
if config_path and config_path.is_file():
|
|
803
|
+
try:
|
|
804
|
+
config = json.loads(config_path.read_text(encoding="utf-8"))
|
|
805
|
+
bv = config.get("browser_verification", {})
|
|
806
|
+
if isinstance(bv, dict) and "web_project" in bv:
|
|
807
|
+
web_project_override = bv["web_project"]
|
|
808
|
+
except (json.JSONDecodeError, OSError):
|
|
809
|
+
pass
|
|
810
|
+
|
|
811
|
+
if web_project_override is not None:
|
|
812
|
+
is_web = bool(web_project_override)
|
|
813
|
+
signal = "config override"
|
|
814
|
+
print(f"Web project: {is_web} (config override)")
|
|
815
|
+
print(f"Signal: {signal}")
|
|
816
|
+
else:
|
|
817
|
+
is_web, signal = _detect_web_project(git_root)
|
|
818
|
+
print(f"Web project: {is_web}")
|
|
819
|
+
print(f"Signal: {signal}")
|
|
724
820
|
|
|
725
821
|
if not is_web:
|
|
726
822
|
print("\nResult: SKIP (not a web project)")
|
|
@@ -759,6 +855,26 @@ def cmd_browser_check(args: argparse.Namespace) -> None:
|
|
|
759
855
|
sys.exit(0)
|
|
760
856
|
|
|
761
857
|
|
|
858
|
+
# ===================================================================
|
|
859
|
+
# Subcommand: detect-web
|
|
860
|
+
# ===================================================================
|
|
861
|
+
|
|
862
|
+
|
|
863
|
+
def cmd_detect_web(args: argparse.Namespace) -> None:
|
|
864
|
+
"""Expose _detect_web_project() for use by config command.
|
|
865
|
+
|
|
866
|
+
Contract:
|
|
867
|
+
Output: text — detected + signal
|
|
868
|
+
Exit codes: 0 = web project, 1 = not web project
|
|
869
|
+
Side effects: read-only
|
|
870
|
+
"""
|
|
871
|
+
git_root = find_git_root()
|
|
872
|
+
is_web, signal = _detect_web_project(git_root)
|
|
873
|
+
print(f"detected: {is_web}")
|
|
874
|
+
print(f"signal: {signal}")
|
|
875
|
+
sys.exit(0 if is_web else 1)
|
|
876
|
+
|
|
877
|
+
|
|
762
878
|
# ===================================================================
|
|
763
879
|
# Subcommand: doctor-scan
|
|
764
880
|
# ===================================================================
|
|
@@ -1131,28 +1247,50 @@ def cmd_doctor_scan(args: argparse.Namespace) -> None:
|
|
|
1131
1247
|
|
|
1132
1248
|
# ---- CHECK 9: Research API Keys ----
|
|
1133
1249
|
print("=== Research API Keys ===")
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1250
|
+
api_keys = {
|
|
1251
|
+
"CONTEXT7_API_KEY": {
|
|
1252
|
+
"enables": "library documentation lookup via Context7",
|
|
1253
|
+
"without": "falls back to WebSearch/WebFetch (less authoritative)",
|
|
1254
|
+
"url": "https://context7.com → copy API key",
|
|
1255
|
+
},
|
|
1256
|
+
"PERPLEXITY_API_KEY": {
|
|
1257
|
+
"enables": "deep research via Perplexity AI",
|
|
1258
|
+
"without": "falls back to WebSearch/WebFetch (less comprehensive)",
|
|
1259
|
+
"url": "https://perplexity.ai/settings/api → copy API key",
|
|
1260
|
+
},
|
|
1261
|
+
}
|
|
1262
|
+
missing_keys: list[str] = []
|
|
1263
|
+
settings_only_keys: list[str] = []
|
|
1264
|
+
for key_name, info in api_keys.items():
|
|
1265
|
+
env_val = os.environ.get(key_name, "")
|
|
1266
|
+
settings_val = _get_settings_env_var(key_name)
|
|
1267
|
+
if env_val:
|
|
1268
|
+
pass # configured via environment
|
|
1269
|
+
elif settings_val:
|
|
1270
|
+
settings_only_keys.append(key_name)
|
|
1271
|
+
else:
|
|
1272
|
+
missing_keys.append(key_name)
|
|
1273
|
+
print(f"{key_name}: not set")
|
|
1274
|
+
print(f" Enables: {info['enables']}")
|
|
1275
|
+
print(f" Without: {info['without']}")
|
|
1276
|
+
if sys.platform == "win32":
|
|
1277
|
+
print(f" Set up: {info['url']} → add to ~/.claude/settings.json env section")
|
|
1278
|
+
print(f" Or set via Windows System Environment Variables")
|
|
1279
|
+
else:
|
|
1280
|
+
shell_rc = "~/.zshrc" if sys.platform == "darwin" else "~/.bashrc"
|
|
1281
|
+
print(f" Set up: {info['url']} → export {key_name}=<key> in {shell_rc}")
|
|
1282
|
+
print(f" Or add to ~/.claude/settings.json env section")
|
|
1283
|
+
if missing_keys:
|
|
1141
1284
|
print("Status: WARN")
|
|
1142
|
-
missing_keys: list[str] = []
|
|
1143
|
-
if not c7_key:
|
|
1144
|
-
missing_keys.append("CONTEXT7_API_KEY")
|
|
1145
|
-
print("CONTEXT7_API_KEY: not set")
|
|
1146
|
-
print(" Enables: library documentation lookup via Context7")
|
|
1147
|
-
print(" Without: falls back to WebSearch/WebFetch (less authoritative)")
|
|
1148
|
-
print(" Set up: https://context7.com → copy API key → export CONTEXT7_API_KEY=<key>")
|
|
1149
|
-
if not pplx_key:
|
|
1150
|
-
missing_keys.append("PERPLEXITY_API_KEY")
|
|
1151
|
-
print("PERPLEXITY_API_KEY: not set")
|
|
1152
|
-
print(" Enables: deep research via Perplexity AI")
|
|
1153
|
-
print(" Without: falls back to WebSearch/WebFetch (less comprehensive)")
|
|
1154
|
-
print(" Set up: https://perplexity.ai/settings/api → copy API key → export PERPLEXITY_API_KEY=<key>")
|
|
1155
1285
|
record("WARN", "Research API Keys")
|
|
1286
|
+
else:
|
|
1287
|
+
print("Status: PASS")
|
|
1288
|
+
if settings_only_keys:
|
|
1289
|
+
print("All research API keys configured")
|
|
1290
|
+
print(f" Note: {', '.join(settings_only_keys)} found in settings.json — restart Claude Code session to activate")
|
|
1291
|
+
else:
|
|
1292
|
+
print("All research API keys configured")
|
|
1293
|
+
record("PASS", "Research API Keys")
|
|
1156
1294
|
print()
|
|
1157
1295
|
|
|
1158
1296
|
# ---- CHECK 10: Phase Directory Naming ----
|
|
@@ -1204,15 +1342,32 @@ def cmd_doctor_scan(args: argparse.Namespace) -> None:
|
|
|
1204
1342
|
if isinstance(bv_config, dict):
|
|
1205
1343
|
bv_enabled = bv_config.get("enabled", True)
|
|
1206
1344
|
|
|
1345
|
+
bv_web_override = None
|
|
1346
|
+
if isinstance(bv_config, dict) and "web_project" in bv_config:
|
|
1347
|
+
bv_web_override = bv_config["web_project"]
|
|
1348
|
+
|
|
1349
|
+
bv_hint = ""
|
|
1350
|
+
|
|
1207
1351
|
if not bv_enabled:
|
|
1208
1352
|
print("Status: SKIP")
|
|
1209
1353
|
print("Disabled in config.json")
|
|
1210
1354
|
record("SKIP", "Browser Verification")
|
|
1355
|
+
elif bv_web_override is False:
|
|
1356
|
+
is_web = False
|
|
1357
|
+
print("Status: SKIP")
|
|
1358
|
+
print("web_project: false in config.json")
|
|
1359
|
+
record("SKIP", "Browser Verification")
|
|
1211
1360
|
else:
|
|
1212
|
-
|
|
1361
|
+
if bv_web_override is True:
|
|
1362
|
+
is_web, web_signal = True, "config override"
|
|
1363
|
+
else:
|
|
1364
|
+
is_web, web_signal = _detect_web_project(git_root)
|
|
1365
|
+
|
|
1213
1366
|
if not is_web:
|
|
1367
|
+
bv_hint = "Tip: If this is a web project, run /ms:config to enable browser verification."
|
|
1214
1368
|
print("Status: SKIP")
|
|
1215
1369
|
print(f"Not a web project ({web_signal})")
|
|
1370
|
+
print(bv_hint)
|
|
1216
1371
|
record("SKIP", "Browser Verification")
|
|
1217
1372
|
else:
|
|
1218
1373
|
bv_missing: list[str] = []
|
|
@@ -1243,6 +1398,8 @@ def cmd_doctor_scan(args: argparse.Namespace) -> None:
|
|
|
1243
1398
|
elif not is_web:
|
|
1244
1399
|
print("Status: SKIP")
|
|
1245
1400
|
print(f"Not a web project ({web_signal})")
|
|
1401
|
+
if bv_hint:
|
|
1402
|
+
print(bv_hint)
|
|
1246
1403
|
record("SKIP", "Screenshot Optimization")
|
|
1247
1404
|
else:
|
|
1248
1405
|
if shutil.which("cwebp"):
|
|
@@ -3643,6 +3800,10 @@ def build_parser() -> argparse.ArgumentParser:
|
|
|
3643
3800
|
p = subparsers.add_parser("browser-check", help="Check browser verification prerequisites")
|
|
3644
3801
|
p.set_defaults(func=cmd_browser_check)
|
|
3645
3802
|
|
|
3803
|
+
# --- detect-web ---
|
|
3804
|
+
p = subparsers.add_parser("detect-web", help="Detect if project is a web project")
|
|
3805
|
+
p.set_defaults(func=cmd_detect_web)
|
|
3806
|
+
|
|
3646
3807
|
# --- doctor-scan ---
|
|
3647
3808
|
p = subparsers.add_parser("doctor-scan", help="Diagnostic scan of .planning/ tree")
|
|
3648
3809
|
p.set_defaults(func=cmd_doctor_scan)
|
|
@@ -1,460 +0,0 @@
|
|
|
1
|
-
<required_reading>
|
|
2
|
-
|
|
3
|
-
**Read these files NOW:**
|
|
4
|
-
|
|
5
|
-
1. `.planning/STATE.md`
|
|
6
|
-
2. `.planning/PROJECT.md`
|
|
7
|
-
3. `.planning/ROADMAP.md`
|
|
8
|
-
4. Current phase's plan files (`*-PLAN.md`)
|
|
9
|
-
5. Current phase's summary files (`*-SUMMARY.md`)
|
|
10
|
-
|
|
11
|
-
</required_reading>
|
|
12
|
-
|
|
13
|
-
<purpose>
|
|
14
|
-
|
|
15
|
-
Mark current phase complete and advance to next. This is the natural point where progress tracking and PROJECT.md evolution happen.
|
|
16
|
-
|
|
17
|
-
"Planning next phase" = "current phase is done"
|
|
18
|
-
|
|
19
|
-
</purpose>
|
|
20
|
-
|
|
21
|
-
<process>
|
|
22
|
-
|
|
23
|
-
<step name="load_project_state" priority="first">
|
|
24
|
-
|
|
25
|
-
Before transition, read project state:
|
|
26
|
-
|
|
27
|
-
```bash
|
|
28
|
-
cat .planning/STATE.md 2>/dev/null
|
|
29
|
-
cat .planning/PROJECT.md 2>/dev/null
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
Parse current position to verify we're transitioning the right phase.
|
|
33
|
-
Note accumulated context that may need updating after transition.
|
|
34
|
-
|
|
35
|
-
</step>
|
|
36
|
-
|
|
37
|
-
<step name="verify_completion">
|
|
38
|
-
|
|
39
|
-
Check current phase has all plan summaries:
|
|
40
|
-
|
|
41
|
-
```bash
|
|
42
|
-
ls .planning/phases/XX-current/*-PLAN.md 2>/dev/null | sort
|
|
43
|
-
ls .planning/phases/XX-current/*-SUMMARY.md 2>/dev/null | sort
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
**Verification logic:**
|
|
47
|
-
|
|
48
|
-
- Count PLAN files
|
|
49
|
-
- Count SUMMARY files
|
|
50
|
-
- If counts match: all plans complete
|
|
51
|
-
- If counts don't match: incomplete
|
|
52
|
-
|
|
53
|
-
**If all plans complete:**
|
|
54
|
-
|
|
55
|
-
```
|
|
56
|
-
⚡ Auto-approved: Transition Phase [X] → Phase [X+1]
|
|
57
|
-
Phase [X] complete — all [Y] plans finished.
|
|
58
|
-
|
|
59
|
-
Proceeding to mark done and advance...
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
Proceed directly to cleanup_handoff step.
|
|
63
|
-
|
|
64
|
-
**If plans incomplete:**
|
|
65
|
-
|
|
66
|
-
**SAFETY RAIL: Skipping incomplete plans is destructive — always confirm.**
|
|
67
|
-
|
|
68
|
-
Present:
|
|
69
|
-
|
|
70
|
-
```
|
|
71
|
-
Phase [X] has incomplete plans:
|
|
72
|
-
- {phase}-01-SUMMARY.md ✓ Complete
|
|
73
|
-
- {phase}-02-SUMMARY.md ✗ Missing
|
|
74
|
-
- {phase}-03-SUMMARY.md ✗ Missing
|
|
75
|
-
|
|
76
|
-
⚠️ Safety rail: Skipping plans requires confirmation (destructive action)
|
|
77
|
-
|
|
78
|
-
Options:
|
|
79
|
-
1. Continue current phase (execute remaining plans)
|
|
80
|
-
2. Mark complete anyway (skip remaining plans)
|
|
81
|
-
3. Review what's left
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
Wait for user decision.
|
|
85
|
-
|
|
86
|
-
</step>
|
|
87
|
-
|
|
88
|
-
<step name="update_roadmap">
|
|
89
|
-
|
|
90
|
-
Update the roadmap file:
|
|
91
|
-
|
|
92
|
-
```bash
|
|
93
|
-
ROADMAP_FILE=".planning/ROADMAP.md"
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
Update the file:
|
|
97
|
-
|
|
98
|
-
- Mark current phase: `[x] Complete`
|
|
99
|
-
- Add completion date
|
|
100
|
-
- Update Progress table
|
|
101
|
-
- Keep next phase as `[ ] Not started`
|
|
102
|
-
|
|
103
|
-
**Example:**
|
|
104
|
-
|
|
105
|
-
```markdown
|
|
106
|
-
## Phases
|
|
107
|
-
|
|
108
|
-
- [x] Phase 1: Foundation (completed 2025-01-15)
|
|
109
|
-
- [ ] Phase 2: Authentication ← Next
|
|
110
|
-
- [ ] Phase 3: Core Features
|
|
111
|
-
|
|
112
|
-
## Progress
|
|
113
|
-
|
|
114
|
-
| Phase | Status | Completed |
|
|
115
|
-
| ----------------- | ----------- | ---------- |
|
|
116
|
-
| 1. Foundation | Complete | 2025-01-15 |
|
|
117
|
-
| 2. Authentication | Not started | - |
|
|
118
|
-
| 3. Core Features | Not started | - |
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
</step>
|
|
122
|
-
|
|
123
|
-
<step name="archive_prompts">
|
|
124
|
-
|
|
125
|
-
If prompts were generated for the phase, they stay in place.
|
|
126
|
-
The `completed/` subfolder pattern from create-meta-prompts handles archival.
|
|
127
|
-
|
|
128
|
-
</step>
|
|
129
|
-
|
|
130
|
-
<step name="evolve_project">
|
|
131
|
-
|
|
132
|
-
Evolve PROJECT.md to reflect learnings from completed phase.
|
|
133
|
-
|
|
134
|
-
**Read phase summaries:**
|
|
135
|
-
|
|
136
|
-
```bash
|
|
137
|
-
cat .planning/phases/XX-current/*-SUMMARY.md
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
**Assess requirement changes:**
|
|
141
|
-
|
|
142
|
-
1. **Requirements validated?**
|
|
143
|
-
- Any requirements shipped in this phase?
|
|
144
|
-
- Add to Validated with phase reference: `- ✓ [Requirement] — Phase X`
|
|
145
|
-
|
|
146
|
-
2. **Requirements invalidated?**
|
|
147
|
-
- Any requirements discovered to be unnecessary or wrong?
|
|
148
|
-
- Add to Out of Scope with reason: `- [Requirement] — [why invalidated]`
|
|
149
|
-
|
|
150
|
-
3. **Business context evolved?**
|
|
151
|
-
- Has understanding of audience, problem, or differentiation changed?
|
|
152
|
-
- Update Who It's For, Core Problem, or How It's Different if so
|
|
153
|
-
- New key flows emerged? → Update Key User Flows
|
|
154
|
-
|
|
155
|
-
4. **Decisions to log?**
|
|
156
|
-
- Extract decisions from SUMMARY.md files
|
|
157
|
-
- Add to Key Decisions table with outcome if known
|
|
158
|
-
|
|
159
|
-
5. **"What This Is" still accurate?**
|
|
160
|
-
- If the product has meaningfully changed, update the description
|
|
161
|
-
- Keep it current and accurate
|
|
162
|
-
|
|
163
|
-
**Update PROJECT.md:**
|
|
164
|
-
|
|
165
|
-
Make the edits inline. Update "Last updated" footer:
|
|
166
|
-
|
|
167
|
-
```markdown
|
|
168
|
-
---
|
|
169
|
-
*Last updated: [date] after Phase [X]*
|
|
170
|
-
```
|
|
171
|
-
|
|
172
|
-
**Example evolution:**
|
|
173
|
-
|
|
174
|
-
Before:
|
|
175
|
-
|
|
176
|
-
```markdown
|
|
177
|
-
## Validated
|
|
178
|
-
|
|
179
|
-
- ✓ Canvas drawing tools — Phase 1
|
|
180
|
-
|
|
181
|
-
## Out of Scope
|
|
182
|
-
|
|
183
|
-
- OAuth2 — complexity not needed for v1
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
After (Phase 2 shipped JWT auth, discovered rate limiting needed):
|
|
187
|
-
|
|
188
|
-
```markdown
|
|
189
|
-
## Validated
|
|
190
|
-
|
|
191
|
-
- ✓ Canvas drawing tools — Phase 1
|
|
192
|
-
- ✓ JWT authentication — Phase 2
|
|
193
|
-
|
|
194
|
-
## Out of Scope
|
|
195
|
-
|
|
196
|
-
- OAuth2 — complexity not needed for v1
|
|
197
|
-
- Offline mode — real-time is core value, discovered Phase 2
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
**Step complete when:**
|
|
201
|
-
|
|
202
|
-
- [ ] Phase summaries reviewed for learnings
|
|
203
|
-
- [ ] Shipped requirements added to Validated
|
|
204
|
-
- [ ] Invalidated requirements added to Out of Scope with reason
|
|
205
|
-
- [ ] Business context sections reviewed (Who It's For, Core Problem, How It's Different, Key User Flows)
|
|
206
|
-
- [ ] New decisions logged with rationale
|
|
207
|
-
- [ ] "What This Is" updated if product changed
|
|
208
|
-
- [ ] "Last updated" footer reflects this transition
|
|
209
|
-
|
|
210
|
-
</step>
|
|
211
|
-
|
|
212
|
-
<step name="update_current_position_after_transition">
|
|
213
|
-
|
|
214
|
-
Update Current Position section in STATE.md to reflect phase completion and transition.
|
|
215
|
-
|
|
216
|
-
**Format:**
|
|
217
|
-
|
|
218
|
-
```markdown
|
|
219
|
-
Phase: [next] of [total] ([Next phase name])
|
|
220
|
-
Plan: Not started
|
|
221
|
-
Status: Ready to plan
|
|
222
|
-
Last activity: [today] — Phase [X] complete, transitioned to Phase [X+1]
|
|
223
|
-
|
|
224
|
-
Progress: [updated progress bar]
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
**Instructions:**
|
|
228
|
-
|
|
229
|
-
- Increment phase number to next phase
|
|
230
|
-
- Reset plan to "Not started"
|
|
231
|
-
- Set status to "Ready to plan"
|
|
232
|
-
- Update last activity to describe transition
|
|
233
|
-
- Recalculate progress bar based on completed plans
|
|
234
|
-
|
|
235
|
-
**Example — transitioning from Phase 2 to Phase 3:**
|
|
236
|
-
|
|
237
|
-
Before:
|
|
238
|
-
|
|
239
|
-
```markdown
|
|
240
|
-
## Current Position
|
|
241
|
-
|
|
242
|
-
Phase: 2 of 4 (Authentication)
|
|
243
|
-
Plan: 2 of 2 in current phase
|
|
244
|
-
Status: Phase complete
|
|
245
|
-
Last activity: 2025-01-20 — Completed 02-02-PLAN.md
|
|
246
|
-
|
|
247
|
-
Progress: ███████░░░ 60%
|
|
248
|
-
```
|
|
249
|
-
|
|
250
|
-
After:
|
|
251
|
-
|
|
252
|
-
```markdown
|
|
253
|
-
## Current Position
|
|
254
|
-
|
|
255
|
-
Phase: 3 of 4 (Core Features)
|
|
256
|
-
Plan: Not started
|
|
257
|
-
Status: Ready to plan
|
|
258
|
-
Last activity: 2025-01-20 — Phase 2 complete, transitioned to Phase 3
|
|
259
|
-
|
|
260
|
-
Progress: ███████░░░ 60%
|
|
261
|
-
```
|
|
262
|
-
|
|
263
|
-
**Step complete when:**
|
|
264
|
-
|
|
265
|
-
- [ ] Phase number incremented to next phase
|
|
266
|
-
- [ ] Plan status reset to "Not started"
|
|
267
|
-
- [ ] Status shows "Ready to plan"
|
|
268
|
-
- [ ] Last activity describes the transition
|
|
269
|
-
- [ ] Progress bar reflects total completed plans
|
|
270
|
-
|
|
271
|
-
</step>
|
|
272
|
-
|
|
273
|
-
<step name="update_project_reference">
|
|
274
|
-
|
|
275
|
-
Update Project Reference section in STATE.md.
|
|
276
|
-
|
|
277
|
-
```markdown
|
|
278
|
-
## Project Reference
|
|
279
|
-
|
|
280
|
-
See: .planning/PROJECT.md (updated [today])
|
|
281
|
-
|
|
282
|
-
**Core value:** [Current core value from PROJECT.md]
|
|
283
|
-
**Current focus:** [Next phase name]
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
Update the date and current focus to reflect the transition.
|
|
287
|
-
|
|
288
|
-
</step>
|
|
289
|
-
|
|
290
|
-
<step name="review_accumulated_context">
|
|
291
|
-
|
|
292
|
-
Review and update Accumulated Context section in STATE.md.
|
|
293
|
-
|
|
294
|
-
**Decisions:**
|
|
295
|
-
|
|
296
|
-
- Note recent decisions from this phase (3-5 max)
|
|
297
|
-
- Full log lives in PROJECT.md Key Decisions table
|
|
298
|
-
|
|
299
|
-
**Blockers/Concerns:**
|
|
300
|
-
|
|
301
|
-
- Review blockers from completed phase
|
|
302
|
-
- If addressed in this phase: Remove from list
|
|
303
|
-
- If still relevant for future: Keep with "Phase X" prefix
|
|
304
|
-
- Add any new concerns from completed phase's summaries
|
|
305
|
-
|
|
306
|
-
**Example:**
|
|
307
|
-
|
|
308
|
-
Before:
|
|
309
|
-
|
|
310
|
-
```markdown
|
|
311
|
-
### Blockers/Concerns
|
|
312
|
-
|
|
313
|
-
- ⚠️ [Phase 1] Database schema not indexed for common queries
|
|
314
|
-
- ⚠️ [Phase 2] WebSocket reconnection behavior on flaky networks unknown
|
|
315
|
-
```
|
|
316
|
-
|
|
317
|
-
After (if database indexing was addressed in Phase 2):
|
|
318
|
-
|
|
319
|
-
```markdown
|
|
320
|
-
### Blockers/Concerns
|
|
321
|
-
|
|
322
|
-
- ⚠️ [Phase 2] WebSocket reconnection behavior on flaky networks unknown
|
|
323
|
-
```
|
|
324
|
-
|
|
325
|
-
**Step complete when:**
|
|
326
|
-
|
|
327
|
-
- [ ] Recent decisions noted (full log in PROJECT.md)
|
|
328
|
-
- [ ] Resolved blockers removed from list
|
|
329
|
-
- [ ] Unresolved blockers kept with phase prefix
|
|
330
|
-
- [ ] New concerns from completed phase added
|
|
331
|
-
|
|
332
|
-
</step>
|
|
333
|
-
|
|
334
|
-
<step name="update_session_continuity_after_transition">
|
|
335
|
-
|
|
336
|
-
Update Session Continuity section in STATE.md to reflect transition completion.
|
|
337
|
-
|
|
338
|
-
**Format:**
|
|
339
|
-
|
|
340
|
-
```markdown
|
|
341
|
-
Last session: [today]
|
|
342
|
-
Stopped at: Phase [X] complete, ready to plan Phase [X+1]
|
|
343
|
-
```
|
|
344
|
-
|
|
345
|
-
**Step complete when:**
|
|
346
|
-
|
|
347
|
-
- [ ] Last session timestamp updated to current date and time
|
|
348
|
-
- [ ] Stopped at describes phase completion and next phase
|
|
349
|
-
|
|
350
|
-
</step>
|
|
351
|
-
|
|
352
|
-
<step name="offer_next_phase">
|
|
353
|
-
|
|
354
|
-
**MANDATORY: Verify milestone status before presenting next steps.**
|
|
355
|
-
|
|
356
|
-
**Step 1: Read ROADMAP.md and identify phases in current milestone**
|
|
357
|
-
|
|
358
|
-
Read the ROADMAP.md file and extract:
|
|
359
|
-
1. Current phase number (the phase just transitioned from)
|
|
360
|
-
2. All phase numbers in the current milestone section
|
|
361
|
-
|
|
362
|
-
To find phases, look for:
|
|
363
|
-
- Phase headers: lines starting with `### Phase` or `#### Phase`
|
|
364
|
-
- Phase list items: lines like `- [ ] **Phase X:` or `- [x] **Phase X:`
|
|
365
|
-
|
|
366
|
-
Count total phases and identify the highest phase number in the milestone.
|
|
367
|
-
|
|
368
|
-
State: "Current phase is {X}. Milestone has {N} phases (highest: {Y})."
|
|
369
|
-
|
|
370
|
-
**Step 2: Route based on milestone status**
|
|
371
|
-
|
|
372
|
-
| Condition | Meaning | Action |
|
|
373
|
-
|-----------|---------|--------|
|
|
374
|
-
| current phase < highest phase | More phases remain | Go to **Route A** |
|
|
375
|
-
| current phase = highest phase | Milestone complete | Go to **Route B** |
|
|
376
|
-
|
|
377
|
-
---
|
|
378
|
-
|
|
379
|
-
**Route A: More phases remain in milestone**
|
|
380
|
-
|
|
381
|
-
Read ROADMAP.md to get the next phase's name and goal.
|
|
382
|
-
|
|
383
|
-
**If next phase exists:**
|
|
384
|
-
|
|
385
|
-
```
|
|
386
|
-
Phase [X] marked complete.
|
|
387
|
-
|
|
388
|
-
Next: Phase [X+1] — [Name]
|
|
389
|
-
|
|
390
|
-
⚡ Auto-continuing: Plan Phase [X+1] in detail
|
|
391
|
-
```
|
|
392
|
-
|
|
393
|
-
Exit skill and invoke SlashCommand("/ms:plan-phase [X+1]")
|
|
394
|
-
|
|
395
|
-
---
|
|
396
|
-
|
|
397
|
-
**Route B: Milestone complete (all phases done)**
|
|
398
|
-
|
|
399
|
-
```
|
|
400
|
-
Phase {X} marked complete.
|
|
401
|
-
|
|
402
|
-
🎉 Milestone is 100% complete — all {N} phases finished!
|
|
403
|
-
|
|
404
|
-
⚡ Auto-continuing: Complete milestone and archive
|
|
405
|
-
```
|
|
406
|
-
|
|
407
|
-
Exit skill and invoke SlashCommand("/ms:complete-milestone")
|
|
408
|
-
|
|
409
|
-
</step>
|
|
410
|
-
|
|
411
|
-
</process>
|
|
412
|
-
|
|
413
|
-
<implicit_tracking>
|
|
414
|
-
|
|
415
|
-
Progress tracking is IMPLICIT:
|
|
416
|
-
|
|
417
|
-
- "Plan phase 2" → Phase 1 must be done (or ask)
|
|
418
|
-
- "Plan phase 3" → Phases 1-2 must be done (or ask)
|
|
419
|
-
- Transition workflow makes it explicit in ROADMAP.md
|
|
420
|
-
|
|
421
|
-
No separate "update progress" step. Forward motion IS progress.
|
|
422
|
-
|
|
423
|
-
</implicit_tracking>
|
|
424
|
-
|
|
425
|
-
<partial_completion>
|
|
426
|
-
|
|
427
|
-
If user wants to move on but phase isn't fully complete:
|
|
428
|
-
|
|
429
|
-
```
|
|
430
|
-
Phase [X] has incomplete plans:
|
|
431
|
-
- {phase}-02-PLAN.md (not executed)
|
|
432
|
-
- {phase}-03-PLAN.md (not executed)
|
|
433
|
-
|
|
434
|
-
Options:
|
|
435
|
-
1. Mark complete anyway (plans weren't needed)
|
|
436
|
-
2. Defer work to later phase
|
|
437
|
-
3. Stay and finish current phase
|
|
438
|
-
```
|
|
439
|
-
|
|
440
|
-
Respect user judgment — they know if work matters.
|
|
441
|
-
|
|
442
|
-
**If marking complete with incomplete plans:**
|
|
443
|
-
|
|
444
|
-
- Note in transition message which plans were skipped
|
|
445
|
-
|
|
446
|
-
</partial_completion>
|
|
447
|
-
|
|
448
|
-
<success_criteria>
|
|
449
|
-
|
|
450
|
-
Transition is complete when:
|
|
451
|
-
|
|
452
|
-
- [ ] Current phase plan summaries verified (all exist or user chose to skip)
|
|
453
|
-
- [ ] Any stale handoffs deleted
|
|
454
|
-
- [ ] ROADMAP.md updated with completion status
|
|
455
|
-
- [ ] PROJECT.md evolved (requirements, decisions, description if needed)
|
|
456
|
-
- [ ] STATE.md updated (position, project reference, context, session)
|
|
457
|
-
- [ ] Progress table updated
|
|
458
|
-
- [ ] User knows next steps
|
|
459
|
-
|
|
460
|
-
</success_criteria>
|