konductor 0.6.0 → 0.7.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.
@@ -0,0 +1,265 @@
1
+ # Planning Guide — Decomposing Phases into Execution Plans
2
+
3
+ This guide helps you transform a phase goal into concrete, executable plans.
4
+
5
+ ## Core Philosophy: Vertical Slices
6
+
7
+ **Prefer vertical slices over horizontal layers.**
8
+
9
+ - **Bad (horizontal):** Plan 1 = data models, Plan 2 = API endpoints, Plan 3 = UI components
10
+ - **Good (vertical):** Plan 1 = user registration (model + API + UI), Plan 2 = user login (model + API + UI)
11
+
12
+ **Why vertical?**
13
+ - Each plan delivers a working feature end-to-end
14
+ - Plans can be executed in parallel (fewer dependencies)
15
+ - Users can test functionality incrementally
16
+ - Rollback is easier (one feature vs. broken layer)
17
+
18
+ **When to use horizontal:**
19
+ - Foundation work that everything depends on (database setup, auth middleware)
20
+ - Cross-cutting concerns (logging, error handling)
21
+ - Infrastructure (deployment, CI/CD)
22
+
23
+ ## Wave Assignment
24
+
25
+ Plans execute in waves. Wave dependencies must form a DAG (directed acyclic graph).
26
+
27
+ **Rules:**
28
+ 1. Plans with no dependencies → Wave 1
29
+ 2. Plans depending only on Wave 1 outputs → Wave 2
30
+ 3. Plans depending on Wave N outputs → Wave N+1
31
+ 4. A plan can depend on multiple waves; use the max wave number + 1
32
+
33
+ **Goal:** Minimize wave count. More parallelism = faster execution.
34
+
35
+ **Example:**
36
+ - Wave 1: User model + migrations, Product model + migrations (parallel)
37
+ - Wave 2: Auth middleware (depends on User), Shopping cart (depends on User + Product)
38
+ - Wave 3: Checkout flow (depends on Shopping cart)
39
+
40
+ ## Task Sizing
41
+
42
+ Each plan contains 2-5 tasks. Each task should take 15-60 minutes of execution time.
43
+
44
+ **If a plan would need more than 5 tasks:** Split it into multiple plans in the same wave.
45
+
46
+ **Task structure:**
47
+ - **files:** Which files to modify/create
48
+ - **action:** What to do (be specific)
49
+ - **verify:** How to check success (command to run)
50
+ - **done:** What "done" looks like (observable outcome)
51
+
52
+ **Example task:**
53
+ ```markdown
54
+ ### Task 2: Add password hashing to User model
55
+
56
+ - **files:** `src/models/user.rs`
57
+ - **action:** Import bcrypt crate, add `hash_password` method to User impl, call it in `new` constructor
58
+ - **verify:** `cargo test user::test_password_hashing`
59
+ - **done:** Passwords are hashed with bcrypt before storage
60
+ ```
61
+
62
+ ## Plan File Format
63
+
64
+ Each plan is a markdown file with TOML frontmatter and a structured body.
65
+
66
+ **Frontmatter fields:**
67
+ - `phase`: Phase identifier (e.g., "01-auth-system")
68
+ - `plan`: Plan number within the phase (1, 2, 3...)
69
+ - `wave`: Execution wave (1, 2, 3...)
70
+ - `depends_on`: List of plan numbers this plan depends on (e.g., `[1, 2]`)
71
+ - `type`: Either "execute" (standard implementation) or "tdd" (test-driven)
72
+ - `autonomous`: Boolean, true if executor can proceed without human input
73
+ - `requirements`: List of REQ-XX identifiers this plan addresses
74
+ - `files_modified`: List of files this plan will touch (helps with merge conflict prediction)
75
+ - `must_haves.truths`: Observable truths that must be true when done
76
+ - `must_haves.artifacts`: Files that must exist
77
+ - `must_haves.key_links`: Wiring checks (A imports B, C calls D)
78
+
79
+ **Complete example:**
80
+ ```markdown
81
+ +++
82
+ phase = "01-auth-system"
83
+ plan = 1
84
+ wave = 1
85
+ depends_on = []
86
+ type = "execute"
87
+ autonomous = true
88
+ requirements = ["REQ-01", "REQ-02"]
89
+ files_modified = ["src/models/user.rs", "src/db/migrations/001_users.sql"]
90
+
91
+ [must_haves]
92
+ truths = ["Users can register with email and password", "Passwords are hashed with bcrypt"]
93
+ artifacts = ["src/models/user.rs", "src/db/migrations/001_users.sql"]
94
+ key_links = ["User model imported by auth routes", "bcrypt used in user.rs"]
95
+ +++
96
+
97
+ # Plan 01: User Model and Migrations
98
+
99
+ ## Goal
100
+ Create the User data model and database schema to support user registration.
101
+
102
+ ## Tasks
103
+
104
+ ### Task 1: Create User struct
105
+
106
+ - **files:** `src/models/user.rs`
107
+ - **action:** Define User struct with fields: id (UUID), email (String), password_hash (String), created_at (DateTime)
108
+ - **verify:** `cargo check` passes
109
+ - **done:** User struct compiles
110
+
111
+ ### Task 2: Add password hashing
112
+
113
+ - **files:** `src/models/user.rs`
114
+ - **action:** Import bcrypt, add `hash_password` method, call in constructor
115
+ - **verify:** `cargo test user::test_password_hashing`
116
+ - **done:** Passwords are hashed before storage
117
+
118
+ ### Task 3: Create migration
119
+
120
+ - **files:** `src/db/migrations/001_users.sql`
121
+ - **action:** Write CREATE TABLE users with columns matching User struct
122
+ - **verify:** `sqlx migrate run` succeeds
123
+ - **done:** users table exists in database
124
+
125
+ ### Task 4: Wire User model to auth routes
126
+
127
+ - **files:** `src/routes/auth.rs`
128
+ - **action:** Import User model, use it in registration handler
129
+ - **verify:** Compilation succeeds, User is referenced
130
+ - **done:** Registration route can create User instances
131
+ ```
132
+
133
+ ## Goal-Backward Methodology
134
+
135
+ Work backward from the phase goal to derive concrete requirements.
136
+
137
+ **Steps:**
138
+ 1. **State the goal:** "Users can register with email and password"
139
+ 2. **Derive observable truths:**
140
+ - A user record exists in the database
141
+ - The password is hashed, not plaintext
142
+ - The registration endpoint returns success
143
+ 3. **Derive required artifacts:**
144
+ - `src/models/user.rs` (User struct)
145
+ - `src/db/migrations/001_users.sql` (users table)
146
+ - `src/routes/auth.rs` (registration endpoint)
147
+ 4. **Derive required wiring:**
148
+ - User model imported by auth routes
149
+ - bcrypt library used in User model
150
+ - Registration route calls User::new
151
+ 5. **Identify key links:**
152
+ - "User model imported by auth routes"
153
+ - "bcrypt used in user.rs"
154
+ - "POST /auth/register returns 201"
155
+
156
+ Use these to populate the `must_haves` section of the plan frontmatter.
157
+
158
+ ## Requirement Coverage
159
+
160
+ Every requirement from `.konductor/requirements.md` must appear in at least one plan's `requirements` field.
161
+
162
+ **Check coverage:**
163
+ 1. List all REQ-XX identifiers from requirements.md
164
+ 2. Collect all `requirements` arrays from plan frontmatter
165
+ 3. Ensure every REQ-XX appears at least once
166
+ 4. If a requirement is missing, add a plan or extend an existing plan
167
+
168
+ **Multi-plan requirements:**
169
+ A requirement can span multiple plans. Example: "REQ-05: Users can manage their profile" might be split into:
170
+ - Plan 3: View profile (requirements = ["REQ-05"])
171
+ - Plan 4: Edit profile (requirements = ["REQ-05"])
172
+
173
+ ## TDD Detection
174
+
175
+ If a task can be expressed as "expect(fn(input)).toBe(output)", make it a TDD plan.
176
+
177
+ **Indicators:**
178
+ - Pure functions (no I/O)
179
+ - Clear input/output contract
180
+ - Algorithmic logic (sorting, parsing, validation)
181
+ - Data transformations
182
+
183
+ **TDD plan differences:**
184
+ - `type = "tdd"` in frontmatter
185
+ - First task writes tests
186
+ - Remaining tasks implement to pass tests
187
+ - Verification is `cargo test` or equivalent
188
+
189
+ **Example TDD task:**
190
+ ```markdown
191
+ ### Task 1: Write password validation tests
192
+
193
+ - **files:** `src/validation/password_test.rs`
194
+ - **action:** Write tests for: min 8 chars, has uppercase, has number, has special char
195
+ - **verify:** Tests exist and fail
196
+ - **done:** 4 test cases written
197
+
198
+ ### Task 2: Implement password validation
199
+
200
+ - **files:** `src/validation/password.rs`
201
+ - **action:** Write validate_password function to satisfy tests
202
+ - **verify:** `cargo test validation::password` passes
203
+ - **done:** All password validation tests pass
204
+ ```
205
+
206
+ ## Interface Context
207
+
208
+ When plans depend on each other, include interface definitions so executors don't need to explore the codebase.
209
+
210
+ **Include in dependent plans:**
211
+ - Type signatures
212
+ - Function signatures
213
+ - API contracts (request/response shapes)
214
+ - Event names and payloads
215
+
216
+ **Example:**
217
+ ```markdown
218
+ ## Dependencies
219
+
220
+ This plan depends on Plan 1 (User model). Expected interface:
221
+
222
+ ```rust
223
+ pub struct User {
224
+ pub id: Uuid,
225
+ pub email: String,
226
+ // password_hash is private
227
+ }
228
+
229
+ impl User {
230
+ pub fn new(email: String, password: String) -> Result<Self, Error>;
231
+ pub fn verify_password(&self, password: &str) -> bool;
232
+ }
233
+ ```
234
+
235
+ Use this interface in Task 2 when implementing the login handler.
236
+ ```
237
+
238
+ ## Anti-Patterns to Avoid
239
+
240
+ **1. God plans:** A plan that touches 20+ files or has 10+ tasks. Split it.
241
+
242
+ **2. Circular dependencies:** Plan A depends on Plan B, Plan B depends on Plan A. Use waves to break cycles.
243
+
244
+ **3. Vague tasks:** "Set up authentication" is too vague. Be specific: "Add bcrypt to Cargo.toml", "Create User model", etc.
245
+
246
+ **4. Missing verification:** Every task needs a `verify` command. "Manual testing" is not sufficient.
247
+
248
+ **5. Underspecified must_haves:** "The feature works" is not an observable truth. Be concrete: "POST /auth/register returns 201 with user JSON".
249
+
250
+ **6. Ignoring research:** If research.md exists, use it. Don't re-discover libraries or patterns.
251
+
252
+ ## Checklist for Completed Plans
253
+
254
+ Before finalizing plans, verify:
255
+
256
+ - [ ] Every plan has valid TOML frontmatter
257
+ - [ ] Wave numbers form a valid DAG (no cycles)
258
+ - [ ] Each plan has 2-5 tasks
259
+ - [ ] Each task has files, action, verify, and done
260
+ - [ ] Every requirement from requirements.md is covered
261
+ - [ ] `must_haves` section is complete and observable
262
+ - [ ] Dependent plans include interface context
263
+ - [ ] File paths in `files_modified` are realistic
264
+ - [ ] Verification commands are concrete (not "manual testing")
265
+ - [ ] Plans prefer vertical slices over horizontal layers
@@ -0,0 +1,400 @@
1
+ # Verification Patterns — 3-Level Verification Framework
2
+
3
+ This guide defines how to verify that phase execution actually achieved its goals, not just created files.
4
+
5
+ ## The Three Levels
6
+
7
+ Verification proceeds in three increasingly rigorous levels:
8
+
9
+ ### Level 1: Exists
10
+ **Question:** Is the artifact present?
11
+
12
+ **Checks:**
13
+ - File exists at expected path
14
+ - Directory structure is correct
15
+ - Database tables exist
16
+ - API endpoints are defined
17
+
18
+ **Commands:**
19
+ ```bash
20
+ # File existence
21
+ [ -f src/models/user.rs ] && echo "OK" || echo "MISSING"
22
+
23
+ # Directory structure
24
+ [ -d src/routes ] && [ -d src/models ] && echo "OK"
25
+
26
+ # Database table (PostgreSQL)
27
+ psql -d mydb -c "\dt users" | grep -q users && echo "OK"
28
+
29
+ # API endpoint defined (grep for route definition)
30
+ grep -r "POST.*auth/register" src/routes/ && echo "OK"
31
+ ```
32
+
33
+ **When Level 1 fails:** The most basic requirement is unmet. Execution did not complete.
34
+
35
+ ### Level 2: Substantive
36
+ **Question:** Is the artifact a real implementation, not a stub?
37
+
38
+ **Checks:**
39
+ - File has meaningful content (>minimum line count)
40
+ - Not just comments or placeholders
41
+ - No TODO/FIXME/PLACEHOLDER patterns
42
+ - Contains expected code structures (functions, classes, exports)
43
+
44
+ **Thresholds:**
45
+ - Model files: >20 lines
46
+ - Route handlers: >15 lines
47
+ - Component files: >25 lines
48
+ - Test files: >30 lines
49
+ - Migration files: >10 lines
50
+
51
+ **Anti-patterns to detect:**
52
+ ```rust
53
+ // STUB: Not substantive
54
+ pub struct User {
55
+ // TODO: implement fields
56
+ }
57
+
58
+ // REAL: Substantive
59
+ pub struct User {
60
+ pub id: Uuid,
61
+ pub email: String,
62
+ password_hash: String,
63
+ created_at: DateTime<Utc>,
64
+ }
65
+ ```
66
+
67
+ **Commands:**
68
+ ```bash
69
+ # Line count check (exclude comments)
70
+ lines=$(grep -v '^[[:space:]]*#' src/models/user.rs | grep -v '^[[:space:]]*$' | wc -l)
71
+ [ "$lines" -gt 20 ] && echo "OK" || echo "STUB"
72
+
73
+ # TODO/FIXME detection
74
+ grep -i 'TODO\|FIXME\|PLACEHOLDER\|STUB' src/models/user.rs && echo "INCOMPLETE"
75
+
76
+ # Meaningful structure (has at least one pub fn)
77
+ grep -q 'pub fn' src/models/user.rs && echo "OK"
78
+ ```
79
+
80
+ **When Level 2 fails:** Execution created files but didn't implement them properly. This is common with autonomous executors that hit errors.
81
+
82
+ ### Level 3: Wired
83
+ **Question:** Is the artifact connected to the rest of the system?
84
+
85
+ **Checks:**
86
+ - Imported by other files
87
+ - Actually used (not just imported)
88
+ - Part of the call graph
89
+ - No orphaned code
90
+
91
+ **Common wiring patterns:**
92
+
93
+ **Component → API fetch:**
94
+ ```javascript
95
+ // In component file
96
+ import { fetchUsers } from '../api/users'
97
+ // And uses it
98
+ const users = await fetchUsers()
99
+ ```
100
+
101
+ **API → Database query:**
102
+ ```python
103
+ # In API handler
104
+ from models.user import User
105
+ # And uses it
106
+ user = User.query.filter_by(email=email).first()
107
+ ```
108
+
109
+ **Form → Handler:**
110
+ ```rust
111
+ // In form component
112
+ <form action="/auth/register" method="POST">
113
+ // And in routes
114
+ pub async fn register(form: Form<RegisterData>) -> Response
115
+ ```
116
+
117
+ **State → Render:**
118
+ ```jsx
119
+ // In state file
120
+ export const userSlice = createSlice({ ... })
121
+ // And in component
122
+ import { selectUser } from '../store/userSlice'
123
+ const user = useSelector(selectUser)
124
+ ```
125
+
126
+ **Commands:**
127
+ ```bash
128
+ # Check if User model is imported anywhere
129
+ grep -r "use.*models::user" src/ --exclude-dir=models | wc -l
130
+
131
+ # Check if User is actually used (not just imported)
132
+ # Look for User:: or User.new or similar
133
+ grep -r "User::\|User\.new\|User\.find" src/ | wc -l
134
+
135
+ # Check bidirectional wiring (component imports API, API returns component data)
136
+ grep -q "fetchUsers" src/components/UserList.tsx && \
137
+ grep -q "export.*fetchUsers" src/api/users.ts && echo "WIRED"
138
+ ```
139
+
140
+ **When Level 3 fails:** Execution implemented features but they're isolated. Integration work is missing.
141
+
142
+ ## Must-Haves Derivation
143
+
144
+ Every plan should have a `must_haves` section in its frontmatter:
145
+
146
+ ```toml
147
+ [must_haves]
148
+ truths = [...]
149
+ artifacts = [...]
150
+ key_links = [...]
151
+ ```
152
+
153
+ Verification uses these to determine what to check.
154
+
155
+ ### Option A: From Plan Frontmatter
156
+
157
+ If the plan has a `must_haves` section, use it directly.
158
+
159
+ **Example plan frontmatter:**
160
+ ```toml
161
+ [must_haves]
162
+ truths = ["Users can register with email", "Passwords are hashed"]
163
+ artifacts = ["src/models/user.rs", "src/routes/auth.rs"]
164
+ key_links = ["User imported by auth routes", "bcrypt used in user.rs"]
165
+ ```
166
+
167
+ **Verification:**
168
+ 1. For each truth, derive a test (manual or automated)
169
+ 2. For each artifact, check Levels 1-3
170
+ 3. For each key_link, verify the connection exists
171
+
172
+ ### Option B: From Roadmap Success Criteria
173
+
174
+ If the plan doesn't have `must_haves`, fall back to the phase's success criteria from `roadmap.md`.
175
+
176
+ **Example roadmap:**
177
+ ```markdown
178
+ ## Phase 01: Authentication System
179
+
180
+ Success criteria:
181
+ - Users can register with email and password
182
+ - Users can log in and receive a session token
183
+ - Passwords are securely hashed
184
+ ```
185
+
186
+ **Derive must_haves:**
187
+ - **truths:** Each success criterion becomes a truth
188
+ - **artifacts:** Infer from common patterns (User model, auth routes, migrations)
189
+ - **key_links:** Infer from dependencies (auth routes use User model)
190
+
191
+ ### Option C: Goal-Backward Derivation
192
+
193
+ If neither plan frontmatter nor roadmap success criteria are available, work backward from the phase goal.
194
+
195
+ **Steps:**
196
+ 1. Read the phase goal from roadmap.md
197
+ 2. Ask: "What must be true for this goal to be achieved?"
198
+ 3. Ask: "What files must exist?"
199
+ 4. Ask: "How must those files be connected?"
200
+
201
+ **Example:**
202
+ - **Goal:** "Implement user authentication"
203
+ - **Truths:** Users can register, Users can log in, Sessions are managed
204
+ - **Artifacts:** User model, auth routes, session middleware
205
+ - **Key links:** Auth routes import User, Middleware validates sessions
206
+
207
+ ## Gap Structuring
208
+
209
+ When verification finds issues, structure them as "gaps" for the next planning cycle.
210
+
211
+ **Gap format:**
212
+ ```toml
213
+ [[gaps]]
214
+ truth = "Users can register with email"
215
+ status = "failed"
216
+ reason = "Registration endpoint returns 500"
217
+ artifacts = ["src/routes/auth.rs"]
218
+ missing = ["Error handling", "Email validation"]
219
+ ```
220
+
221
+ **Fields:**
222
+ - `truth`: Which must_have truth failed
223
+ - `status`: "failed" or "partial" or "incomplete"
224
+ - `reason`: Specific error or issue
225
+ - `artifacts`: Which files are involved
226
+ - `missing`: What needs to be added/fixed
227
+
228
+ **Write gaps to:** `.konductor/phases/{phase}/gaps.toml`
229
+
230
+ The next planning cycle can read this file and create gap-closure plans.
231
+
232
+ ## Verification Commands by Language
233
+
234
+ ### Rust
235
+ ```bash
236
+ # Compilation check
237
+ cargo check
238
+
239
+ # Test execution
240
+ cargo test
241
+
242
+ # Import check
243
+ grep -r "use crate::models::User" src/
244
+
245
+ # Usage check
246
+ grep -r "User::" src/ | grep -v "^src/models/user.rs"
247
+ ```
248
+
249
+ ### Python
250
+ ```bash
251
+ # Import check
252
+ python -c "from models.user import User; print('OK')"
253
+
254
+ # Test execution
255
+ pytest tests/
256
+
257
+ # Import usage
258
+ grep -r "from models.user import" src/ | wc -l
259
+
260
+ # Usage check
261
+ grep -r "User(" src/ | grep -v "models/user.py"
262
+ ```
263
+
264
+ ### JavaScript/TypeScript
265
+ ```bash
266
+ # Compilation check (TypeScript)
267
+ npx tsc --noEmit
268
+
269
+ # Test execution
270
+ npm test
271
+
272
+ # Import check
273
+ grep -r "import.*from.*models/user" src/
274
+
275
+ # Usage check
276
+ grep -r "new User\|User\.find\|User\.create" src/
277
+ ```
278
+
279
+ ### Go
280
+ ```bash
281
+ # Compilation check
282
+ go build ./...
283
+
284
+ # Test execution
285
+ go test ./...
286
+
287
+ # Import check
288
+ grep -r "\"myapp/models\"" . | wc -l
289
+
290
+ # Usage check
291
+ grep -r "models\.User" . | grep -v "models/user.go"
292
+ ```
293
+
294
+ ## Example Verification Report
295
+
296
+ A verification report should follow this structure:
297
+
298
+ ```markdown
299
+ # Verification Report: Phase 01 — Authentication System
300
+
301
+ **Status:** Issues Found
302
+ **Date:** 2026-03-19
303
+ **Plans Verified:** 3
304
+
305
+ ## Level 1: Exists ✓
306
+
307
+ All expected artifacts are present:
308
+ - ✓ src/models/user.rs
309
+ - ✓ src/routes/auth.rs
310
+ - ✓ src/db/migrations/001_users.sql
311
+ - ✓ tests/auth_test.rs
312
+
313
+ ## Level 2: Substantive ✓
314
+
315
+ All files contain real implementations:
316
+ - ✓ User model has 45 lines, includes fields and methods
317
+ - ✓ Auth routes have 67 lines, no TODOs
318
+ - ✓ Migration file creates users table with all columns
319
+ - ✓ Tests have 52 lines with 6 test cases
320
+
321
+ ## Level 3: Wired ⚠
322
+
323
+ Issues found:
324
+ - ⚠ User model is imported by auth routes (OK)
325
+ - ⚠ Auth routes use User::new (OK)
326
+ - ✗ Registration endpoint returns 500 error
327
+ - ✗ No middleware validates session tokens
328
+
329
+ ## Gaps
330
+
331
+ ```toml
332
+ [[gaps]]
333
+ truth = "Users can register with email"
334
+ status = "failed"
335
+ reason = "POST /auth/register returns 500: database connection error"
336
+ artifacts = ["src/routes/auth.rs", "src/db/connection.rs"]
337
+ missing = ["Database connection pool initialization", "Error handling"]
338
+
339
+ [[gaps]]
340
+ truth = "Sessions are validated on protected routes"
341
+ status = "incomplete"
342
+ reason = "Session middleware exists but is not applied to routes"
343
+ artifacts = ["src/middleware/session.rs", "src/main.rs"]
344
+ missing = ["Apply middleware to protected routes"]
345
+ ```
346
+
347
+ ## Next Steps
348
+
349
+ 1. Run `konductor plan phase 01 --gaps` to create gap-closure plans
350
+ 2. Or manually fix: Initialize DB connection pool in main.rs
351
+ 3. Re-run verification after fixes
352
+ ```
353
+
354
+ ## Verification Automation
355
+
356
+ Verification should be automated where possible.
357
+
358
+ **Pattern: Verification script per plan**
359
+
360
+ Create `.konductor/phases/{phase}/verify-plan-{n}.sh`:
361
+ ```bash
362
+ #!/bin/bash
363
+ set -e
364
+
365
+ # Level 1: Exists
366
+ [ -f src/models/user.rs ] || { echo "FAIL: user.rs missing"; exit 1; }
367
+
368
+ # Level 2: Substantive
369
+ lines=$(grep -v '^[[:space:]]*//' src/models/user.rs | grep -v '^[[:space:]]*$' | wc -l)
370
+ [ "$lines" -gt 20 ] || { echo "FAIL: user.rs is stub"; exit 1; }
371
+
372
+ # Level 3: Wired
373
+ grep -q "User::" src/routes/auth.rs || { echo "FAIL: User not used in auth"; exit 1; }
374
+
375
+ # Truth verification
376
+ cargo test auth::test_register || { echo "FAIL: registration test failed"; exit 1; }
377
+
378
+ echo "PASS: Plan 1 verified"
379
+ ```
380
+
381
+ Then run: `bash .konductor/phases/{phase}/verify-plan-{n}.sh`
382
+
383
+ ## Verification vs. Testing
384
+
385
+ **Testing** checks that code is correct (unit tests, integration tests).
386
+ **Verification** checks that execution achieved the phase goal (end-to-end validation).
387
+
388
+ **Testing:**
389
+ - Runs during execution (per task)
390
+ - Checks individual functions
391
+ - Passes/fails per test case
392
+ - Developer-focused
393
+
394
+ **Verification:**
395
+ - Runs after all plans execute
396
+ - Checks the entire phase
397
+ - Validates against must_haves
398
+ - User-focused (does it deliver the feature?)
399
+
400
+ **Both are necessary.** Tests catch bugs. Verification catches gaps.