sequant 2.0.0 → 2.1.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.
Files changed (61) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/README.md +7 -6
  4. package/dist/bin/cli.js +2 -1
  5. package/dist/marketplace/external_plugins/sequant/.claude-plugin/plugin.json +1 -1
  6. package/dist/marketplace/external_plugins/sequant/.mcp.json +6 -0
  7. package/dist/marketplace/external_plugins/sequant/README.md +58 -8
  8. package/dist/marketplace/external_plugins/sequant/hooks/post-tool.sh +19 -8
  9. package/dist/marketplace/external_plugins/sequant/hooks/pre-tool.sh +36 -49
  10. package/dist/marketplace/external_plugins/sequant/skills/_shared/references/subagent-types.md +158 -48
  11. package/dist/marketplace/external_plugins/sequant/skills/assess/SKILL.md +354 -352
  12. package/dist/marketplace/external_plugins/sequant/skills/exec/SKILL.md +1155 -33
  13. package/dist/marketplace/external_plugins/sequant/skills/fullsolve/SKILL.md +35 -4
  14. package/dist/marketplace/external_plugins/sequant/skills/qa/SKILL.md +2157 -104
  15. package/dist/marketplace/external_plugins/sequant/skills/qa/scripts/quality-checks.sh +1 -1
  16. package/dist/marketplace/external_plugins/sequant/skills/setup/SKILL.md +386 -0
  17. package/dist/marketplace/external_plugins/sequant/skills/solve/SKILL.md +38 -664
  18. package/dist/marketplace/external_plugins/sequant/skills/spec/SKILL.md +505 -120
  19. package/dist/marketplace/external_plugins/sequant/skills/test/SKILL.md +246 -1
  20. package/dist/marketplace/external_plugins/sequant/skills/testgen/SKILL.md +138 -1
  21. package/dist/src/commands/dashboard.js +1 -1
  22. package/dist/src/commands/doctor.js +1 -1
  23. package/dist/src/commands/init.js +10 -10
  24. package/dist/src/commands/logs.js +1 -1
  25. package/dist/src/commands/run.js +49 -39
  26. package/dist/src/commands/state.js +3 -3
  27. package/dist/src/commands/status.js +5 -5
  28. package/dist/src/commands/sync.js +8 -8
  29. package/dist/src/commands/update.js +16 -16
  30. package/dist/src/lib/cli-ui.js +20 -19
  31. package/dist/src/lib/merge-check/index.js +2 -2
  32. package/dist/src/lib/settings.d.ts +8 -0
  33. package/dist/src/lib/settings.js +1 -0
  34. package/dist/src/lib/shutdown.js +1 -1
  35. package/dist/src/lib/templates.js +2 -0
  36. package/dist/src/lib/wizard.js +6 -4
  37. package/dist/src/lib/workflow/batch-executor.d.ts +9 -1
  38. package/dist/src/lib/workflow/batch-executor.js +39 -2
  39. package/dist/src/lib/workflow/log-writer.js +6 -6
  40. package/dist/src/lib/workflow/metrics-writer.js +5 -3
  41. package/dist/src/lib/workflow/phase-executor.d.ts +1 -1
  42. package/dist/src/lib/workflow/phase-executor.js +52 -22
  43. package/dist/src/lib/workflow/platforms/github.js +5 -1
  44. package/dist/src/lib/workflow/state-cleanup.js +1 -1
  45. package/dist/src/lib/workflow/state-manager.js +15 -13
  46. package/dist/src/lib/workflow/state-rebuild.js +2 -2
  47. package/dist/src/lib/workflow/types.d.ts +27 -0
  48. package/dist/src/lib/workflow/worktree-manager.js +40 -41
  49. package/dist/src/lib/worktree-isolation.d.ts +130 -0
  50. package/dist/src/lib/worktree-isolation.js +310 -0
  51. package/package.json +24 -14
  52. package/templates/agents/sequant-explorer.md +23 -0
  53. package/templates/agents/sequant-implementer.md +18 -0
  54. package/templates/agents/sequant-qa-checker.md +24 -0
  55. package/templates/agents/sequant-testgen.md +25 -0
  56. package/templates/scripts/cleanup-worktree.sh +18 -0
  57. package/templates/skills/_shared/references/subagent-types.md +158 -48
  58. package/templates/skills/exec/SKILL.md +72 -6
  59. package/templates/skills/qa/SKILL.md +8 -217
  60. package/templates/skills/spec/SKILL.md +446 -120
  61. package/templates/skills/testgen/SKILL.md +138 -1
@@ -12,9 +12,10 @@ allowed-tools:
12
12
  - Grep
13
13
  - Edit
14
14
  - Write
15
- # Build and test
15
+ # Build, lint, and test
16
16
  - Bash(npm test:*)
17
17
  - Bash(npm run build:*)
18
+ - Bash(npm run lint:*)
18
19
  - Bash(npm install:*)
19
20
  - Bash(npx tsc:*)
20
21
  # Git operations
@@ -38,7 +39,7 @@ allowed-tools:
38
39
  - mcp__context7__* # Library documentation lookup - falls back to web search if unavailable
39
40
  - mcp__sequential-thinking__* # Complex reasoning - falls back to standard analysis if unavailable
40
41
  # Task management
41
- - Task(general-purpose)
42
+ - Agent(sequant-implementer)
42
43
  - TodoWrite
43
44
  ---
44
45
 
@@ -116,9 +117,38 @@ Invocation:
116
117
  - `/exec <freeform description>`:
117
118
  - Treat the text as a lightweight description + AC if no issue context is available.
118
119
 
120
+ ## Orchestration Context
121
+
122
+ When running as part of an orchestrated workflow (e.g., `sequant run` or `/fullsolve`), this skill receives environment variables that indicate the orchestration context:
123
+
124
+ | Environment Variable | Description | Example Value |
125
+ |---------------------|-------------|---------------|
126
+ | `SEQUANT_ORCHESTRATOR` | The orchestrator invoking this skill | `sequant-run` |
127
+ | `SEQUANT_PHASE` | Current phase in the workflow | `exec` |
128
+ | `SEQUANT_ISSUE` | Issue number being processed | `123` |
129
+ | `SEQUANT_WORKTREE` | Path to the feature worktree | `/path/to/worktrees/feature/...` |
130
+ | `SEQUANT_BASE_BRANCH` | Base branch for worktree (if custom) | `feature/dashboard` |
131
+
132
+ **Behavior when orchestrated (SEQUANT_ORCHESTRATOR is set):**
133
+
134
+ 1. **Skip pre-flight git checks** - The orchestrator has already verified git state
135
+ 2. **Skip worktree creation** - Orchestrator creates worktrees before invoking skills
136
+ 3. **Use provided worktree path** - Work in `SEQUANT_WORKTREE` instead of creating a new one
137
+ 4. **Reduce GitHub comment frequency** - Defer progress updates to the orchestrator
138
+ 5. **Trust issue context** - The orchestrator has already fetched and validated issue data
139
+
140
+ **Behavior when standalone (SEQUANT_ORCHESTRATOR is NOT set):**
141
+
142
+ - Perform all pre-flight checks
143
+ - Create worktree if needed
144
+ - Post progress updates to GitHub
145
+ - Fetch fresh issue context
146
+
119
147
  ### 0. Pre-flight Check (After Context Restoration)
120
148
 
121
- **CRITICAL:** If continuing from a restored/summarized conversation, verify git state first:
149
+ **Skip this section if `SEQUANT_ORCHESTRATOR` is set** - the orchestrator has already performed these checks.
150
+
151
+ **CRITICAL:** If continuing from a restored/summarized conversation (standalone mode), verify git state first:
122
152
 
