@a-canary/pi-choose-wisely 1.0.0
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 +84 -0
- package/package.json +15 -0
- package/skills/choose-wisely/SKILL.md +113 -0
- package/skills/choose-wisely/lib/audit.md +97 -0
- package/skills/choose-wisely/lib/bootstrap.md +92 -0
- package/skills/choose-wisely/lib/cascade.md +138 -0
- package/skills/choose-wisely/lib/interview.md +190 -0
- package/skills/replan/SKILL.md +140 -0
- package/templates/CHOICES.md +66 -0
- package/templates/PLAN.md +42 -0
package/README.md
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Pi Choose Wisely
|
|
2
|
+
|
|
3
|
+
A pi-package for architectural decision management using the CHOICES.md framework.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pi install git:github.com/a-canary/pi-choose-wisely
|
|
9
|
+
# or
|
|
10
|
+
pi install /path/to/pi-choose-wisely
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Skills
|
|
14
|
+
|
|
15
|
+
### `/choose-wisely`
|
|
16
|
+
|
|
17
|
+
Clarify project vision, mission, UX, operations, and architectural decisions in CHOICES.md.
|
|
18
|
+
|
|
19
|
+
- Auto-bootstraps from existing docs if CHOICES.md missing
|
|
20
|
+
- Validates with cascading impact review after changes
|
|
21
|
+
- Runs structural audit automatically
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
/choose-wisely # Bootstrap or show status
|
|
25
|
+
/choose-wisely add OAuth authentication # Add a choice
|
|
26
|
+
/choose-wisely change database to Postgres # Modify a choice
|
|
27
|
+
/choose-wisely audit # Full validation
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### `/choose-wisely:replan`
|
|
31
|
+
|
|
32
|
+
Gap analysis: compare CHOICES.md against current implementation state, generate PLAN.md for next phase.
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
/choose-wisely:replan # Analyze gaps, generate plan
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## CHOICES.md Structure
|
|
39
|
+
|
|
40
|
+
8 sections in priority order:
|
|
41
|
+
|
|
42
|
+
| Section | Prefix | What goes here |
|
|
43
|
+
|---------|--------|----------------|
|
|
44
|
+
| Mission | M- | Why we exist, values, principles |
|
|
45
|
+
| User Experiences | UX- | Core user journeys, interactions |
|
|
46
|
+
| Features | F- | Specific capabilities |
|
|
47
|
+
| Operations | O- | Automation, SLAs, workflows |
|
|
48
|
+
| Data | D- | Storage decisions, schemas |
|
|
49
|
+
| Architecture | A- | System design (tool-agnostic) |
|
|
50
|
+
| Technology | T- | Tech stack, libraries (names tools) |
|
|
51
|
+
| Implementation | I- | Dev practices, standards |
|
|
52
|
+
|
|
53
|
+
## Choice Format
|
|
54
|
+
|
|
55
|
+
```markdown
|
|
56
|
+
### A-0012: Event-driven architecture for order processing
|
|
57
|
+
Supports: F-0003, O-0002
|
|
58
|
+
|
|
59
|
+
Use message queue for order events. Decouples billing, inventory,
|
|
60
|
+
and shipping services. Enables async processing for traffic spikes.
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**Rules:**
|
|
64
|
+
- Position = Priority (higher constrains lower)
|
|
65
|
+
- `Supports:` required on every choice (except top)
|
|
66
|
+
- Architecture is tool-agnostic, Technology names tools
|
|
67
|
+
|
|
68
|
+
## Helper Modules
|
|
69
|
+
|
|
70
|
+
Loaded on-demand by the main skill:
|
|
71
|
+
|
|
72
|
+
- `lib/bootstrap.md` — Scan docs, extract choices
|
|
73
|
+
- `lib/audit.md` — 8 validation checks
|
|
74
|
+
- `lib/cascade.md` — 3-check impact review
|
|
75
|
+
- `lib/interview.md` — Planning questions by category
|
|
76
|
+
|
|
77
|
+
## Templates
|
|
78
|
+
|
|
79
|
+
- `templates/CHOICES.md` — Empty template with 8 sections
|
|
80
|
+
- `templates/PLAN.md` — Phased implementation plan
|
|
81
|
+
|
|
82
|
+
## License
|
|
83
|
+
|
|
84
|
+
MIT
|
package/package.json
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@a-canary/pi-choose-wisely",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "CHOICES.md management — clarify project vision, mission, UX, operations, architectural decisions with cascading impact review. Includes replan skill for gap analysis and PLAN.md generation.",
|
|
5
|
+
"keywords": ["pi-package"],
|
|
6
|
+
"author": {
|
|
7
|
+
"name": "a-canary"
|
|
8
|
+
},
|
|
9
|
+
"license": "MIT",
|
|
10
|
+
"type": "module",
|
|
11
|
+
"pi": {
|
|
12
|
+
"skills": ["./skills"],
|
|
13
|
+
"templates": ["./templates"]
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: choose-wisely
|
|
3
|
+
description: "Clarify project vision, mission, UX, operations, and architectural decisions in CHOICES.md. Auto-bootstraps from existing docs, validates with cascading impact review."
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Choose Wisely — Architectural Decision Management
|
|
7
|
+
|
|
8
|
+
Manage project choices in CHOICES.md. Auto-bootstraps if missing, runs cascading audit after changes.
|
|
9
|
+
|
|
10
|
+
## Quick Routing
|
|
11
|
+
|
|
12
|
+
| User Input | Action |
|
|
13
|
+
|------------|--------|
|
|
14
|
+
| No CHOICES.md | Bootstrap from template + existing docs |
|
|
15
|
+
| "audit" / "check" | Run full validation, report issues |
|
|
16
|
+
| "init" / "bootstrap" | Scan docs, extract choices |
|
|
17
|
+
| Describing a change | Apply with 3-check cascade |
|
|
18
|
+
| Empty/new project | Offer planning interview |
|
|
19
|
+
|
|
20
|
+
## Workflow
|
|
21
|
+
|
|
22
|
+
### 1. Discover
|
|
23
|
+
|
|
24
|
+
Find CHOICES.md (project root, docs/, .pi/). If missing, create from template:
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
Template: {{SKILL_DIR}}/../templates/CHOICES.md
|
|
28
|
+
Target: {{PROJECT_ROOT}}/CHOICES.md
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
### 2. Parse State
|
|
32
|
+
|
|
33
|
+
If CHOICES.md exists, parse into:
|
|
34
|
+
- Sections (Mission → Implementation)
|
|
35
|
+
- Choices with ID, title, rationale
|
|
36
|
+
- `Supports:` dependency graph
|
|
37
|
+
|
|
38
|
+
### 3. Route by Input
|
|
39
|
+
|
|
40
|
+
#### Bootstrap (no CHOICES.md or "init")
|
|
41
|
+
|
|
42
|
+
Load [bootstrap module](lib/bootstrap.md) to scan existing docs:
|
|
43
|
+
- README.md, ARCHITECTURE.md, DESIGN.md
|
|
44
|
+
- docs/*.md, specs/*.md
|
|
45
|
+
- ADR files
|
|
46
|
+
|
|
47
|
+
Extract choices → assign IDs → write CHOICES.md.
|
|
48
|
+
|
|
49
|
+
#### Audit ("audit" / "check")
|
|
50
|
+
|
|
51
|
+
Load [audit module](lib/audit.md) and run 8 validation checks. Report issues tersely:
|
|
52
|
+
|
|
53
|
+
> 23 choices audited. 1 stale reference in "timeout operations" choice. No gaps, no contradictions. Clean.
|
|
54
|
+
|
|
55
|
+
#### Change (describing modification)
|
|
56
|
+
|
|
57
|
+
Apply edit, then run [cascade module](lib/cascade.md):
|
|
58
|
+
|
|
59
|
+
**Three checks per change:**
|
|
60
|
+
1. **Upward**: Does change still support its `Supports:` targets?
|
|
61
|
+
2. **Lateral**: Any contradictions/redundancies in same section?
|
|
62
|
+
3. **Downward**: Do choices referencing this one still hold?
|
|
63
|
+
|
|
64
|
+
Cascade silently to convergence. Summarize in 2-3 sentences by title.
|
|
65
|
+
|
|
66
|
+
#### Planning (empty project / "plan")
|
|
67
|
+
|
|
68
|
+
Load [interview module](lib/interview.md) and conduct structured interview:
|
|
69
|
+
- Mission questions (why, who, value)
|
|
70
|
+
- UX questions (workflow, interactions)
|
|
71
|
+
- Architecture questions (patterns, communication)
|
|
72
|
+
- Technology questions (frameworks, tools)
|
|
73
|
+
|
|
74
|
+
Generate CHOICES.md with decisions + PLAN.md for next phase.
|
|
75
|
+
|
|
76
|
+
### 4. Always Audit
|
|
77
|
+
|
|
78
|
+
After any change, run audit checks. Only surface if issues found.
|
|
79
|
+
|
|
80
|
+
### 5. Commit
|
|
81
|
+
|
|
82
|
+
Commit CHOICES.md independently with descriptive message.
|
|
83
|
+
|
|
84
|
+
## CHOICES.md Format
|
|
85
|
+
|
|
86
|
+
```markdown
|
|
87
|
+
### X-0001: Title of choice
|
|
88
|
+
Supports: X-0000, Y-0000
|
|
89
|
+
|
|
90
|
+
One to two lines of rationale. Not a spec.
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Sections (fixed order):**
|
|
94
|
+
1. Mission (M-)
|
|
95
|
+
2. User Experiences (UX-)
|
|
96
|
+
3. Features (F-)
|
|
97
|
+
4. Operations (O-)
|
|
98
|
+
5. Data (D-)
|
|
99
|
+
6. Architecture (A-)
|
|
100
|
+
7. Technology (T-)
|
|
101
|
+
8. Implementation (I-)
|
|
102
|
+
|
|
103
|
+
**Rules:**
|
|
104
|
+
- Position = Priority (higher constrains lower)
|
|
105
|
+
- `Supports:` required on every choice except top
|
|
106
|
+
- Architecture is tool-agnostic, Technology names tools
|
|
107
|
+
|
|
108
|
+
## Modules
|
|
109
|
+
|
|
110
|
+
- [lib/bootstrap.md](lib/bootstrap.md) — Scan docs, extract choices
|
|
111
|
+
- [lib/audit.md](lib/audit.md) — 8 validation checks
|
|
112
|
+
- [lib/cascade.md](lib/cascade.md) — 3-check impact review
|
|
113
|
+
- [lib/interview.md](lib/interview.md) — Planning questions
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# Audit Module — CHOICES.md Validation
|
|
2
|
+
|
|
3
|
+
Run 8 validation checks to ensure structural integrity and consistency.
|
|
4
|
+
|
|
5
|
+
## Process
|
|
6
|
+
|
|
7
|
+
Run checks iteratively — up to 10 passes. Apply fixes, re-run until convergence (zero new issues).
|
|
8
|
+
|
|
9
|
+
## Checks (in order)
|
|
10
|
+
|
|
11
|
+
### 1. Structural Integrity
|
|
12
|
+
|
|
13
|
+
- [ ] Sections in correct order: Mission > UX > Features > Operations > Data > Architecture > Technology > Implementation
|
|
14
|
+
- [ ] Each choice ID uses correct prefix for its section
|
|
15
|
+
- [ ] IDs are globally unique (no duplicates)
|
|
16
|
+
- [ ] Every choice (except top-most) has `Supports:` line
|
|
17
|
+
- [ ] `Supports:` references only valid IDs that exist
|
|
18
|
+
- [ ] `Supports:` only points upward (higher priority choices)
|
|
19
|
+
|
|
20
|
+
### 2. Support Integrity
|
|
21
|
+
|
|
22
|
+
For each choice:
|
|
23
|
+
- [ ] Rationale connects to `Supports:` targets?
|
|
24
|
+
- [ ] Orphaned choices flagged (no other choice references them)
|
|
25
|
+
|
|
26
|
+
### 3. Standalone Comprehensibility
|
|
27
|
+
|
|
28
|
+
**3a. Undefined terms**
|
|
29
|
+
- Flag domain terms used in 3+ choices but not defined where first used
|
|
30
|
+
|
|
31
|
+
**3b. Opaque names**
|
|
32
|
+
- Flag module/component names without explanation
|
|
33
|
+
|
|
34
|
+
**3c. Scope completeness**
|
|
35
|
+
- Mission answers: content scope, audience, platform scope
|
|
36
|
+
|
|
37
|
+
**3d. Dangling counts**
|
|
38
|
+
- Flag numbers without traceable items ("9 data stores" → list them)
|
|
39
|
+
|
|
40
|
+
### 4. Section Coherence
|
|
41
|
+
|
|
42
|
+
Within each section:
|
|
43
|
+
- [ ] No contradictions between choices
|
|
44
|
+
- [ ] No redundancies (same decision stated twice)
|
|
45
|
+
- [ ] Ordering is logical (constraining choices first)
|
|
46
|
+
|
|
47
|
+
### 5. Architecture Tool-Agnosticism
|
|
48
|
+
|
|
49
|
+
- [ ] Architecture section contains no named technologies
|
|
50
|
+
- Architecture describes patterns, Technology names tools
|
|
51
|
+
- If found, suggest move to Technology section
|
|
52
|
+
|
|
53
|
+
### 6. Bottom-Up: Implicit Choices
|
|
54
|
+
|
|
55
|
+
Look for patterns in lower sections (Data→Implementation):
|
|
56
|
+
- [ ] Cluster choices with shared themes
|
|
57
|
+
- [ ] Propose abstractions for clusters without explicit parent choice
|
|
58
|
+
|
|
59
|
+
### 7. Top-Down: Implementation Gaps
|
|
60
|
+
|
|
61
|
+
- [ ] Every choice in Mission→Operations appears in at least one `Supports:` line in Data→Implementation
|
|
62
|
+
- Flag high-level choices without supporting implementation
|
|
63
|
+
|
|
64
|
+
### 8. Cross-File (if applicable)
|
|
65
|
+
|
|
66
|
+
- [ ] Parent choices correctly inherited
|
|
67
|
+
- [ ] No contradictions with parent
|
|
68
|
+
- [ ] No ID collisions
|
|
69
|
+
|
|
70
|
+
## Auto-Fixes
|
|
71
|
+
|
|
72
|
+
When issues found, offer to fix:
|
|
73
|
+
|
|
74
|
+
| Issue | Auto-Fix |
|
|
75
|
+
|-------|----------|
|
|
76
|
+
| Missing `Supports:` | Suggest based on content |
|
|
77
|
+
| Invalid reference | Remove or suggest correct ID |
|
|
78
|
+
| Wrong section | Move to correct section |
|
|
79
|
+
| Tech in Architecture | Move to Technology |
|
|
80
|
+
| Duplicate ID | Renumber |
|
|
81
|
+
|
|
82
|
+
## Output Format
|
|
83
|
+
|
|
84
|
+
Run silently. When converged, report tersely:
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
Audit: 23 choices, converged in 2 passes.
|
|
88
|
+
|
|
89
|
+
[✓] Structure valid
|
|
90
|
+
[✓] Support chains intact
|
|
91
|
+
[✓] No contradictions
|
|
92
|
+
[~] 1 warning: "session timeout" choice references undefined term "JWT"
|
|
93
|
+
|
|
94
|
+
Fixed: 1 stale reference in timeout operations.
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
If issues remain after 10 passes, list as unresolved with suggestions.
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Bootstrap Module — Extract Choices from Docs
|
|
2
|
+
|
|
3
|
+
Scan existing documentation and extract implicit architectural decisions.
|
|
4
|
+
|
|
5
|
+
## Sources to Scan
|
|
6
|
+
|
|
7
|
+
Priority order:
|
|
8
|
+
1. `README.md` — project overview, mission
|
|
9
|
+
2. `ARCHITECTURE.md` — system design
|
|
10
|
+
3. `DESIGN.md` — design decisions
|
|
11
|
+
4. `CLAUDE.md` — AI agent instructions
|
|
12
|
+
5. `.pi/agent/AGENTS.md` — project guidelines
|
|
13
|
+
6. `docs/*.md` — additional docs
|
|
14
|
+
7. `specs/*.md` — specifications
|
|
15
|
+
8. ADR files (`docs/adr/*.md`, `adr/*.md`)
|
|
16
|
+
|
|
17
|
+
## Extraction Mapping
|
|
18
|
+
|
|
19
|
+
| Found In | Section |
|
|
20
|
+
|----------|---------|
|
|
21
|
+
| Mission statements, values, principles | **Mission** (M-) |
|
|
22
|
+
| User journeys, interaction patterns | **User Experiences** (UX-) |
|
|
23
|
+
| Specific capabilities, behaviors | **Features** (F-) |
|
|
24
|
+
| Automation, SLAs, moderation | **Operations** (O-) |
|
|
25
|
+
| Schema decisions, storage patterns | **Data** (D-) |
|
|
26
|
+
| System design, module structure | **Architecture** (A-) |
|
|
27
|
+
| Named technologies, libraries | **Technology** (T-) |
|
|
28
|
+
| Dev practices, coding standards | **Implementation** (I-) |
|
|
29
|
+
|
|
30
|
+
## Extraction Process
|
|
31
|
+
|
|
32
|
+
For each document:
|
|
33
|
+
|
|
34
|
+
1. **Identify decisions** — statements of intent, choices made, patterns adopted
|
|
35
|
+
2. **Classify by section** — which of 8 sections does this belong to?
|
|
36
|
+
3. **Extract rationale** — why was this chosen? (1-2 sentences)
|
|
37
|
+
4. **Note alternatives** — what else was considered?
|
|
38
|
+
5. **Find dependencies** — what does this support / depend on?
|
|
39
|
+
|
|
40
|
+
## Output Format
|
|
41
|
+
|
|
42
|
+
```yaml
|
|
43
|
+
choices:
|
|
44
|
+
- section: Mission
|
|
45
|
+
title: Core value proposition
|
|
46
|
+
rationale: Build X because Y
|
|
47
|
+
source: README.md:12
|
|
48
|
+
supports: []
|
|
49
|
+
- section: Technology
|
|
50
|
+
title: Use PostgreSQL for primary database
|
|
51
|
+
rationale: ACID compliance needed for financial data
|
|
52
|
+
source: ARCHITECTURE.md:45
|
|
53
|
+
supports: [D-0001]
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Deduplication
|
|
57
|
+
|
|
58
|
+
- Same concept, different wording → merge, keep clearest rationale
|
|
59
|
+
- Similar but distinct → keep separate
|
|
60
|
+
- Contradictory → flag as conflict
|
|
61
|
+
|
|
62
|
+
## Conflict Marking
|
|
63
|
+
|
|
64
|
+
```markdown
|
|
65
|
+
### A-0012: Data storage approach
|
|
66
|
+
Supports: F-0003
|
|
67
|
+
|
|
68
|
+
<!-- CONFLICT: README.md says PostgreSQL, ARCHITECTURE.md says MongoDB -->
|
|
69
|
+
Use PostgreSQL for transactional data, MongoDB for documents.
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Gap Detection
|
|
73
|
+
|
|
74
|
+
After extraction, flag:
|
|
75
|
+
|
|
76
|
+
1. **Undefined terms** — used in 3+ choices but not explained
|
|
77
|
+
2. **Missing scope** — Mission doesn't answer: who, what, platform
|
|
78
|
+
3. **Phantom references** — "9 data stores" but only 3 listed
|
|
79
|
+
4. **Opaque names** — component/module names without explanation
|
|
80
|
+
|
|
81
|
+
## ID Assignment
|
|
82
|
+
|
|
83
|
+
Within each section:
|
|
84
|
+
- Order by priority (most constraining first)
|
|
85
|
+
- Assign sequential IDs: M-0001, M-0002, UX-0001, F-0001, etc.
|
|
86
|
+
|
|
87
|
+
## Final Steps
|
|
88
|
+
|
|
89
|
+
1. Write all choices to CHOICES.md
|
|
90
|
+
2. Present summary (N choices, M sources, P conflicts, G gaps)
|
|
91
|
+
3. Walk through conflicts with user
|
|
92
|
+
4. Run audit to validate
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# Cascade Module — Impact Review
|
|
2
|
+
|
|
3
|
+
Three-check cascade for propagating change impacts through the choice hierarchy.
|
|
4
|
+
|
|
5
|
+
## Principle
|
|
6
|
+
|
|
7
|
+
Changing a choice can affect:
|
|
8
|
+
1. What it supports (upward)
|
|
9
|
+
2. Peers in same section (lateral)
|
|
10
|
+
3. What depends on it (downward)
|
|
11
|
+
|
|
12
|
+
## The Three Checks
|
|
13
|
+
|
|
14
|
+
### Check 1: Upward — Support Integrity
|
|
15
|
+
|
|
16
|
+
**Question:** Does the changed choice still support its `Supports:` targets?
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
Before: A-0012 "Use event queue" supports F-0003 "Real-time updates"
|
|
20
|
+
Change: A-0012 → "Use synchronous API calls"
|
|
21
|
+
Check: Does sync API still support real-time updates? NO
|
|
22
|
+
Result: Flag broken support, suggest alternatives
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Actions:
|
|
26
|
+
- Verify support still holds
|
|
27
|
+
- If weakened: note degraded support
|
|
28
|
+
- If broken: flag and propose alternatives
|
|
29
|
+
|
|
30
|
+
### Check 2: Lateral — Section Coherence
|
|
31
|
+
|
|
32
|
+
**Question:** Any contradictions or redundancies with peer choices?
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
Section: Technology
|
|
36
|
+
Existing: T-0003 "Use PostgreSQL for transactions"
|
|
37
|
+
Change: Add T-0008 "Use MongoDB for all data"
|
|
38
|
+
Check: Contradiction! Can't use both for all data
|
|
39
|
+
Result: Flag conflict, ask user to resolve
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Actions:
|
|
43
|
+
- Scan same section for contradictions
|
|
44
|
+
- Identify redundancies (same decision twice)
|
|
45
|
+
- Check ordering (more constraining first)
|
|
46
|
+
|
|
47
|
+
### Check 3: Downward — Impact Propagation
|
|
48
|
+
|
|
49
|
+
**Question:** Do choices that reference this one still hold?
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
Changed: A-0012 "Use event queue" → "Use synchronous API"
|
|
53
|
+
Dependents:
|
|
54
|
+
- D-0005 "Store events in Kafka" (supports A-0012)
|
|
55
|
+
- O-0003 "Async event processing" (supports A-0012)
|
|
56
|
+
|
|
57
|
+
Check: These depend on event queue. Sync API invalidates them.
|
|
58
|
+
Result: Propose modifications to D-0005, O-0003
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Actions:
|
|
62
|
+
- Find all choices with changed ID in their `Supports:`
|
|
63
|
+
- Assess if dependency still valid
|
|
64
|
+
- Propose modifications → re-enters cascade
|
|
65
|
+
|
|
66
|
+
## Cascade Algorithm
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
function cascade(change, depth=0):
|
|
70
|
+
if depth > 10:
|
|
71
|
+
return "Max depth exceeded"
|
|
72
|
+
|
|
73
|
+
issues = []
|
|
74
|
+
|
|
75
|
+
# Check 1: Upward
|
|
76
|
+
for target in change.supports:
|
|
77
|
+
if not supports_target(change, target):
|
|
78
|
+
issues.append(broken_support(change, target))
|
|
79
|
+
|
|
80
|
+
# Check 2: Lateral
|
|
81
|
+
for peer in get_section_peers(change.section):
|
|
82
|
+
if contradicts(change, peer):
|
|
83
|
+
issues.append(contradiction(change, peer))
|
|
84
|
+
if redundant(change, peer):
|
|
85
|
+
issues.append(redundancy(change, peer))
|
|
86
|
+
|
|
87
|
+
# Check 3: Downward
|
|
88
|
+
for dependent in get_dependents(change.id):
|
|
89
|
+
if not dependency_holds(dependent, change):
|
|
90
|
+
proposed = propose_fix(dependent, change)
|
|
91
|
+
issues.append(impact(dependent, proposed))
|
|
92
|
+
cascade(proposed, depth + 1) # Recurse
|
|
93
|
+
|
|
94
|
+
return issues
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
## Convergence
|
|
98
|
+
|
|
99
|
+
Cascade recursively until:
|
|
100
|
+
- No new issues found
|
|
101
|
+
- Max depth (10) reached
|
|
102
|
+
|
|
103
|
+
## Output
|
|
104
|
+
|
|
105
|
+
Run silently. When converged, summarize tersely:
|
|
106
|
+
|
|
107
|
+
> Updated "event architecture" choice. Cascade found 2 impacts: "Kafka storage" choice now needs revision, "async processing" choice marked for review. Fixed stale reference. 4 choices touched total.
|
|
108
|
+
|
|
109
|
+
## Example Session
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
User: Change A-0012 from event queue to synchronous API
|
|
113
|
+
|
|
114
|
+
Analyzing change...
|
|
115
|
+
Check 1: A-0012 supports F-0003 "real-time updates"
|
|
116
|
+
→ Sync API weakens support. Flag for review.
|
|
117
|
+
|
|
118
|
+
Check 2: Lateral scan of Architecture section
|
|
119
|
+
→ No contradictions found.
|
|
120
|
+
|
|
121
|
+
Check 3: Finding dependents...
|
|
122
|
+
→ D-0005 "Kafka storage" depends on A-0012
|
|
123
|
+
→ O-0003 "Async processing" depends on A-0012
|
|
124
|
+
→ Both invalidated by sync API change.
|
|
125
|
+
|
|
126
|
+
Cascade continues...
|
|
127
|
+
→ Proposing D-0005 revision: "HTTP request storage"
|
|
128
|
+
→ Proposing O-0003 revision: "Synchronous processing"
|
|
129
|
+
|
|
130
|
+
Converged after 2 passes.
|
|
131
|
+
|
|
132
|
+
Summary: Changed "event architecture" to synchronous. 3 downstream choices affected:
|
|
133
|
+
- D-0005: Kafka → HTTP logs
|
|
134
|
+
- O-0003: Async → Sync processing
|
|
135
|
+
- F-0003: Real-time capability degraded (warning)
|
|
136
|
+
|
|
137
|
+
Proceed with these changes?
|
|
138
|
+
```
|
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# Interview Module — Planning Questions
|
|
2
|
+
|
|
3
|
+
Structured interview for discovering architectural decisions.
|
|
4
|
+
|
|
5
|
+
## When to Use
|
|
6
|
+
|
|
7
|
+
- New project with no CHOICES.md
|
|
8
|
+
- Major replanning needed
|
|
9
|
+
- User explicitly requests planning
|
|
10
|
+
|
|
11
|
+
## Interview Categories
|
|
12
|
+
|
|
13
|
+
Ask questions in this order, grouped by section.
|
|
14
|
+
|
|
15
|
+
### Mission (M-*)
|
|
16
|
+
|
|
17
|
+
Core questions:
|
|
18
|
+
1. **Problem** — What problem does this solve?
|
|
19
|
+
2. **Users** — Who are the primary users?
|
|
20
|
+
3. **Value** — What's the core value proposition?
|
|
21
|
+
4. **Scope** — What's explicitly in/out of scope?
|
|
22
|
+
|
|
23
|
+
Example prompts:
|
|
24
|
+
- "What pain point are you addressing?"
|
|
25
|
+
- "Who wakes up excited to use this?"
|
|
26
|
+
- "In one sentence, why does this exist?"
|
|
27
|
+
|
|
28
|
+
### User Experiences (UX-*)
|
|
29
|
+
|
|
30
|
+
Core questions:
|
|
31
|
+
1. **Workflow** — What's the primary user journey?
|
|
32
|
+
2. **Interactions** — How do users interact with this?
|
|
33
|
+
3. **Easy vs Powerful** — What should be effortless? What should be configurable?
|
|
34
|
+
4. **Errors** — How should failures appear to users?
|
|
35
|
+
|
|
36
|
+
Example prompts:
|
|
37
|
+
- "Walk me through a typical user session"
|
|
38
|
+
- "What's the happy path? What's the sad path?"
|
|
39
|
+
|
|
40
|
+
### Features (F-*)
|
|
41
|
+
|
|
42
|
+
Core questions:
|
|
43
|
+
1. **Core capabilities** — What must it do?
|
|
44
|
+
2. **Nice-to-have** — What would be nice but not required?
|
|
45
|
+
3. **Differentiators** — What makes this different from alternatives?
|
|
46
|
+
4. **Integrations** — What must it connect to?
|
|
47
|
+
|
|
48
|
+
Example prompts:
|
|
49
|
+
- "If you could only have 3 features, which ones?"
|
|
50
|
+
- "What would make users switch from competitors?"
|
|
51
|
+
|
|
52
|
+
### Operations (O-*)
|
|
53
|
+
|
|
54
|
+
Core questions:
|
|
55
|
+
1. **Deployment** — Where does this run?
|
|
56
|
+
2. **Scaling** — How does it handle growth?
|
|
57
|
+
3. **Monitoring** — How do you know it's healthy?
|
|
58
|
+
4. **Recovery** — What happens when things break?
|
|
59
|
+
|
|
60
|
+
Example prompts:
|
|
61
|
+
- "How many concurrent users at peak?"
|
|
62
|
+
- "What's acceptable downtime?"
|
|
63
|
+
|
|
64
|
+
### Data (D-*)
|
|
65
|
+
|
|
66
|
+
Core questions:
|
|
67
|
+
1. **Storage** — What data must persist?
|
|
68
|
+
2. **Access patterns** — How is data read/written?
|
|
69
|
+
3. **Privacy** — What's sensitive? Who can see what?
|
|
70
|
+
4. **Retention** — How long is data kept?
|
|
71
|
+
|
|
72
|
+
Example prompts:
|
|
73
|
+
- "What would be catastrophic to lose?"
|
|
74
|
+
- "Does data have different access speeds?"
|
|
75
|
+
|
|
76
|
+
### Architecture (A-*)
|
|
77
|
+
|
|
78
|
+
Core questions:
|
|
79
|
+
1. **Structure** — Monolith or distributed?
|
|
80
|
+
2. **Communication** — Sync or async?
|
|
81
|
+
3. **Boundaries** — How do components interact?
|
|
82
|
+
4. **Resilience** — Single points of failure?
|
|
83
|
+
|
|
84
|
+
Example prompts:
|
|
85
|
+
- "Do components need to scale independently?"
|
|
86
|
+
- "What happens if one piece goes down?"
|
|
87
|
+
|
|
88
|
+
### Technology (T-*)
|
|
89
|
+
|
|
90
|
+
Core questions:
|
|
91
|
+
1. **Stack** — What languages/frameworks?
|
|
92
|
+
2. **Databases** — What storage systems?
|
|
93
|
+
3. **Infrastructure** — Where is it hosted?
|
|
94
|
+
4. **Constraints** — Any technology mandates or prohibitions?
|
|
95
|
+
|
|
96
|
+
Example prompts:
|
|
97
|
+
- "What does your team already know well?"
|
|
98
|
+
- "Any tech debt or legacy constraints?"
|
|
99
|
+
|
|
100
|
+
### Implementation (I-*)
|
|
101
|
+
|
|
102
|
+
Core questions:
|
|
103
|
+
1. **Process** — How is code written and reviewed?
|
|
104
|
+
2. **Testing** — What testing strategy?
|
|
105
|
+
3. **CI/CD** — How is code deployed?
|
|
106
|
+
4. **Standards** — Any coding conventions?
|
|
107
|
+
|
|
108
|
+
Example prompts:
|
|
109
|
+
- "How do you ensure code quality?"
|
|
110
|
+
- "What's your release cadence?"
|
|
111
|
+
|
|
112
|
+
## Question Format
|
|
113
|
+
|
|
114
|
+
For each decision point:
|
|
115
|
+
|
|
116
|
+
```
|
|
117
|
+
Q: {question}?
|
|
118
|
+
|
|
119
|
+
Options:
|
|
120
|
+
A) {option} — {tradeoff}
|
|
121
|
+
B) {option} — {tradeoff}
|
|
122
|
+
C) {option} — {tradeoff}
|
|
123
|
+
|
|
124
|
+
[Your choice]: _
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Recording Decisions
|
|
128
|
+
|
|
129
|
+
For each answer:
|
|
130
|
+
|
|
131
|
+
```markdown
|
|
132
|
+
### X-0001: {title}
|
|
133
|
+
Supports: {parent IDs}
|
|
134
|
+
|
|
135
|
+
{rationale derived from answer}
|
|
136
|
+
|
|
137
|
+
Alternatives considered: {options not chosen}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Interview Flow
|
|
141
|
+
|
|
142
|
+
1. **Discovery** — Scan existing code/docs for context
|
|
143
|
+
2. **Questions** — Ask by section, 1-3 per section
|
|
144
|
+
3. **Clarification** — Ask follow-ups if answers are vague
|
|
145
|
+
4. **Synthesis** — Convert answers to CHOICES.md format
|
|
146
|
+
5. **Review** — Show summary, ask for corrections
|
|
147
|
+
6. **Generate** — Write CHOICES.md + PLAN.md
|
|
148
|
+
|
|
149
|
+
## Example
|
|
150
|
+
|
|
151
|
+
```
|
|
152
|
+
## Mission Questions
|
|
153
|
+
|
|
154
|
+
Q1: What problem does this solve?
|
|
155
|
+
A) Developers need faster API development
|
|
156
|
+
B) Teams need better collaboration tools
|
|
157
|
+
C) Users need simpler data visualization
|
|
158
|
+
|
|
159
|
+
User: A
|
|
160
|
+
|
|
161
|
+
Q2: Who are the primary users?
|
|
162
|
+
A) Backend developers
|
|
163
|
+
B) Full-stack teams
|
|
164
|
+
C) API product managers
|
|
165
|
+
|
|
166
|
+
User: B
|
|
167
|
+
|
|
168
|
+
Recording:
|
|
169
|
+
M-0001: Accelerate API development for full-stack teams
|
|
170
|
+
Supports: (none - top level)
|
|
171
|
+
|
|
172
|
+
Full-stack teams spend too much time on boilerplate.
|
|
173
|
+
This tool reduces API setup from hours to minutes.
|
|
174
|
+
|
|
175
|
+
[Continues through sections...]
|
|
176
|
+
|
|
177
|
+
## Summary
|
|
178
|
+
|
|
179
|
+
Generated 18 choices across 8 sections:
|
|
180
|
+
- Mission: 2
|
|
181
|
+
- User Experiences: 3
|
|
182
|
+
- Features: 5
|
|
183
|
+
- Operations: 2
|
|
184
|
+
- Data: 2
|
|
185
|
+
- Architecture: 2
|
|
186
|
+
- Technology: 1
|
|
187
|
+
- Implementation: 1
|
|
188
|
+
|
|
189
|
+
Review CHOICES.md? [y/n]
|
|
190
|
+
```
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: replan
|
|
3
|
+
description: "Gap analysis: compare CHOICES.md against current state, generate PLAN.md for next implementation phase."
|
|
4
|
+
allowed-tools: Read, Glob, Grep, Bash, Edit
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Replan — Gap Analysis & Plan Generation
|
|
8
|
+
|
|
9
|
+
Compare CHOICES.md goals against current implementation. Generate PLAN.md for next phase.
|
|
10
|
+
|
|
11
|
+
## When to Use
|
|
12
|
+
|
|
13
|
+
- Current PLAN.md is 100% complete
|
|
14
|
+
- Major scope change requires new planning
|
|
15
|
+
- User asks to "replan" or "next phase"
|
|
16
|
+
- Starting fresh implementation cycle
|
|
17
|
+
|
|
18
|
+
## Workflow
|
|
19
|
+
|
|
20
|
+
### 1. Read CHOICES.md
|
|
21
|
+
|
|
22
|
+
Parse all 8 sections, extract:
|
|
23
|
+
- Choice ID, title, decision
|
|
24
|
+
- `Supports:` dependencies
|
|
25
|
+
- Section ordering (M > UX > F > O > D > A > T > I)
|
|
26
|
+
|
|
27
|
+
### 2. Analyze Current State
|
|
28
|
+
|
|
29
|
+
Check implementation status:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# What's been committed?
|
|
33
|
+
git log --oneline -20
|
|
34
|
+
|
|
35
|
+
# What's the current structure?
|
|
36
|
+
find . -type f -name "*.ts" -o -name "*.py" -o -name "*.js" | head -50
|
|
37
|
+
|
|
38
|
+
# Any existing PLAN.md?
|
|
39
|
+
cat PLAN.md 2>/dev/null || echo "No PLAN.md"
|
|
40
|
+
|
|
41
|
+
# Memory/log of what's done?
|
|
42
|
+
cat MEMORY.md 2>/dev/null || cat .pi/memory.md 2>/dev/null || echo "No memory file"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### 3. Categorize Choices
|
|
46
|
+
|
|
47
|
+
| Status | Criteria |
|
|
48
|
+
|--------|----------|
|
|
49
|
+
| **Fulfilled** | Code exists, tests pass, documented |
|
|
50
|
+
| **Partial** | Started but incomplete |
|
|
51
|
+
| **Not started** | No implementation evidence |
|
|
52
|
+
|
|
53
|
+
### 4. Prioritize Unfulfilled
|
|
54
|
+
|
|
55
|
+
Order by:
|
|
56
|
+
1. Section priority (M > UX > F > O > D > A > T > I)
|
|
57
|
+
2. Dependencies (unblocked first)
|
|
58
|
+
3. Impact (high-impact choices first)
|
|
59
|
+
|
|
60
|
+
### 5. Generate PLAN.md
|
|
61
|
+
|
|
62
|
+
Use [plan template](../templates/PLAN.md). Group into phases:
|
|
63
|
+
|
|
64
|
+
```markdown
|
|
65
|
+
## Phase 1: {Focused Goal}
|
|
66
|
+
### Steps
|
|
67
|
+
- [ ] 1.1 {Action verb} {specific thing}
|
|
68
|
+
- [ ] 1.2 {Action verb} {specific thing}
|
|
69
|
+
|
|
70
|
+
### Gates
|
|
71
|
+
- [ ] {Testable criterion}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**Rules:**
|
|
75
|
+
- 3-7 steps per phase
|
|
76
|
+
- 1-3 gates per phase
|
|
77
|
+
- Gates must be testable (can run command, check output)
|
|
78
|
+
- Max 300 lines total
|
|
79
|
+
|
|
80
|
+
### 6. Validate Plan
|
|
81
|
+
|
|
82
|
+
Run plan validation checks:
|
|
83
|
+
- [ ] Line count ≤ 300
|
|
84
|
+
- [ ] Objective section present
|
|
85
|
+
- [ ] Each phase has Steps + Gates
|
|
86
|
+
- [ ] Steps are actionable (start with verb)
|
|
87
|
+
- [ ] Gates are testable (not subjective)
|
|
88
|
+
- [ ] Scope defined (In/Out)
|
|
89
|
+
|
|
90
|
+
### 7. Output
|
|
91
|
+
|
|
92
|
+
```
|
|
93
|
+
Gap Analysis Complete
|
|
94
|
+
|
|
95
|
+
CHOICES.md: {N} choices
|
|
96
|
+
✓ Fulfilled: {a}
|
|
97
|
+
◐ Partial: {b}
|
|
98
|
+
✗ Not started: {c}
|
|
99
|
+
|
|
100
|
+
PLAN.md generated: {M} phases, {K} tasks
|
|
101
|
+
Phase 1: {name} ({n} steps)
|
|
102
|
+
Phase 2: {name} ({n} steps)
|
|
103
|
+
...
|
|
104
|
+
|
|
105
|
+
Ready to implement. Run /choose-wisely:replan again when complete.
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Example
|
|
109
|
+
|
|
110
|
+
```
|
|
111
|
+
User: /choose-wisely:replan
|
|
112
|
+
|
|
113
|
+
Analyzing CHOICES.md...
|
|
114
|
+
M-0001: Real-time chat platform — fulfilled ✓
|
|
115
|
+
UX-0001: Channel-based messaging — fulfilled ✓
|
|
116
|
+
F-0003: Video integration — partial ◐
|
|
117
|
+
F-0008: Search — not started ✗
|
|
118
|
+
O-0012: Monitoring — not started ✗
|
|
119
|
+
|
|
120
|
+
Gap Analysis Complete
|
|
121
|
+
|
|
122
|
+
CHOICES.md: 23 choices
|
|
123
|
+
✓ Fulfilled: 8
|
|
124
|
+
◐ Partial: 2
|
|
125
|
+
✗ Not started: 13
|
|
126
|
+
|
|
127
|
+
PLAN.md generated: 3 phases, 24 tasks
|
|
128
|
+
Phase 1: Search implementation (8 steps)
|
|
129
|
+
Phase 2: Video completion (6 steps)
|
|
130
|
+
Phase 3: Monitoring setup (5 steps)
|
|
131
|
+
|
|
132
|
+
Ready to implement.
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Integration
|
|
136
|
+
|
|
137
|
+
After PLAN.md is 100% complete:
|
|
138
|
+
1. Run `/choose-wisely:replan` again for next phase
|
|
139
|
+
2. Or update CHOICES.md with new decisions first
|
|
140
|
+
3. Cycle continues until all choices fulfilled
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# CHOICES.md — Source of Plan
|
|
2
|
+
|
|
3
|
+
All project choices in priority order. Higher choices constrain lower ones.
|
|
4
|
+
Use `/choose-wisely:choose` to add, change, remove, or reorder choices.
|
|
5
|
+
Use `/choose-wisely:choose-audit` to check for contradictions and structural issues.
|
|
6
|
+
|
|
7
|
+
## Rules
|
|
8
|
+
|
|
9
|
+
- **Position = Priority**: higher constrains lower, no exceptions
|
|
10
|
+
- **Gravity rule**: changing a choice triggers cascading review
|
|
11
|
+
- **Section order is fixed**: Mission > User Experiences > Features > Operations > Data > Architecture > Technology > Implementation
|
|
12
|
+
- **Supports line required**: every choice (except top) lists IDs it directly supports
|
|
13
|
+
- **Architecture is tool-agnostic**: Architecture describes patterns; Technology names tools
|
|
14
|
+
- **No status values**: git diff is the change record
|
|
15
|
+
|
|
16
|
+
### Choice Entry Format
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
### X-0001: Title of choice
|
|
20
|
+
Supports: X-0000, Y-0000
|
|
21
|
+
|
|
22
|
+
One to two lines of rationale. Not a spec. Just why this choice was made.
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
- ID format: `PREFIX-NNNN` (globally unique 4-digit number)
|
|
26
|
+
- Prefixes: `M-` (Mission), `UX-` (User Experiences), `F-` (Features), `O-` (Operations), `D-` (Data), `A-` (Architecture), `T-` (Technology), `I-` (Implementation)
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Mission
|
|
31
|
+
<!-- Why we exist, values, principles. Everything else flows from here. -->
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## User Experiences
|
|
36
|
+
<!-- Core user journeys, interaction patterns. -->
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Features
|
|
41
|
+
<!-- Specific capabilities and behaviors. -->
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Operations
|
|
46
|
+
<!-- Automation vs human-in-loop, workflows, SLAs, moderation. -->
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Data
|
|
51
|
+
<!-- Data model, schemas, storage decisions. -->
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## Architecture
|
|
56
|
+
<!-- System design, module structure, communication patterns. Tool-agnostic. -->
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Technology
|
|
61
|
+
<!-- Tech stack, libraries, infrastructure. Names specific tools. -->
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Implementation
|
|
66
|
+
<!-- Dev practices, coding standards, deployment patterns. -->
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Plan
|
|
2
|
+
|
|
3
|
+
## Objective
|
|
4
|
+
|
|
5
|
+
{What you're building, why, and expected outcome in 2-5 sentences.}
|
|
6
|
+
|
|
7
|
+
## Scope
|
|
8
|
+
|
|
9
|
+
**In Scope:**
|
|
10
|
+
- {Specific deliverable 1}
|
|
11
|
+
- {Specific deliverable 2}
|
|
12
|
+
|
|
13
|
+
**Out of Scope:**
|
|
14
|
+
- {Explicitly excluded item}
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Phase 1: {Phase Name}
|
|
19
|
+
|
|
20
|
+
### Steps
|
|
21
|
+
- [ ] 1.1 {Concrete action starting with verb}
|
|
22
|
+
- [ ] 1.2 {Concrete action starting with verb}
|
|
23
|
+
- [ ] 1.3 {Concrete action starting with verb}
|
|
24
|
+
|
|
25
|
+
### Gates
|
|
26
|
+
- [ ] {Testable criterion with command or check}
|
|
27
|
+
- [ ] {Testable criterion with command or check}
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Current Phase: 1
|
|
32
|
+
## Status: not-started
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Success Criteria
|
|
37
|
+
|
|
38
|
+
Overall verification that the objective is achieved:
|
|
39
|
+
|
|
40
|
+
- [ ] {Final testable criterion 1}
|
|
41
|
+
- [ ] {Final testable criterion 2}
|
|
42
|
+
- [ ] {Final testable criterion 3}
|