123
153
  ```bash
124
154
  # Check current state - are we in a worktree or main repo?
@@ -134,6 +164,66 @@ git branch -a | grep -i "<issue-number>" || true
134
164
 
135
165
  **If PR already merged:** The issue may be complete - verify and close if so.
136
166
 
167
+ ### 0a. Stale Branch Detection (Warning Only)
168
+
169
+ **Skip this section if `SEQUANT_ORCHESTRATOR` is set** - the orchestrator handles branch freshness checks.
170
+
171
+ **Purpose:** Warn when starting implementation on a feature branch that is significantly behind main. This helps developers rebase early rather than discovering conflicts late in the workflow.
172
+
173
+ **Note:** Unlike `/qa` and `/test`, `/exec` **warns but does not block** — starting implementation on a slightly stale branch is acceptable since rebasing can happen before PR creation.
174
+
175
+ **Detection:**
176
+
177
+ ```bash
178
+ # Ensure we have latest remote state
179
+ git fetch origin 2>/dev/null || true
180
+
181
+ # Count commits behind main (only if we're in a worktree, not on main)
182
+ current_branch=$(git rev-parse --abbrev-ref HEAD)
183
+ if [[ "$current_branch" != "main" && "$current_branch" != "master" ]]; then
184
+ behind=$(git rev-list --count HEAD..origin/main 2>/dev/null || echo "0")
185
+ echo "Feature branch is $behind commits behind main"
186
+ fi
187
+ ```
188
+
189
+ **Threshold Configuration:**
190
+
191
+ The stale branch threshold is configurable in `.sequant/settings.json`:
192
+
193
+ ```json
194
+ {
195
+ "run": {
196
+ "staleBranchThreshold": 5
197
+ }
198
+ }
199
+ ```
200
+
201
+ Default: 5 commits
202
+
203
+ **Behavior:**
204
+
205
+ | Commits Behind | Action |
206
+ |----------------|--------|
207
+ | 0 | ✅ Proceed normally |
208
+ | 1 to threshold | ℹ️ **Info:** "Feature branch is N commits behind main." |
209
+ | > threshold | ⚠️ **Warning:** "Feature branch is N commits behind main (threshold: T). Consider rebasing before continuing: `git fetch origin && git rebase origin/main`" |
210
+
211
+ **Important:** `/exec` never blocks on stale branches. It warns to help developers make informed decisions about rebasing.
212
+
213
+ **Output Format:**
214
+
215
+ ```markdown
216
+ ### Stale Branch Check
217
+
218
+ | Check | Value |
219
+ |-------|-------|
220
+ | Commits behind main | N |
221
+ | Threshold | T |
222
+ | Status | ✅ OK / ℹ️ Info / ⚠️ Warning |
223
+
224
+ [Info/warning message if applicable]
225
+ ```
226
+
137
227
  ### 1. Check Implementation Readiness
138
228
 
139
229
  **FIRST STEP:** Review the issue readiness and proceed with implementation.
@@ -160,34 +250,263 @@ git branch -a | grep -i "<issue-number>" || true
160
250
  - Issue is already closed
161
251
  - No acceptance criteria exist and cannot be inferred
162
252
 
163
- ### 2. Re-establish Context
253
+ ### 2. Re-establish Context (with Parallel Optimization)
254
+
255
+ **Performance Optimization:** When creating a new worktree, gather context in parallel with worktree creation to reduce setup time by ~5-10 seconds.
256
+
257
+ #### Parallel Context Gathering Pattern
258
+
259
+ When worktree creation is needed (standalone mode, no existing worktree):
260
+
261
+ ```
262
+ 1. Start worktree creation in background → runs ~30s (npm install)
263
+ 2. While waiting, gather context in parallel:
264
+ - Fetch issue details ~2s
265
+ - Read all issue comments ~2s
266
+ - Check for existing patterns/files ~2s
267
+ 3. Wait for worktree completion
268
+ 4. Begin implementation with full context ready
269
+ ```
270
+
271
+ **Implementation:**
272
+
273
+ 1. **Start worktree creation as background task:**
274
+ ```bash
275
+ # From main repo, start worktree creation in background
276
+ ./scripts/dev/new-feature.sh <issue-number> &
277
+ WORKTREE_PID=$!
278
+ echo "Worktree creation started (PID: $WORKTREE_PID)"
279
+ ```
280
+
281
+ 2. **Gather context while waiting:**
282
+ - **Read all GitHub issue comments** to gather complete context:
283
+ - Comments often contain clarifications, updates, or additional AC added after the initial issue description
284
+ - Look for discussion about implementation details, edge cases, or requirements mentioned in comments
285
+ - Review feedback from previous implementation cycles or review comments
286
+ - Summarize briefly:
287
+ - The AC checklist (AC-1, AC-2, ...) from the issue and all comments
288
+ - The current implementation plan (from issue comments or `/spec`)
289
+ - **The Feature Quality Planning section** (if present from `/spec`)
290
+ - If there is no plan:
291
+ - Ask whether to quickly propose one (or suggest using `/spec` first).
292
+
293
+ #### 2.1b Quality Plan Reference (RECOMMENDED)
294
+
295
+ **If `/spec` was run**, look for the **Feature Quality Planning** section in issue comments. This section provides guidance for implementation quality:
296
+
297
+ **What to extract from Quality Plan:**
298
+ - **Error Handling items** → Implement error handling for identified scenarios
299
+ - **Edge cases** → Handle edge cases listed in the plan
300
+ - **Test Coverage items** → Know what tests are expected
301
+ - **Derived ACs** → Additional ACs generated from quality planning
302
+
303
+ **How to use during implementation:**
304
+ 1. Before implementing each AC, check if quality plan has related items
305
+ 2. Implement error handling per quality plan's "Error Handling" checklist
306
+ 3. Ensure test coverage matches quality plan's "Test Coverage Plan"
307
+ 4. Address derived ACs alongside original ACs
308
+
309
+ **Example reference:**
310
+ ```markdown
311
+ Per Quality Plan:
312
+ - Error Handling: Handle API timeout with graceful fallback
313
+ - Test Coverage: Add unit tests for edge case (empty input)
314
+ - Derived AC-6: Log errors for observability
315
+ ```
316
+
317
+ **If no Quality Plan found:** Proceed with standard implementation but note in progress update that quality planning was not available.
318
+
319
+ #### 2.1b2 Codebase Conventions (RECOMMENDED)
320
+
321
+ **Before generating code**, check for codebase conventions detected during `sequant init`:
322
+
323
+ ```bash
324
+ # Read conventions file if it exists
325
+ cat .sequant/conventions.json 2>/dev/null || echo "No conventions detected"
326
+ ```
327
+
328
+ **If `.sequant/conventions.json` exists**, use the detected conventions to align generated code:
329
+ - **testFilePattern** → Name test files accordingly (e.g., `*.test.ts` vs `*.spec.ts`)
330
+ - **exportStyle** → Use named or default exports to match codebase style
331
+ - **asyncPattern** → Prefer async/await or promise chains as appropriate
332
+ - **indentation** → Match existing indentation style
333
+ - **semicolons** → Include or omit semicolons per convention
334
+
335
+ **Manual overrides** in the `manual` section take precedence over detected values.
336
+
337
+ **If no conventions file exists:** Proceed normally — conventions are optional enhancement.
338
+
339
+ #### 2.1c Derived AC Extraction (REQUIRED when Quality Plan exists)
340
+
341
+ **Purpose:** Extract derived ACs from the spec comment's Derived ACs table so they can be tracked alongside original ACs during implementation.
342
+
343
+ **When to extract:** If the Quality Plan section exists and contains a "Derived ACs" table.
344
+
345
+ **Extraction Method:**
346
+
347
+ ```bash
348
+ # Extract derived ACs from spec comment's Derived ACs table
349
+ # Format: | Source | AC-N: Description | Priority |
350
+ # Uses flexible pattern to match any source dimension (not hardcoded)
351
+ derived_acs=$(gh issue view <issue-number> --comments --json comments -q '.comments[].body' | \
352
+ grep -E '\|[^|]+\|\s*AC-[0-9]+:' | \
353
+ grep -oE 'AC-[0-9]+:[^|]+' | \
354
+ sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | \
355
+ sort -u || true)
356
+
357
+ # Display extracted derived ACs
358
+ if [[ -n "$derived_acs" ]]; then
359
+ echo "Derived ACs found:"
360
+ echo "$derived_acs"
361
+ else
362
+ echo "No derived ACs found in spec comment"
363
+ fi
364
+ ```
365
+
366
+ **Handling Malformed Rows:**
367
+
368
+ The extraction pattern is designed to handle edge cases:
369
+ - Missing columns → Row is skipped (requires Source + AC-N pattern)
370
+ - Extra whitespace → Trimmed during extraction
371
+ - Empty description → AC ID still captured
372
+ - Non-standard source names → Row is skipped (only standard sources matched)
373
+
374
+ **Include in AC Tracking:**
375
+
376
+ Once extracted, derived ACs should be:
377
+ 1. Added to the implementation checklist
378
+ 2. Tracked in the Pre-PR AC Verification table (labeled as "Derived")
379
+ 3. Included in progress updates
380
+
381
+ **Example Output:**
382
+
383
+ ```markdown
384
+ ## Derived ACs (from Quality Plan)
385
+
386
+ | AC | Source | Description | Status |
387
+ |----|--------|-------------|--------|
388
+ | AC-6 | Error Handling | Handle malformed table rows gracefully | ⬜ Pending |
389
+ | AC-7 | Test Coverage | Verify extraction with 0, 1, 5+ derived ACs | ⬜ Pending |
390
+ ```
391
+
392
+ **If no Derived ACs found:** Output: "Derived ACs: None in spec comment" and proceed with original ACs only.
393
+
394
+ 3. **Wait for worktree completion before implementation:**
395
+ ```bash
396
+ # Wait for worktree creation to complete
397
+ wait $WORKTREE_PID
398
+ WORKTREE_EXIT=$?
399
+ if [ $WORKTREE_EXIT -ne 0 ]; then
400
+ echo "ERROR: Worktree creation failed with exit code $WORKTREE_EXIT"
401
+ # Fall back to sequential creation with error visibility
402
+ fi
403
+ ```
404
+
405
+ **When to use parallel context gathering:**
406
+ - ✅ Creating a new worktree (standalone mode)
407
+ - ❌ Worktree already exists (skip - just navigate to it)
408
+ - ❌ Orchestrated mode (SEQUANT_WORKTREE set - worktree pre-created)
409
+
410
+ **Fallback:** If parallel execution fails or is not applicable, fall back to sequential context gathering.
411
+
412
+ ### 2.1a Smoke Test (Recommended for UI Issues)
413
+
414
+ **Purpose:** Catch runtime failures that pass `npm test` and `npm run build` but crash at runtime (e.g., missing module registrations, framework version incompatibilities).
415
+
416
+ **When to run:** Issues with `admin`, `ui`, or `frontend` labels.
417
+
418
+ **Skip if:** Issue has none of these labels (backend-only, CLI, docs, etc.).
419
+
420
+ **Quick verification (< 30 seconds):**
421
+
422
+ 1. Start dev server in background:
423
+ ```bash
424
+ npm run dev &
425
+ DEV_PID=$!
426
+ sleep 5 # Wait for server startup
427
+ ```
428
+
429
+ 2. Check for startup errors:
430
+ ```bash
431
+ # Verify server is running
432
+ curl -s http://localhost:3000 > /dev/null && echo "✓ Server responding" || echo "✗ Server not responding"
433
+ ```
434
+
435
+ 3. Kill the dev server:
436
+ ```bash
437
+ kill $DEV_PID 2>/dev/null
438
+ ```
164
439
 
165
- - **Read all GitHub issue comments** to gather complete context:
166
- - Comments often contain clarifications, updates, or additional AC added after the initial issue description
167
- - Look for discussion about implementation details, edge cases, or requirements mentioned in comments
168
- - Review feedback from previous implementation cycles or review comments
169
- - Summarize briefly:
170
- - The AC checklist (AC-1, AC-2, ...) from the issue and all comments
171
- - The current implementation plan (from issue comments or `/spec`)
172
- - If there is no plan:
173
- - Ask whether to quickly propose one (or suggest using `/spec` first).
440
+ **What to look for:**
441
+ - Server crash on startup Check `framework-gotchas.md`
442
+ - Blank white page React hydration error or missing component
443
+ - Module registration errors AG Grid, chart libraries, etc.
444
+ - Console errors on load → Missing imports, env vars
445
+
446
+ **If issues found:** Fix before proceeding with new implementation. Reference `references/shared/framework-gotchas.md` for common solutions.
174
447
 
175
448
  ### Feature Worktree Workflow
176
449
 
177
450
  **Execution Phase:** Create and work in a feature worktree.
178
451
 
452
+ **CRITICAL: Main Branch Safeguard (Issue #85)**
453
+
454
+ Before starting any implementation, verify you are NOT on the main/master branch:
455
+
456
+ ```bash
457
+ # Check current branch
458
+ CURRENT_BRANCH=$(git rev-parse --abbrev-ref HEAD)
459
+ echo "Current branch: $CURRENT_BRANCH"
460
+ ```
461
+
462
+ **If on main/master branch:**
463
+ 1. **STOP** - Do not implement directly on main
464
+ 2. Create a feature worktree first: `./scripts/dev/new-feature.sh <issue-number>`
465
+ - For custom base branch: `./scripts/dev/new-feature.sh <issue-number> --base <branch>`
466
+ 3. Navigate to the worktree before making any changes
467
+
468
+ **Why this matters:** Work done directly on main can be lost during sync operations (git reset, git pull --rebase, etc.). Worktrees provide isolation and safe recovery through branches.
469
+
470
+ **If orchestrated (SEQUANT_WORKTREE is set):**
471
+ - Use the provided worktree path directly: `cd $SEQUANT_WORKTREE`
472
+ - Skip steps 1-2 below (worktree already created by orchestrator)
473
+ - Continue with step 3 (Work in the worktree)
474
+
475
+ **If standalone:**
476
+
179
477
  1. **Check if worktree already exists:**
180
478
  - Check if you're already in a worktree: `git worktree list` or check if `../worktrees/` contains a directory for this issue
181
479
  - If worktree exists, navigate to it and continue work there
182
480
 
183
- 2. **Create worktree if needed:**
184
- - From the main repository directory, run: `./scripts/dev/new-feature.sh <issue-number>`
185
- - This will:
481
+ 2. **Create worktree if needed (with parallel context gathering):**
482
+
483
+ **Optimized flow (parallel):**
484
+ ```bash
485
+ # Step 1: Start worktree creation in background
486
+ # For default (main) base:
487
+ ./scripts/dev/new-feature.sh <issue-number> &
488
+ # For custom base branch (e.g., feature integration branch):
489
+ ./scripts/dev/new-feature.sh <issue-number> --base feature/dashboard &
490
+ WORKTREE_PID=$!
491
+
492
+ # Step 2: Gather context while worktree creates (see Section 2)
493
+ # - Fetch issue details
494
+ # - Read issue comments
495
+ # - Check for existing patterns
496
+
497
+ # Step 3: Wait for worktree completion
498
+ wait $WORKTREE_PID
499
+ ```
500
+
501
+ **What new-feature.sh does:**
186
502
  - Fetch issue details from GitHub
187
503
  - Create branch: `feature/<issue-number>-<issue-title-slug>`
188
504
  - Create worktree in: `../worktrees/feature/<branch-name>/`
189
- - Install dependencies
505
+ - Branch from specified base (default: main)
506
+ - Install dependencies (can use cache if `SEQUANT_NPM_CACHE=true`)
190
507
  - Copy environment files if they exist
508
+
509
+ **After completion:**
191
510
  - Navigate to the worktree directory: `cd ../worktrees/feature/<branch-name>/`
192
511
 
193
512
  3. **Work in the worktree:**
@@ -202,6 +521,249 @@ git branch -a | grep -i "<issue-number>" || true
202
521
 
203
522
  **Important:** Always work in the worktree directory, not the main repository, once the worktree is created.
204
523
 
524
+ ### Pre-PR AC Verification (REQUIRED)
525
+
526
+ **Before creating a PR**, you MUST verify that each Acceptance Criteria has been addressed:
527
+
528
+ 1. **Retrieve AC from workflow state:**
529
+ ```bash
530
+ # Get stored AC for this issue
531
+ npx tsx -e "
532
+ import { StateManager } from './src/lib/workflow/state-manager.ts';
533
+ const manager = new StateManager();
534
+ (async () => {
535
+ const state = await manager.getIssueState(<issue-number>);
536
+ if (state?.acceptanceCriteria) {
537
+ console.log(JSON.stringify(state.acceptanceCriteria, null, 2));
538
+ } else {
539
+ console.log('No AC found in state - check issue body');
540
+ }
541
+ })();
542
+ "
543
+ ```
544
+
545
+ 2. **If no AC in state**, extract from issue body:
546
+ - Check issue body for AC items (AC-1, AC-2, etc.)
547
+ - Parse from issue comments if clarifications were added
548
+
549
+ 3. **Generate AC Verification Checklist:**
550
+
551
+ For each AC item (including derived ACs), determine implementation status:
552
+
553
+ ```markdown
554
+ ### Pre-PR AC Verification
555
+
556
+ | AC | Source | Description | Status | Evidence |
557
+ |----|--------|-------------|--------|----------|
558
+ | AC-1 | Original | [Description] | ✅ Implemented | [File:line or brief explanation] |
559
+ | AC-2 | Original | [Description] | ✅ Implemented | [File:line or brief explanation] |
560
+ | AC-3 | Original | [Description] | ⚠️ Partial | [What's missing] |
561
+ | **Derived ACs** | | | | |
562
+ | AC-6 | Error Handling | [From Quality Plan] | ✅ Implemented | [File:line] |
563
+ | AC-7 | Test Coverage | [From Quality Plan] | ⚠️ Partial | [What's missing] |
564
+ ```
565
+
566
+ **Derived AC Handling:**
567
+ - Extract derived ACs using the method in Section 2.1c
568
+ - Include in the same verification table with "Source" column indicating origin
569
+ - Treat derived ACs identically to original ACs for verification purposes
570
+
571
+ 4. **Status Definitions:**
572
+ - ✅ **Implemented**: Code exists that satisfies this AC
573
+ - ⚠️ **Partial**: Some aspects implemented, others missing
574
+ - ❌ **Not addressed**: AC not implemented (must include justification)
575
+ - 🔄 **Deferred**: Intentionally deferred to follow-up issue (link issue)
576
+
577
+ 5. **Verification Behavior:**
578
+ - **All AC ✅**: Proceed to PR creation
579
+ - **Some AC ⚠️/❌**: Include in PR description as known gaps
580
+ - **Critical AC ❌**: Consider whether to create PR or continue implementation
581
+
582
+ 6. **Include in PR Description:**
583
+ Add the AC verification table to the PR body so reviewers can validate coverage.
584
+
585
+ **Why this matters:** Catching AC gaps before PR creation:
586
+ - Reduces review cycles
587
+ - Ensures nothing is forgotten
588
+ - Documents intentional deferrals
589
+ - Enables better QA in `/qa` phase
590
+
591
+ ### 3e2. Simulate QA Before PR (REQUIRED)
592
+
593
+ **Purpose:** Prevent first-pass QA failures by simulating the QA reviewer's perspective before creating a PR. Root cause analysis of multi-attempt QA issues (#448) found that the majority of first-pass failures stem from gaps exec could have caught with deliberate self-verification.
594
+
595
+ **Top failure patterns exec must check for (from analysis of 6 multi-attempt issues):**
596
+
597
+ | Pattern | Frequency | What to check |
598
+ |---------|-----------|---------------|
599
+ | Test coverage gaps | 50% (3/6 issues) | Changed files have corresponding tests |
600
+ | Incomplete self-verification | 17% (1/6 issues) | Each AC verified against literal wording, not just spirit |
601
+ | Lint/build not run pre-PR | 17% (1/6 issues) | `npm run lint` + `npm run build` pass locally |
602
+
603
+ *Note: Remaining 33% were QA detection issues, addressed separately in QA skill.*
604
+
605
+ **Simulate QA Checklist (answer each before creating PR):**
606
+
607
+ 1. **Test-to-Change Alignment:** For each source file you modified:
608
+ ```bash
609
+ # List changed source files (excluding tests)
610
+ changed=$(git diff main...HEAD --name-only | grep -E '\.(ts|tsx|js|jsx)$' | grep -v -E '\.(test|spec)\.' || true)
611
+
612
+ # For each, verify a corresponding test exists and covers the change
613
+ for file in $changed; do
614
+ base=$(basename "$file" | sed 's/\.[^.]*$//')
615
+ test_exists=$(find . -name "${base}.test.*" -o -name "${base}.spec.*" 2>/dev/null | head -1 || true)
616
+ if [[ -z "$test_exists" ]]; then
617
+ echo "WARNING NO TEST: $file"
618
+ fi
619
+ done
620
+ ```
621
+ - If critical files lack tests, add tests before PR creation
622
+ - If tests exist but don't cover the specific change, note as known gap
623
+
624
+ 2. **QA Reviewer Perspective:** Ask yourself:
625
+ - "If I were reviewing this PR for the first time, what would I flag?"
626
+ - "Are there any 'I'll fix it later' shortcuts that QA will catch?"
627
+ - "Did I actually run the feature, or just verify it compiles?"
628
+
629
+ **If any check reveals a gap:**
630
+ - Fix the gap before creating the PR
631
+ - Re-run build/lint/tests after fixing
632
+ - Update the AC verification table
633
+
634
+ **Do NOT skip this step.** This single checkpoint addresses the most common first-pass QA failure patterns.
635
+
636
+ ### 3f. CHANGELOG Update (REQUIRED for user-facing changes)
637
+
638
+ **Purpose:** Ensure all user-facing changes are documented in the CHANGELOG before PR creation. This prevents documentation gaps and reduces release overhead.
639
+
640
+ **When to update CHANGELOG:**
641
+
642
+ | Change Type | CHANGELOG Required? | Section |
643
+ |-------------|---------------------|---------|
644
+ | New feature | ✅ Yes | `### Added` |
645
+ | Bug fix | ✅ Yes | `### Fixed` |
646
+ | Breaking change | ✅ Yes | `### Changed` or `### Removed` |
647
+ | Performance improvement | ✅ Yes | `### Changed` |
648
+ | Dependency update (security) | ✅ Yes | `### Fixed` or `### Security` |
649
+ | Documentation only | ❌ No | - |
650
+ | Internal refactor (no behavior change) | ❌ No | - |
651
+ | Test-only changes | ❌ No | - |
652
+ | CI/workflow changes | ❌ No | - |
653
+
654
+ **How to update:**
655
+
656
+ 1. **Check if CHANGELOG.md exists:**
657
+ ```bash
658
+ if [ -f "CHANGELOG.md" ]; then
659
+ echo "CHANGELOG.md found - update required for user-facing changes"
660
+ else
661
+ echo "No CHANGELOG.md - skip CHANGELOG update"
662
+ fi
663
+ ```
664
+
665
+ 2. **If CHANGELOG.md exists and change is user-facing**, use the Edit tool to add an entry under `## [Unreleased]`:
666
+
667
+ ```markdown
668
+ ## [Unreleased]
669
+
670
+ ### Added
671
+
672
+ - Brief description of new feature (#<issue-number>)
673
+ ```
674
+
675
+ 3. **Entry format:**
676
+ - Start with a verb: "Add", "Fix", "Update", "Remove", "Improve"
677
+ - Keep it concise (1-2 lines)
678
+ - Include issue number as `(#123)`
679
+ - Group related changes in a single bullet with sub-bullets if needed
680
+
681
+ **Example entries:**
682
+
683
+ ```markdown
684
+ ### Added
685
+
686
+ - CHANGELOG update step in /exec skill (#320)
687
+ - Instructs /exec to add [Unreleased] entries during feature commits
688
+ - Includes change type classification table
689
+
690
+ ### Fixed
691
+
692
+ - Race condition in parallel agent spawning (#315)
693
+ ```
694
+
695
+ **If CHANGELOG doesn't exist:** Skip this step. Not all projects use CHANGELOG.md.
696
+
697
+ **If change is not user-facing:** Skip this step but note in progress summary: "CHANGELOG: N/A (internal change)"
698
+
699
+ ---
700
+
701
+ ### 3g. CLI Wiring Checklist (When Option Interfaces Modified)
702
+
703
+ **Purpose:** Prevent incomplete CLI implementations where option interface fields are added but never wired to CLI flags. This is a proactive check during implementation, complementing the verification in `/qa`.
704
+
705
+ **When to apply:** Adding or modifying `RunOptions` or similar CLI option interfaces.
706
+
707
+ **Origin:** Issue #305 — A `force` option was added to `RunOptions` and used in runtime logic, but `--force` was never registered in `bin/cli.ts`. This caused the feature to be unreachable by users.
708
+
709
+ **Before committing changes that add option interface fields:**
710
+
711
+ | Step | Action | Verification |
712
+ |------|--------|--------------|
713
+ | 1 | Add field to interface | `src/lib/workflow/batch-executor.ts` |
714
+ | 2 | Register CLI flag | Add `.option("--flag-name", "description")` in `bin/cli.ts` |
715
+ | 3 | Wire to handler | Ensure `options.flagName` passes to implementation |
716
+ | 4 | Test CLI help | Run `npx tsx bin/cli.ts <command> --help` to verify flag appears |
717
+
718
+ **Key File Map:**
719
+
720
+ | Interface | Location | CLI Registration |
721
+ |-----------|----------|------------------|
722
+ | `RunOptions` | `src/lib/workflow/batch-executor.ts` | `run` command in `bin/cli.ts` |
723
+
724
+ **Quick Verification Script:**
725
+
726
+ ```bash
727
+ # List all RunOptions fields
728
+ grep -E '^\s+\w+\??: ' src/lib/workflow/batch-executor.ts | head -30 || true
729
+
730
+ # List all registered options for 'run' command
731
+ grep -A 50 'command("run")' bin/cli.ts | grep '\.option(' | head -30 || true
732
+
733
+ # Check if a specific field is registered (e.g., 'force')
734
+ field_name="force"
735
+ cli_flag=$(echo "$field_name" | sed 's/\([A-Z]\)/-\L\1/g') # camelCase to kebab-case
736
+ grep -q "\-\-$cli_flag" bin/cli.ts && echo "✅ --$cli_flag registered" || echo "❌ --$cli_flag NOT registered"
737
+ ```
738
+
739
+ **Internal-only Field Exclusion:**
740
+
741
+ Not all interface fields need CLI registration. Fields are internal-only if:
742
+ - They have no `mergedOptions.X` runtime usage (set programmatically)
743
+ - They're environment-controlled (e.g., `SEQUANT_*` env vars)
744
+ - They're only used in type signatures, not at runtime
745
+
746
+ **Detection:** If `grep "mergedOptions.$field"` returns no matches, the field is likely internal-only.
747
+
748
+ **Self-Check Before Commit:**
749
+
750
+ ```markdown
751
+ ## CLI Wiring Self-Check
752
+
753
+ | New Field | CLI Flag | Help Text | Wiring Status |
754
+ |-----------|----------|-----------|---------------|
755
+ | `newOption` | `--new-option` | "Description" | ✅ Complete |
756
+ | `internalOnly` | N/A | N/A | ⏭️ Internal |
757
+ ```
758
+
759
+ **If wiring is incomplete:**
760
+ 1. Add the missing `.option()` call in `bin/cli.ts`
761
+ 2. Update help text to describe the flag
762
+ 3. Run `npm run build` to verify no TypeScript errors
763
+ 4. Test with `--help` to confirm flag appears
764
+
765
+ ---
766
+
205
767
  ### PR Creation and Verification
206
768
 
207
769
  After implementation is complete and all checks pass, create and verify the PR:
@@ -244,6 +806,16 @@ After implementation is complete and all checks pass, create and verify the PR:
244
806
  - If PR exists: Record the URL from `gh pr view` output
245
807
  - If PR creation failed: Record the error and include manual creation instructions
246
808
 
809
+ 6. **Record PR info in workflow state:**
810
+ ```bash
811
+ # Extract PR number and URL from gh pr view output, then update state
812
+ PR_INFO=$(gh pr view --json number,url)
813
+ PR_NUMBER=$(echo "$PR_INFO" | jq -r '.number')
814
+ PR_URL=$(echo "$PR_INFO" | jq -r '.url')
815
+ npx tsx scripts/state/update.ts pr <issue-number> "$PR_NUMBER" "$PR_URL"
816
+ ```
817
+ This enables `--cleanup` to detect merged PRs and auto-remove state entries.
818
+
247
819
  **PR Verification Failure Handling:**
248
820
 
249
821
  If `gh pr view` fails after retry:
@@ -275,6 +847,52 @@ If `gh pr view` fails after retry:
275
847
  - If it needs modification, extend it rather than creating a new one
276
848
  - Document why existing utilities don't meet requirements before creating new ones
277
849
 
850
+ ### Check npm for Existing Packages
851
+
852
+ **IMPORTANT:** Before implementing utilities for common "solved problem" domains, check if a well-maintained package exists.
853
+
854
+ **Domains to check npm first:**
855
+
856
+ | Domain | Recommended Packages |
857
+ |--------|---------------------|
858
+ | Date/time handling | `date-fns`, `dayjs` |
859
+ | Validation | `zod`, `yup`, `valibot` |
860
+ | HTTP requests with retry | `ky`, `got`, `axios` |
861
+ | Form state | `react-hook-form`, `formik` |
862
+ | State management | `zustand`, `jotai` |
863
+ | ID generation | `nanoid`, `uuid` |
864
+ | String utilities | `lodash` (specific imports only) |
865
+
866
+ **Package evaluation criteria:**
867
+
868
+ | Criterion | Threshold | Why |
869
+ |-----------|-----------|-----|
870
+ | Weekly downloads | >10,000 | Indicates community trust |
871
+ | Last update | <6 months ago | Actively maintained |
872
+ | License | MIT, Apache-2.0, BSD | Permissive, compatible |
873
+ | Bundle size | Proportional to use | Avoid 500kb for one function |
874
+
875
+ **Quick check commands:**
876
+ ```bash
877
+ # Package metadata (license, last update, size)
878
+ npm view <pkg> --json | jq '{name, version, license, modified: .time.modified, size: .dist.unpackedSize}'
879
+
880
+ # Weekly downloads (requires npm API)
881
+ curl -s "https://api.npmjs.org/downloads/point/last-week/<pkg>" | jq '.downloads'
882
+ ```
883
+
884
+ **Custom implementation is appropriate when:**
885
+ - Only a tiny subset of functionality needed (<20 lines)
886
+ - Package is abandoned (no updates 12+ months) or has security issues
887
+ - Project constraints prohibit new dependencies
888
+ - User explicitly requests custom solution
889
+
890
+ **Decision flow:**
891
+ 1. Is this a "solved problem" domain? → Check npm first
892
+ 2. Does a well-maintained package exist? → Prefer package
893
+ 3. Would custom implementation be <20 lines? → Custom is OK
894
+ 4. Uncertain? → Ask user preference
895
+
278
896
  ### Check Framework Gotchas on Runtime Errors
279
897
 
280
898
  **When encountering unexpected runtime errors or build failures:**
@@ -292,19 +910,41 @@ If you discover a new framework-specific issue that caused debugging time, add i
292
910
 
293
911
  This section covers optional MCP tools that enhance implementation quality when available.
294
912
 
295
- #### MCP Availability Check
913
+ #### MCP Availability Check (Lazy Loading)
914
+
915
+ **Performance Optimization:** Check MCP availability lazily on first use, NOT proactively at session start. This avoids wasting time checking MCPs for issues that don't need them.
296
916
 
297
- **Before using MCP tools**, verify they are available in your session. If unavailable, use the documented fallback behavior.
917
+ **Lazy Check Pattern:**
918
+ - ❌ **Don't:** Check all MCPs at session start
919
+ - ✅ **Do:** Check MCP availability only when you're about to use it
298
920
 
299
921
  ```markdown
300
- **MCP Status Check (perform at session start):**
301
- - [ ] Context7: Try `mcp__context7__resolve-library-id` - if available, proceed
302
- - [ ] Sequential Thinking: Try `mcp__sequential-thinking__sequentialthinking` - if available, proceed
303
- - [ ] Chrome DevTools: Try `mcp__chrome-devtools__take_snapshot` - if available, proceed
922
+ **MCP Check (on first use only):**
923
+ When you need to use an MCP tool:
924
+ 1. Attempt the MCP call
925
+ 2. If it fails with "tool not available", use the fallback strategy
926
+ 3. Cache the result for the session (don't re-check)
927
+ ```
304
928
 
305
- If any MCP is unavailable, use fallback strategies documented below.
929
+ **Example - Lazy Context7 Check:**
930
+ ```javascript
931
+ // Only check when you actually need library docs
932
+ // NOT at session start
933
+ if (need_library_documentation) {
934
+ // Try Context7 - fallback to WebSearch if unavailable
935
+ try {
936
+ mcp__context7__resolve-library-id(...)
937
+ } catch {
938
+ // Fallback: use WebSearch or codebase patterns
939
+ }
940
+ }
306
941
  ```
307
942
 
943
+ **Why lazy loading:**
944
+ - Many issues don't need MCPs (simple bugs, docs, config changes)
945
+ - Proactive checks waste 2-5 seconds per MCP
946
+ - Lazy checks only run when the tool provides value
947
+
308
948
  ---
309
949
 
310
950
  #### Context7 - Library Documentation Lookup
@@ -462,20 +1102,387 @@ If your project uses a database MCP (e.g., Supabase, Postgres):
462
1102
  ### 3. Checks-first Mindset
463
1103
 
464
1104
  - Before and after meaningful changes, plan to run:
465
- - `npm test`
1105
+ - `npm run build` - TypeScript compilation
1106
+ - `npm run lint` - ESLint validation (catches unused imports, formatting issues)
1107
+ - `npm test` - Run relevant tests
466
1108
  - For larger changes or anything that might impact build/runtime:
467
1109
  - Suggest running `npm run build` and interpret any errors.
468
1110
 
1111
+ **Pre-PR Quality Gates (REQUIRED):**
1112
+
1113
+ Before creating a PR, run ALL checks in this order:
1114
+ 1. `npm run build` - Must pass (no TypeScript errors)
1115
+ 2. `npm run lint` - Must pass (no ESLint errors)
1116
+ 3. `npm test` - Must pass (all tests green)
1117
+
1118
+ If any check fails, fix the issues before creating the PR.
1119
+
469
1120
  Do NOT silently skip checks. Always state which commands you intend to run and why.
470
1121
 
1122
+ ### 3a. Test Coverage Transparency (REQUIRED)
1123
+
1124
+ **Purpose:** Report which changed files have corresponding tests, not just "N tests passed."
1125
+
1126
+ **After running `npm test`, you MUST analyze test coverage for changed files:**
1127
+
1128
+ Use the Glob tool to check for corresponding test files:
1129
+ ```
1130
+ # Get changed source files (excluding tests) from git
1131
+ changed=$(git diff main...HEAD --name-only | grep -E '\.(ts|tsx|js|jsx)$' | grep -v -E '\.test\.|\.spec\.|__tests__' || true)
1132
+
1133
+ # For each changed file, use the Glob tool to find matching test files
1134
+ # Glob(pattern="**/${base}.test.*") or Glob(pattern="**/${base}.spec.*")
1135
+ # If no test file found, report "NO TEST: $file"
1136
+ ```
1137
+
1138
+ **Required reporting format:**
1139
+
1140
+ | Scenario | Report |
1141
+ |----------|--------|
1142
+ | Tests cover changed files | `Tests: N passed (covers changed files)` |
1143
+ | Tests don't cover changed files | `Tests: N passed (⚠️ 0 cover changed files)` |
1144
+ | No tests for specific files | `Tests: N passed (⚠️ NO TESTS: file1.ts, file2.ts)` |
1145
+
1146
+ ### 3b. Change Tier Classification
1147
+
1148
+ **Purpose:** Flag coverage gaps based on criticality, not just presence/absence.
1149
+
1150
+ **Tier definitions:**
1151
+
1152
+ | Tier | Change Type | Coverage Requirement |
1153
+ |------|-------------|---------------------|
1154
+ | **Critical** | Auth, payments, security, server-actions, middleware, admin | Flag prominently if missing |
1155
+ | **Standard** | Business logic, API handlers, utilities | Note if missing |
1156
+ | **Optional** | Config, types-only, UI tweaks | No flag needed |
1157
+
1158
+ **Detection heuristic:**
1159
+
1160
+ ```bash
1161
+ # Detect critical paths in changed files
1162
+ changed=$(git diff main...HEAD --name-only | grep -E '\.(ts|tsx|js|jsx)$' || true)
1163
+ critical=$(echo "$changed" | grep -E 'auth|payment|security|server-action|middleware|admin' || true)
1164
+
1165
+ if [[ -n "$critical" ]]; then
1166
+ echo "⚠️ CRITICAL PATH CHANGES (test coverage strongly recommended):"
1167
+ echo "$critical"
1168
+ fi
1169
+ ```
1170
+
1171
+ **Include in progress summary:**
1172
+
1173
+ ```markdown
1174
+ ### Test Coverage Analysis
1175
+
1176
+ | Changed File | Tier | Has Tests? |
1177
+ |--------------|------|------------|
1178
+ | `auth/login.ts` | Critical | ⚠️ NO TESTS |
1179
+ | `lib/utils.ts` | Standard | ✅ Yes |
1180
+ | `types/index.ts` | Optional | - (types only) |
1181
+
1182
+ **Coverage:** X/Y changed source files have corresponding tests
1183
+ ```
1184
+
1185
+ ### 3c. Shell Script Checks (When .sh files modified)
1186
+
1187
+ **Purpose:** Catch shell script issues that `npm test` and `npm run build` miss.
1188
+
1189
+ **When shell scripts are modified, run these checks:**
1190
+
1191
+ ```bash
1192
+ # Get changed shell scripts
1193
+ shell_scripts=$(git diff main...HEAD --name-only | grep -E '\.sh$' || true)
1194
+
1195
+ for script in $shell_scripts; do
1196
+ echo "Checking: $script"
1197
+
1198
+ # 1. Syntax validation
1199
+ bash -n "$script" && echo "✅ Syntax OK" || echo "❌ Syntax error"
1200
+
1201
+ # 2. Shellcheck (if available)
1202
+ if command -v shellcheck &>/dev/null; then
1203
+ shellcheck "$script" && echo "✅ Shellcheck OK" || echo "⚠️ Shellcheck warnings"
1204
+ fi
1205
+
1206
+ # 3. Unused function detection
1207
+ funcs=$(grep -oE "^[a-zA-Z_]+\(\)" "$script" | sed 's/()//' || true)
1208
+ for func in $funcs; do
1209
+ calls=$(grep -c "\b${func}\b" "$script" || true)
1210
+ if [[ $calls -lt 2 ]]; then
1211
+ echo "⚠️ Function '$func' defined but possibly not called"
1212
+ fi
1213
+ done
1214
+
1215
+ # 4. Smoke test (--help or similar)
1216
+ if grep -q "getopts\|--help" "$script"; then
1217
+ bash "$script" --help 2>/dev/null && echo "✅ --help works" || echo "⚠️ --help failed"
1218
+ fi
1219
+ done
1220
+ ```
1221
+
1222
+ **Checklist:**
1223
+
1224
+ | Check | Command | Pass Criteria |
1225
+ |-------|---------|---------------|
1226
+ | Syntax | `bash -n script.sh` | Exit code 0 |
1227
+ | Shellcheck | `shellcheck script.sh` | No errors (warnings OK) |
1228
+ | Functions used | grep analysis | All defined functions called |
1229
+ | Smoke test | `bash script.sh --help` | Runs without crash |
1230
+
1231
+ **Include in progress summary:**
1232
+
1233
+ ```markdown
1234
+ ### Shell Script Checks
1235
+
1236
+ | Script | Syntax | Shellcheck | Functions | Smoke Test |
1237
+ |--------|--------|------------|-----------|------------|
1238
+ | `quality-checks.sh` | ✅ OK | ⚠️ 2 warnings | ✅ All used | ✅ OK |
1239
+ ```
1240
+
1241
+ ### 3d. Lint Check (REQUIRED before PR)
1242
+
1243
+ **Purpose:** Catch ESLint errors locally before they fail CI. This prevents wasted quality loop iterations from lint failures.
1244
+
1245
+ **When to run:** Before every PR creation. Run after `npm run build` succeeds, before `npm test`.
1246
+
1247
+ **Execution:**
1248
+
1249
+ ```bash
1250
+ # Run lint check
1251
+ npm run lint
1252
+
1253
+ # If lint script doesn't exist, gracefully skip
1254
+ if ! npm run lint 2>/dev/null; then
1255
+ if npm run --list 2>/dev/null | grep -q "lint"; then
1256
+ echo "❌ Lint failed - fix issues before PR"
1257
+ # Show specific errors
1258
+ npm run lint 2>&1 | head -50
1259
+ else
1260
+ echo "ℹ️ No lint script found - skipping lint check"
1261
+ fi
1262
+ fi
1263
+ ```
1264
+
1265
+ **Graceful Skip Logic (AC-4):**
1266
+
1267
+ Not all projects have a lint script. Handle this gracefully:
1268
+
1269
+ | Scenario | Behavior |
1270
+ |----------|----------|
1271
+ | `npm run lint` passes | ✅ Continue to tests |
1272
+ | `npm run lint` fails with errors | ❌ Fix errors before PR |
1273
+ | No `lint` script in package.json | ⚠️ Skip lint, log "No lint script found" |
1274
+ | Lint script exists but times out | ⚠️ Log warning, continue |
1275
+
1276
+ **Detection of lint script:**
1277
+
1278
+ ```bash
1279
+ # Check if lint script exists
1280
+ if npm run --list 2>/dev/null | grep -qE "^\s*lint\b"; then
1281
+ echo "Lint script found - running npm run lint"
1282
+ npm run lint
1283
+ else
1284
+ echo "ℹ️ No lint script in package.json - skipping lint check"
1285
+ fi
1286
+ ```
1287
+
1288
+ **If lint fails:**
1289
+
1290
+ 1. **Read the error output** - identify which files/lines have issues
1291
+ 2. **Common lint errors to fix:**
1292
+ - Unused imports → Remove them
1293
+ - Unused variables → Remove or use them
1294
+ - Missing semicolons → Add them (if required by config)
1295
+ - Formatting issues → Run auto-fix if available
1296
+ 3. **Fix the issues** - make minimal changes
1297
+ 4. **Re-run lint** - verify all errors are resolved
1298
+ 5. **Then continue** - to `npm test`
1299
+
1300
+ **Auto-fix consideration:**
1301
+
1302
+ Some projects support `npm run lint -- --fix`. However, auto-fix should be used cautiously:
1303
+ - ✅ Safe: formatting fixes, import ordering
1304
+ - ⚠️ Caution: removing unused code (verify it's truly unused)
1305
+ - ❌ Avoid: auto-fixing semantic errors without review
1306
+
1307
+ **Include in progress summary:**
1308
+
1309
+ ```markdown
1310
+ ### Lint Results
1311
+
1312
+ | Check | Status | Notes |
1313
+ |-------|--------|-------|
1314
+ | ESLint | ✅ Passed | 0 errors, 0 warnings |
1315
+ ```
1316
+
1317
+ Or if issues were found and fixed:
1318
+
1319
+ ```markdown
1320
+ ### Lint Results
1321
+
1322
+ | Check | Status | Notes |
1323
+ |-------|--------|-------|
1324
+ | ESLint | ✅ Passed (after fixes) | Fixed 2 unused imports in `src/lib/scope/index.ts` |
1325
+ ```
1326
+
1327
+ ### 3e. Testing Non-Exported Functions (REQUIRED)
1328
+
1329
+ **Purpose:** Provide guidance when a function needs tests but is not exported, preventing tautological tests that provide zero regression protection.
1330
+
1331
+ **Decision Tree:**
1332
+
1333
+ ```
1334
+ Function needs tests but is not exported?
1335
+
1336
+ ├─ Can it be exported with @internal tag?
1337
+ │ └─ YES → Export it, test directly
1338
+
1339
+ ├─ Can a dependency be injected for mocking?
1340
+ │ └─ YES → Add optional param, test with mock
1341
+
1342
+ ├─ Can the behavior be tested via a public caller?
1343
+ │ └─ YES → Write integration test through the public API
1344
+
1345
+ └─ None of the above?
1346
+ └─ Document why tests are limited, do NOT write tautological tests
1347
+ ```
1348
+
1349
+ **⚠️ ANTI-PATTERN WARNING:**
1350
+
1351
+ > **NEVER write tests that only assert on local variables.** If a test block does not call any imported function, it is tautological and provides no regression protection.
1352
+ >
1353
+ > **Bad example (from #267):**
1354
+ > ```typescript
1355
+ > // ❌ TAUTOLOGICAL - tests nothing real
1356
+ > it("should retry on failure", () => {
1357
+ > const mcpEnabled = true;
1358
+ > const phaseFailed = true;
1359
+ > expect(mcpEnabled && phaseFailed).toBe(true); // Always passes!
1360
+ > });
1361
+ > ```
1362
+ >
1363
+ > If you cannot test a function directly, escalate to integration testing or export with `@internal` — **do not fake the test**.
1364
+
1365
+ **Pattern 1: Export with @internal**
1366
+
1367
+ When the function can be safely exported without breaking encapsulation:
1368
+
1369
+ ```typescript
1370
+ // src/lib/retry.ts
1371
+
1372
+ /** @internal Exported for testing only - do not use directly */
1373
+ export function executePhaseWithRetry(
1374
+ phase: Phase,
1375
+ maxRetries: number,
1376
+ ): Promise<Result> {
1377
+ // Implementation
1378
+ }
1379
+
1380
+ // src/lib/retry.test.ts
1381
+ import { executePhaseWithRetry } from './retry';
1382
+
1383
+ it("retries up to maxRetries on failure", async () => {
1384
+ const result = await executePhaseWithRetry(mockPhase, 3);
1385
+ expect(result.attempts).toBe(3);
1386
+ });
1387
+ ```
1388
+
1389
+ **Pattern 2: Dependency Injection (often combined with Pattern 1)**
1390
+
1391
+ When the function has internal dependencies that need mocking, DI requires the
1392
+ function to be exported so tests can pass in mock dependencies. Combine with
1393
+ `@internal` from Pattern 1 to signal it's not part of the public API:
1394
+
1395
+ ```typescript
1396
+ // src/lib/retry.ts
1397
+
1398
+ /** @internal Exported for testing - DI allows mocking internal dependencies */
1399
+ export function retry<T>(
1400
+ fn: () => Promise<T>,
1401
+ maxRetries: number,
1402
+ // Injectable for tests - defaults to real implementation
1403
+ delayFn: (ms: number) => Promise<void> = delay,
1404
+ ): Promise<T> {
1405
+ // Implementation uses delayFn instead of hardcoded delay
1406
+ }
1407
+
1408
+ // src/lib/retry.test.ts
1409
+ import { retry } from './retry';
1410
+
1411
+ it("waits between retries", async () => {
1412
+ const mockDelay = vi.fn().mockResolvedValue(undefined);
1413
+
1414
+ await retry(failingFn, 3, mockDelay);
1415
+
1416
+ expect(mockDelay).toHaveBeenCalledTimes(2); // Called between retries
1417
+ });
1418
+ ```
1419
+
1420
+ **Pattern 3: Integration Test via Public API**
1421
+
1422
+ When the private function is called by a public entry point:
1423
+
1424
+ ```typescript
1425
+ // src/commands/run.ts (public)
1426
+ export async function runCommand(options: RunOptions): Promise<Result> {
1427
+ // Internally calls executePhaseWithRetry (private)
1428
+ }
1429
+
1430
+ // src/commands/run.test.ts
1431
+ import { runCommand } from './run';
1432
+
1433
+ it("retries on cold-start MCP failure", async () => {
1434
+ // Mock the MCP to fail once then succeed
1435
+ mockMcp.onFirstCall().throws(new Error("Cold start"));
1436
+ mockMcp.onSecondCall().resolves(successResult);
1437
+
1438
+ // Test via public API - exercises the private retry logic
1439
+ const result = await runCommand({ useMcp: true });
1440
+
1441
+ expect(result.exitCode).toBe(0);
1442
+ expect(mockMcp.callCount).toBe(2); // Proves retry happened
1443
+ });
1444
+ ```
1445
+
1446
+ **Pattern 4: Document Limitation (Last Resort)**
1447
+
1448
+ When none of the above approaches work, document the limitation clearly:
1449
+
1450
+ ```typescript
1451
+ // src/lib/internal.ts
1452
+
1453
+ /**
1454
+ * @remarks
1455
+ * This function cannot be directly tested because:
1456
+ * - It relies on process-level state that cannot be mocked
1457
+ * - Exporting would break the module's encapsulation contract
1458
+ * - No public API exercises this code path in isolation
1459
+ *
1460
+ * Coverage is provided indirectly through E2E tests in:
1461
+ * - e2e/full-workflow.test.ts (lines 45-67)
1462
+ *
1463
+ * TODO: Refactor to enable direct testing (see #XXX)
1464
+ */
1465
+ function internalHelper(): void {
1466
+ // Implementation
1467
+ }
1468
+ ```
1469
+
1470
+ **When documenting limitations, you MUST:**
1471
+ 1. Explain WHY direct testing is not possible
1472
+ 2. Reference any indirect coverage (E2E, integration tests)
1473
+ 3. Create a follow-up issue if refactoring would enable testability
1474
+ 4. **Never** write a tautological test to inflate coverage numbers
1475
+
471
1476
  ### 4. Implementation Loop
472
1477
 
473
1478
  - Implement in **small, incremental diffs**.
474
1479
  - Prefer touching the minimal number of files required.
475
1480
  - Align with repository conventions described in CLAUDE.md (naming, patterns, etc.).
476
1481
  - After each meaningful change:
477
- 1. Run `npm test` (and optionally `npm run build`).
478
- 2. If checks fail:
1482
+ 1. Run `npm run build` (if TypeScript changes)
1483
+ 2. Run `npm run lint` (catches unused imports early)
1484
+ 3. Run `npm test`
1485
+ 4. If checks fail:
479
1486
  - Inspect the failure output.
480
1487
  - Identify the root cause.
481
1488
  - Apply small, targeted fixes.
@@ -515,8 +1522,10 @@ Look in the issue comments (especially from `/spec`) for:
515
1522
  3. Default to `haiku` if no annotation
516
1523
 
517
1524
  3. **Spawn parallel agents with the appropriate model in a SINGLE message:**
1525
+ Note: `sequant-implementer` intentionally omits `model` in its agent definition
1526
+ so the skill can override per-invocation (e.g., `model="haiku"` for subtasks).
518
1527
  ```
519
- Task(subagent_type="general-purpose",
1528
+ Agent(subagent_type="sequant-implementer",
520
1529
  model="haiku",
521
1530
  run_in_background=true,
522
1531
  prompt="Implement: Create types/metrics.ts with MetricEvent interface.
@@ -547,7 +1556,9 @@ Fall back to sequential execution (standard implementation loop).
547
1556
  - Run Prettier on all modified files after each group (agents skip auto-format)
548
1557
  - On any agent failure: stop remaining agents, log error, continue with sequential
549
1558
  - File locking prevents concurrent edits to the same file
550
- - **Use prompt templates** for each agent see [Section 4c](#4c-prompt-templates-for-sub-agents)
1559
+ - **REQUIRED:** When spawning agents, you MUST use prompt templates from Section 4c for typed tasks (component, CLI, test, refactor). Generic prompts are only acceptable for truly untyped tasks.
1560
+
1561
+ ⚠️ **Warning:** Skipping templates for typed tasks will result in QA rejection.
551
1562
 
552
1563
  **Error Handling with Automatic Retry:**
553
1564
 
@@ -617,14 +1628,14 @@ Use `[template: X]` annotation to force a specific template:
617
1628
 
618
1629
  Instead of a generic prompt:
619
1630
  ```
620
- Task(subagent_type="general-purpose",
1631
+ Agent(subagent_type="sequant-implementer",
621
1632
  model="haiku",
622
1633
  prompt="Create MetricsCard component in components/admin/")
623
1634
  ```
624
1635
 
625
1636
  Use a structured template prompt:
626
1637
  ```
627
- Task(subagent_type="general-purpose",
1638
+ Agent(subagent_type="sequant-implementer",
628
1639
  model="haiku",
629
1640
  prompt="## Task: Create React Component
630
1641
 
@@ -672,6 +1683,22 @@ When retrying a failed agent, use the error recovery template from [prompt-templ
672
1683
 
673
1684
  Before each commit, self-check against these standards:
674
1685
 
1686
+ ### 0. Branch Verification
1687
+
1688
+ **CRITICAL:** Verify you are on the correct feature branch, not main/master.
1689
+
1690
+ ```bash
1691
+ CURRENT_BRANCH=$(git branch --show-current)
1692
+ if [[ "$CURRENT_BRANCH" == "main" || "$CURRENT_BRANCH" == "master" ]]; then
1693
+ echo "❌ ERROR: On $CURRENT_BRANCH — do NOT commit here."
1694
+ echo " Navigate to the feature worktree or create a branch first."
1695
+ exit 1
1696
+ fi
1697
+ echo "✓ On branch: $CURRENT_BRANCH"
1698
+ ```
1699
+
1700
+ **Why:** Sub-agents and shell context resets can silently switch the working directory back to main. Without this check, commits land on main instead of the feature branch.
1701
+
675
1702
  ### 1. Scope Check
676
1703
  Does this change directly address an AC item?
677
1704
  - **Yes** → Proceed
@@ -746,7 +1773,51 @@ When in doubt, choose:
746
1773
 
747
1774
  The goal is to satisfy AC with the smallest, safest change possible.
748
1775
 
749
- ### 5. Progress Summary and Draft Issue Update
1776
+ ### 5. Adversarial Self-Evaluation (REQUIRED)
1777
+
1778
+ **Before outputting your final summary**, you MUST complete this adversarial self-evaluation to catch issues that automated checks miss.
1779
+
1780
+ **Why this matters:** Sessions show that honest self-questioning consistently catches real issues:
1781
+ - Tests that pass but don't cover the actual changes
1782
+ - Features that build but don't work as expected
1783
+ - AC items marked "done" but with weak implementation
1784
+
1785
+ **Answer these questions honestly:**
1786
+ 1. "Did anything not work as expected during implementation?"
1787
+ 2. "If this feature broke tomorrow, would the current tests catch it?"
1788
+ 3. "What's the weakest part of this implementation?"
1789
+ 4. "Am I reporting success metrics without honest self-evaluation?"
1790
+ 5. "For each changed source file, does a corresponding test file exist? If not, why is that acceptable?"
1791
+ 6. "Did I run `npm run lint` and fix all errors, or am I hoping CI will pass?"
1792
+
1793
+ **Include this section in your output:**
1794
+
1795
+ ```markdown
1796
+ ### Self-Evaluation
1797
+
1798
+ - **Worked as expected:** [Yes/No - if No, explain what didn't work]
1799
+ - **Test coverage confidence:** [High/Medium/Low - explain why]
1800
+ - **Weakest part:** [Identify the weakest aspect of the implementation]
1801
+ - **Honest assessment:** [Any concerns or caveats?]
1802
+ ```
1803
+
1804
+ **If any answer reveals concerns:**
1805
+ - Address the issues before proceeding
1806
+ - Re-run relevant checks (`npm test`, `npm run build`)
1807
+ - Update the self-evaluation after fixes
1808
+
1809
+ **Do NOT skip this self-evaluation.** Honest reflection catches issues that automated checks miss.
1810
+
1811
+ ---
1812
+
1813
+ ### 6. Progress Summary and Draft Issue Update
1814
+
1815
+ **If orchestrated (SEQUANT_ORCHESTRATOR is set):**
1816
+ - Skip posting progress comments to GitHub (orchestrator handles summary)
1817
+ - Still provide AC coverage summary in output for orchestrator to capture
1818
+ - Let orchestrator handle final GitHub update
1819
+
1820
+ **If standalone:**
750
1821
 
751
1822
  At the end of a session:
752
1823
 
@@ -761,9 +1832,26 @@ At the end of a session:
761
1832
  - Include:
762
1833
  - AC coverage summary
763
1834
  - Brief list of key files changed
1835
+ - **Quality Plan Alignment** (REQUIRED if quality plan exists in issue comments)
764
1836
  - **PR Status** (Created with URL, or Failed with reason and manual instructions)
765
1837
  - Any known gaps or open questions
766
1838
 
1839
+ **Quality Plan Alignment (REQUIRED when quality plan exists):**
1840
+
1841
+ If the issue has a Feature Quality Planning section from `/spec`, you MUST include this section. If no quality plan exists, output: "Quality Plan Alignment: N/A - No quality plan in issue"
1842
+ ```markdown
1843
+ ### Quality Plan Alignment
1844
+
1845
+ | Quality Dimension | Items Addressed | Notes |
1846
+ |-------------------|-----------------|-------|
1847
+ | Error Handling | 2/3 | Missing: API timeout handling |
1848
+ | Test Coverage | 3/3 | All critical paths covered |
1849
+ | Code Quality | 2/2 | Types defined, patterns followed |
1850
+ | Best Practices | 1/1 | Logging added |
1851
+
1852
+ **Derived ACs:** 2/2 addressed
1853
+ ```
1854
+
767
1855
  - Label it clearly as:
768
1856
 
769
1857
  ```md
@@ -792,13 +1880,47 @@ You may be invoked multiple times for the same issue. Each time, re-establish co
792
1880
 
793
1881
  ---
794
1882
 
1883
+ ## State Tracking
1884
+
1885
+ **IMPORTANT:** Update workflow state when running standalone (not orchestrated).
1886
+
1887
+ ### Check Orchestration Mode
1888
+
1889
+ The orchestration check happens automatically when you run the state update script - it exits silently if `SEQUANT_ORCHESTRATOR` is set.
1890
+
1891
+ ### State Updates (Standalone Only)
1892
+
1893
+ When NOT orchestrated (`SEQUANT_ORCHESTRATOR` is not set):
1894
+
1895
+ **At skill start:**
1896
+ ```bash
1897
+ npx tsx scripts/state/update.ts start <issue-number> exec
1898
+ ```
1899
+
1900
+ **On successful completion:**
1901
+ ```bash
1902
+ npx tsx scripts/state/update.ts complete <issue-number> exec
1903
+ ```
1904
+
1905
+ **On failure:**
1906
+ ```bash
1907
+ npx tsx scripts/state/update.ts fail <issue-number> exec "Error description"
1908
+ ```
1909
+
1910
+ **Why this matters:** State tracking enables dashboard visibility, resume capability, and workflow orchestration. Skills update state when standalone; orchestrators handle state when running workflows.
1911
+
1912
+ ---
1913
+
795
1914
  ## Output Verification
796
1915
 
797
1916
  **Before responding, verify your output includes ALL of these:**
798
1917
 
1918
+ - [ ] **Self-Evaluation Completed** - Adversarial self-evaluation section included in output
799
1919
  - [ ] **AC Progress Summary** - Which AC items are satisfied, partially met, or blocked
800
1920
  - [ ] **Files Changed** - List of key files modified
801
- - [ ] **Test/Build Results** - Output from `npm test` and `npm run build`
1921
+ - [ ] **Test/Build/Lint Results** - Output from `npm run build`, `npm run lint`, and `npm test`
1922
+ - [ ] **CLI Wiring Check** - If option interfaces modified, verified CLI flags are registered (Section 3g)
1923
+ - [ ] **Quality Plan Alignment** - Included if quality plan was available (or marked N/A if no quality plan)
802
1924
  - [ ] **PR Status** - Created (with URL) or Failed (with error and manual instructions)
803
1925
  - [ ] **Progress Update Draft** - Formatted comment for GitHub issue
804
1926
  - [ ] **Documentation Reminder** - Note if README/docs need updating (checked in /qa)