sequant 1.15.1 → 1.15.3

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 (48) hide show
  1. package/.claude-plugin/marketplace.json +4 -4
  2. package/.claude-plugin/plugin.json +3 -3
  3. package/README.md +3 -3
  4. package/dist/bin/cli.js +3 -0
  5. package/dist/src/commands/init.js +1 -1
  6. package/dist/src/commands/logs.js +15 -0
  7. package/dist/src/commands/run.d.ts +114 -1
  8. package/dist/src/commands/run.js +513 -31
  9. package/dist/src/commands/stats.js +48 -0
  10. package/dist/src/lib/scope/index.d.ts +1 -0
  11. package/dist/src/lib/scope/index.js +2 -0
  12. package/dist/src/lib/scope/settings-converter.d.ts +28 -0
  13. package/dist/src/lib/scope/settings-converter.js +53 -0
  14. package/dist/src/lib/settings.d.ts +45 -0
  15. package/dist/src/lib/settings.js +30 -0
  16. package/dist/src/lib/test-tautology-detector.d.ts +122 -0
  17. package/dist/src/lib/test-tautology-detector.js +488 -0
  18. package/dist/src/lib/upstream/issues.js +5 -5
  19. package/dist/src/lib/workflow/git-diff-utils.d.ts +39 -0
  20. package/dist/src/lib/workflow/git-diff-utils.js +142 -0
  21. package/dist/src/lib/workflow/log-writer.d.ts +9 -2
  22. package/dist/src/lib/workflow/log-writer.js +9 -3
  23. package/dist/src/lib/workflow/metrics-schema.d.ts +9 -0
  24. package/dist/src/lib/workflow/metrics-schema.js +10 -1
  25. package/dist/src/lib/workflow/phase-detection.d.ts +3 -0
  26. package/dist/src/lib/workflow/phase-detection.js +27 -1
  27. package/dist/src/lib/workflow/qa-cache.d.ts +3 -1
  28. package/dist/src/lib/workflow/qa-cache.js +2 -0
  29. package/dist/src/lib/workflow/run-log-schema.d.ts +90 -3
  30. package/dist/src/lib/workflow/run-log-schema.js +44 -2
  31. package/dist/src/lib/workflow/state-utils.d.ts +46 -0
  32. package/dist/src/lib/workflow/state-utils.js +167 -0
  33. package/dist/src/lib/workflow/token-utils.d.ts +92 -0
  34. package/dist/src/lib/workflow/token-utils.js +170 -0
  35. package/dist/src/lib/workflow/types.d.ts +6 -0
  36. package/dist/src/lib/workflow/types.js +1 -0
  37. package/package.json +4 -4
  38. package/templates/hooks/pre-tool.sh +4 -0
  39. package/templates/skills/assess/SKILL.md +1 -1
  40. package/templates/skills/exec/SKILL.md +5 -4
  41. package/templates/skills/improve/SKILL.md +37 -24
  42. package/templates/skills/loop/SKILL.md +3 -3
  43. package/templates/skills/qa/SKILL.md +66 -1
  44. package/templates/skills/qa/references/code-review-checklist.md +10 -11
  45. package/templates/skills/qa/scripts/quality-checks.sh +16 -0
  46. package/templates/skills/security-review/references/security-checklists.md +89 -36
  47. package/templates/skills/solve/SKILL.md +3 -1
  48. package/templates/skills/spec/SKILL.md +8 -4
@@ -47,9 +47,9 @@ When invoked as `/loop <issue-number>`, your job is to:
47
47
 
48
48
  ### Step 1: Read Previous Phase Output
49
49
 
50
- ```bash
51
- # Read the log file for this issue
52
- cat /tmp/claude-issue-<issue-number>.log
50
+ Use the Read tool to read the log file for this issue:
51
+ ```
52
+ Read(file_path="/tmp/claude-issue-<issue-number>.log")
53
53
  ```
54
54
 
55
55
  Parse the log to find:
@@ -369,7 +369,7 @@ fi
369
369
 
370
370
  **If no verification evidence exists:**
371
371
  1. Prompt: "Script changes detected but no execution verification found. Run `/verify <issue> --command \"<test command>\"` before READY_FOR_MERGE verdict."
372
- 2. Do NOT give `READY_FOR_MERGE` verdict until verification is complete
372
+ 2. Do NOT give `READY_FOR_MERGE` verdict until verification is complete (unless an approved override applies — see Section 9a)
373
373
  3. Verdict should be `AC_MET_BUT_NOT_A_PLUS` with note about missing verification
374
374
 
375
375
  **Why this matters:**
@@ -389,6 +389,59 @@ fi
389
389
  /qa 558 # Re-run, now sees verification, can give READY_FOR_MERGE
390
390
  ```
391
391
 
392
+ ### 9a. Script Verification Override
393
+
394
+ In some cases, `/verify` execution can be safely skipped when script changes are purely cosmetic or have no runtime impact. **Overrides require explicit justification and risk assessment.**
395
+
396
+ **Override Format (REQUIRED when skipping /verify):**
397
+
398
+ ```markdown
399
+ ### Script Verification Override
400
+
401
+ **Requirement:** `/verify` before READY_FOR_MERGE
402
+ **Override:** Yes
403
+ **Justification:** [One of the approved categories below]
404
+ **Risk Assessment:** [None/Low/Medium]
405
+ ```
406
+
407
+ **Approved Override Categories:**
408
+
409
+ | Category | Example | Risk |
410
+ |----------|---------|------|
411
+ | Syntax-only refactor | `catch (error)` → `catch` | None |
412
+ | Comment/documentation changes | Adding JSDoc, updating comments | None |
413
+ | Type annotation additions | Adding `: string`, `: number` | None |
414
+ | Import reorganization | Sorting imports, removing unused | None |
415
+ | Variable rename (no logic change) | `foo` → `bar` with no behavioral change | Low |
416
+ | Dead code removal | Removing unreachable branches | Low |
417
+
418
+ **NOT Approved for Override (always require /verify):**
419
+
420
+ | Category | Example | Why |
421
+ |----------|---------|-----|
422
+ | Logic changes | Modified conditionals, new branches | Runtime behavior changes |
423
+ | New functionality | Added functions, new exports | Must verify execution |
424
+ | Dependency changes | Updated imports from new packages | May affect runtime |
425
+ | Error handling changes | Modified catch blocks, new try/catch | Failure paths change |
426
+ | Configuration changes | Modified env vars, config parsing | Environment-dependent |
427
+
428
+ **Risk Assessment Definitions:**
429
+
430
+ | Level | Meaning | Criteria |
431
+ |-------|---------|----------|
432
+ | **None** | Zero runtime impact | Change is invisible at runtime (comments, types, syntax) |
433
+ | **Low** | Negligible runtime impact | Change is cosmetic (rename, dead code) with no logical effect |
434
+ | **Medium** | Possible runtime impact | Change touches executable code but appears safe — **should NOT be overridden** |
435
+
436
+ **Override Decision Flow:**
437
+
438
+ 1. Check if change matches an approved category → If no, `/verify` is required
439
+ 2. Assess risk level → If Medium or higher, `/verify` is required
440
+ 3. Document override using the format above in the QA output
441
+ 4. Include override in the GitHub issue comment for audit trail
442
+
443
+ **CRITICAL:** When in doubt, run `/verify`. Overrides are for clear-cut cases only. If you need to argue that a change is safe, it probably needs verification.
444
+
392
445
  ---
393
446
 
394
447
  ## Output Verification
@@ -399,6 +452,7 @@ fi
399
452
  - [ ] **Verdict** - One of: READY_FOR_MERGE, AC_MET_BUT_NOT_A_PLUS, AC_NOT_MET
400
453
  - [ ] **Quality Metrics** - Type issues, deleted tests, files changed, additions/deletions
401
454
  - [ ] **Code Review Findings** - Strengths, issues, suggestions
455
+ - [ ] **Script Verification Override** - Included if scripts/CLI modified AND /verify was skipped (with justification and risk assessment)
402
456
  - [ ] **Documentation Check** - README/docs updated if feature adds new functionality
403
457
  - [ ] **Next Steps** - Clear, actionable recommendations
404
458
 
@@ -447,6 +501,17 @@ You MUST include these sections:
447
501
 
448
502
  ---
449
503
 
504
+ ### Script Verification Override
505
+
506
+ [Include if scripts/CLI modified AND /verify was skipped, otherwise omit this section]
507
+
508
+ **Requirement:** `/verify` before READY_FOR_MERGE
509
+ **Override:** Yes
510
+ **Justification:** [Approved category from Section 9a]
511
+ **Risk Assessment:** [None/Low/Medium]
512
+
513
+ ---
514
+
450
515
  ### Verdict: [READY_FOR_MERGE | AC_MET_BUT_NOT_A_PLUS | AC_NOT_MET]
451
516
 
452
517
  [Explanation of verdict]
@@ -51,16 +51,15 @@ If project uses a database with access controls:
51
51
 
52
52
  ## Integration Check
53
53
 
54
- Verify new exports are imported somewhere:
55
- ```bash
54
+ Verify new exports are imported somewhere using the Grep tool:
55
+ ```
56
+ # 1. Get new files from git
56
57
  new_files=$(git diff main...HEAD --name-only --diff-filter=A | grep -E "\.(ts|tsx)$" || true)
57
- for file in $new_files; do
58
- exports=$(grep -oE "export (const|function|class|type|interface) ([A-Za-z_][A-Za-z0-9_]*)" "$file" | awk '{print $3}')
59
- for exp in $exports; do
60
- import_count=$(grep -r "import.*$exp" --include="*.ts" --include="*.tsx" . | grep -v "$file" | wc -l | xargs)
61
- if [[ $import_count -eq 0 ]]; then
62
- echo "⚠️ '$exp' exported from $file but never imported"
63
- fi
64
- done
65
- done
58
+
59
+ # 2. For each new file, use Grep to find exports:
60
+ # Grep(pattern="export (const|function|class|type|interface)", path="<file>", output_mode="content")
61
+
62
+ # 3. For each export, use Grep to check if it's imported anywhere:
63
+ # Grep(pattern="import.*<export_name>", glob="*.{ts,tsx}")
64
+ # If no matches (excluding the source file), flag as unused export
66
65
  ```
@@ -600,6 +600,22 @@ if [[ $hit_count -gt 0 ]]; then
600
600
  fi
601
601
  echo ""
602
602
 
603
+ # Write structured cache metrics JSON for sequant observability (AC-7)
604
+ # This file is read by run.ts to populate PhaseLog.cacheMetrics
605
+ CACHE_METRICS_DIR=".sequant/.cache/qa"
606
+ mkdir -p "$CACHE_METRICS_DIR"
607
+
608
+ # Build JSON with per-check status
609
+ CACHE_JSON="{\"hits\":$hit_count,\"misses\":$miss_count,\"skipped\":$skip_count,\"checks\":{"
610
+ first=true
611
+ for check in "type-safety" "deleted-tests" "scope" "size" "security" "semgrep" "build"; do
612
+ $first || CACHE_JSON+=","
613
+ CACHE_JSON+="\"$check\":\"${CACHE_STATUS[$check]:-MISS}\""
614
+ first=false
615
+ done
616
+ CACHE_JSON+="}}"
617
+ echo "$CACHE_JSON" > "$CACHE_METRICS_DIR/cache-metrics.json"
618
+
603
619
  echo "✅ Quality checks complete"
604
620
 
605
621
  # Exit with build verification result if it indicates a problem
@@ -8,8 +8,11 @@ Detailed checklists for each security domain, used by the `/security-review` ski
8
8
  **Requirement:** Passwords must use bcrypt/argon2 with appropriate cost factor.
9
9
 
10
10
  **How to Verify:**
11
- ```bash
12
- grep -r "bcrypt\|argon2\|hashPassword" lib/ app/
11
+
12
+ Use the Grep tool for content search:
13
+ ```
14
+ Grep(pattern="bcrypt|argon2|hashPassword", path="lib/")
15
+ Grep(pattern="bcrypt|argon2|hashPassword", path="app/")
13
16
  ```
14
17
 
15
18
  **Good:**
@@ -27,8 +30,10 @@ const hash = crypto.createHash('sha256').update(password).digest('hex')
27
30
  **Requirement:** Session tokens must be cryptographically random.
28
31
 
29
32
  **How to Verify:**
30
- ```bash
31
- grep -r "crypto.randomBytes\|uuid\|nanoid" lib/auth/
33
+
34
+ Use the Grep tool for content search:
35
+ ```
36
+ Grep(pattern="crypto.randomBytes|uuid|nanoid", path="lib/auth/")
32
37
  ```
33
38
 
34
39
  **Good:**
@@ -45,8 +50,11 @@ const token = Date.now().toString(36)
45
50
  **Requirement:** Sessions must expire within appropriate timeframe.
46
51
 
47
52
  **How to Verify:**
48
- ```bash
49
- grep -r "maxAge\|expires\|TTL" lib/auth/ app/api/auth/
53
+
54
+ Use the Grep tool for content search:
55
+ ```
56
+ Grep(pattern="maxAge|expires|TTL", path="lib/auth/")
57
+ Grep(pattern="maxAge|expires|TTL", path="app/api/auth/")
50
58
  ```
51
59
 
52
60
  **Good:** 15-60 minutes for sensitive, 1-7 days for general.
@@ -64,8 +72,11 @@ grep -r "maxAge\|expires\|TTL" lib/auth/ app/api/auth/
64
72
  **Requirement:** Reset tokens must be single-use and time-limited.
65
73
 
66
74
  **How to Verify:**
67
- ```bash
68
- grep -r "resetToken\|passwordReset" lib/ app/
75
+
76
+ Use the Grep tool for content search:
77
+ ```
78
+ Grep(pattern="resetToken|passwordReset", path="lib/")
79
+ Grep(pattern="resetToken|passwordReset", path="app/")
69
80
  ```
70
81
 
71
82
  **Good:** Token expires in 1 hour, deleted after use.
@@ -76,8 +87,11 @@ grep -r "resetToken\|passwordReset" lib/ app/
76
87
  **Requirement:** Failed login attempts must be rate-limited.
77
88
 
78
89
  **How to Verify:**
79
- ```bash
80
- grep -r "rateLimit\|loginAttempts\|throttle" lib/ app/api/auth/
90
+
91
+ Use the Grep tool for content search:
92
+ ```
93
+ Grep(pattern="rateLimit|loginAttempts|throttle", path="lib/")
94
+ Grep(pattern="rateLimit|loginAttempts|throttle", path="app/api/auth/")
81
95
  ```
82
96
 
83
97
  **Good:** 5 attempts per 15 minutes.
@@ -86,8 +100,10 @@ grep -r "rateLimit\|loginAttempts\|throttle" lib/ app/api/auth/
86
100
  **Requirement:** Password comparison must be constant-time.
87
101
 
88
102
  **How to Verify:**
89
- ```bash
90
- grep -r "timingSafeEqual\|bcrypt.compare" lib/auth/
103
+
104
+ Use the Grep tool for content search:
105
+ ```
106
+ Grep(pattern="timingSafeEqual|bcrypt.compare", path="lib/auth/")
91
107
  ```
92
108
 
93
109
  **Good:**
@@ -116,8 +132,11 @@ if (input === password) // Direct comparison leaks timing info
116
132
  **Requirement:** Every sensitive endpoint must check authentication.
117
133
 
118
134
  **How to Verify:**
119
- ```bash
120
- grep -r "requireAuth\|getServerSession\|authenticate" app/api/ app/admin/
135
+
136
+ Use the Grep tool for content search:
137
+ ```
138
+ Grep(pattern="requireAuth|getServerSession|authenticate", path="app/api/")
139
+ Grep(pattern="requireAuth|getServerSession|authenticate", path="app/admin/")
121
140
  ```
122
141
 
123
142
  **Good:** Middleware checks auth before route handler.
@@ -128,8 +147,11 @@ grep -r "requireAuth\|getServerSession\|authenticate" app/api/ app/admin/
128
147
  **Requirement:** Role checks must happen before privileged actions.
129
148
 
130
149
  **How to Verify:**
131
- ```bash
132
- grep -r "role\|isAdmin\|hasPermission" lib/ app/
150
+
151
+ Use the Grep tool for content search:
152
+ ```
153
+ Grep(pattern="role|isAdmin|hasPermission", path="lib/")
154
+ Grep(pattern="role|isAdmin|hasPermission", path="app/")
133
155
  ```
134
156
 
135
157
  **Good:**
@@ -173,8 +195,11 @@ const item = await db.items.findUnique({ where: { id: itemId } })
173
195
  **Requirement:** Admin actions must be logged for audit.
174
196
 
175
197
  **How to Verify:**
176
- ```bash
177
- grep -r "audit\|logAction\|createAuditLog" lib/ app/admin/
198
+
199
+ Use the Grep tool for content search:
200
+ ```
201
+ Grep(pattern="audit|logAction|createAuditLog", path="lib/")
202
+ Grep(pattern="audit|logAction|createAuditLog", path="app/admin/")
178
203
  ```
179
204
 
180
205
  **Good:**
@@ -190,8 +215,11 @@ await logAuditEvent({ action: 'approve_item', actor: userId, target: itemId })
190
215
  **Requirement:** All inputs must be validated with schemas.
191
216
 
192
217
  **How to Verify:**
193
- ```bash
194
- grep -r "z\.\|zod\|yup\|joi" lib/validations/ app/api/
218
+
219
+ Use the Grep tool for content search:
220
+ ```
221
+ Grep(pattern="z\\.|zod|yup|joi", path="lib/validations/")
222
+ Grep(pattern="z\\.|zod|yup|joi", path="app/api/")
195
223
  ```
196
224
 
197
225
  **Good:**
@@ -216,8 +244,11 @@ const { name } = req.body // No validation
216
244
  **Requirement:** Queries must use parameterized statements.
217
245
 
218
246
  **How to Verify:**
219
- ```bash
220
- grep -r "raw\|execute\|query" lib/ app/
247
+
248
+ Use the Grep tool for content search:
249
+ ```
250
+ Grep(pattern="raw|execute|query", path="lib/")
251
+ Grep(pattern="raw|execute|query", path="app/")
221
252
  ```
222
253
 
223
254
  **Good:**
@@ -237,16 +268,22 @@ db.query(`SELECT * FROM items WHERE id = ${itemId}`)
237
268
  **Requirement:** Public endpoints must be rate-limited.
238
269
 
239
270
  **How to Verify:**
240
- ```bash
241
- grep -r "rateLimit\|Ratelimit" middleware/ lib/
271
+
272
+ Use the Grep tool for content search:
273
+ ```
274
+ Grep(pattern="rateLimit|Ratelimit", path="middleware/")
275
+ Grep(pattern="rateLimit|Ratelimit", path="lib/")
242
276
  ```
243
277
 
244
278
  ### API-5: CORS Configuration
245
279
  **Requirement:** CORS must be properly configured.
246
280
 
247
281
  **How to Verify:**
248
- ```bash
249
- grep -r "cors\|Access-Control" next.config.js middleware/
282
+
283
+ Use the Grep tool for content search:
284
+ ```
285
+ Grep(pattern="cors|Access-Control", path="next.config.js")
286
+ Grep(pattern="cors|Access-Control", path="middleware/")
250
287
  ```
251
288
 
252
289
  **Good:** Specific origins allowed.
@@ -274,8 +311,11 @@ return { error: err.message, stack: err.stack }
274
311
  **Requirement:** Uploads must validate type, size, and name.
275
312
 
276
313
  **How to Verify:**
277
- ```bash
278
- grep -r "upload\|multipart\|formData" app/api/ lib/
314
+
315
+ Use the Grep tool for content search:
316
+ ```
317
+ Grep(pattern="upload|multipart|formData", path="app/api/")
318
+ Grep(pattern="upload|multipart|formData", path="lib/")
279
319
  ```
280
320
 
281
321
  **Good:**
@@ -314,8 +354,11 @@ if (file.size > 5 * 1024 * 1024) throw Error
314
354
  **Requirement:** Logs must not contain sensitive data.
315
355
 
316
356
  **How to Verify:**
317
- ```bash
318
- grep -r "console.log\|logger" lib/ app/ | head -20
357
+
358
+ Use the Grep tool for content search:
359
+ ```
360
+ Grep(pattern="console.log|logger", path="lib/", head_limit=20)
361
+ Grep(pattern="console.log|logger", path="app/", head_limit=20)
319
362
  ```
320
363
 
321
364
  **Bad:**
@@ -338,8 +381,11 @@ console.log('User login:', { email, password })
338
381
  **Requirement:** Secrets must be in env vars, not code.
339
382
 
340
383
  **How to Verify:**
341
- ```bash
342
- grep -r "process.env" lib/ app/ | head -10
384
+
385
+ Use the Grep tool for content search:
386
+ ```
387
+ Grep(pattern="process.env", path="lib/", head_limit=10)
388
+ Grep(pattern="process.env", path="app/", head_limit=10)
343
389
  ```
344
390
 
345
391
  **Good:** API keys in `.env.local`, read via `process.env`.
@@ -350,8 +396,12 @@ grep -r "process.env" lib/ app/ | head -10
350
396
  **Requirement:** No secrets committed to repository.
351
397
 
352
398
  **How to Verify:**
353
- ```bash
354
- grep -ri "password\|secret\|apikey\|api_key" --include="*.ts" --include="*.tsx" . | grep -v "process.env"
399
+
400
+ Use the Grep tool for content search (filter results excluding process.env):
401
+ ```
402
+ Grep(pattern="password|secret|apikey|api_key", glob="*.ts", -i=true)
403
+ Grep(pattern="password|secret|apikey|api_key", glob="*.tsx", -i=true)
404
+ # Then manually filter out lines containing "process.env"
355
405
  ```
356
406
 
357
407
  ### INFRA-3: Dependencies Up to Date
@@ -366,8 +416,11 @@ npm audit
366
416
  **Requirement:** Content Security Policy should be configured.
367
417
 
368
418
  **How to Verify:**
369
- ```bash
370
- grep -r "Content-Security-Policy\|CSP" next.config.js middleware/
419
+
420
+ Use the Grep tool for content search:
421
+ ```
422
+ Grep(pattern="Content-Security-Policy|CSP", path="next.config.js")
423
+ Grep(pattern="Content-Security-Policy|CSP", path="middleware/")
371
424
  ```
372
425
 
373
426
  ### INFRA-5: Security Headers
@@ -106,7 +106,9 @@ gh issue view <issue-number> --json body --jq '.body' | grep -iE "(feature/|bran
106
106
  gh issue view <issue-number> --json labels --jq '.labels[].name' | grep -iE "(dashboard|feature-|epic-)"
107
107
 
108
108
  # Check if project has defaultBase configured
109
- cat .sequant/settings.json 2>/dev/null | jq -r '.run.defaultBase // empty'
109
+ # Use the Read tool to check project settings
110
+ Read(file_path=".sequant/settings.json")
111
+ # Extract .run.defaultBase from the JSON
110
112
  ```
111
113
 
112
114
  **Recommend `--base <branch>` when:**
@@ -198,8 +198,10 @@ console.log(formatACLintResults(lintResults));
198
198
  **You MUST spawn sub-agents for context gathering.** Do NOT explore the codebase inline with Glob/Grep commands. Sub-agents provide parallel execution, better context isolation, and consistent reporting.
199
199
 
200
200
  **Check agent execution mode first:**
201
- ```bash
202
- parallel=$(cat .sequant/settings.json 2>/dev/null | jq -r '.agents.parallel // false')
201
+ Use the Read tool to check project settings:
202
+ ```
203
+ Read(file_path=".sequant/settings.json")
204
+ # Parse JSON and extract agents.parallel (default: false)
203
205
  ```
204
206
 
205
207
  #### If parallel mode enabled:
@@ -237,8 +239,10 @@ Before creating the implementation plan, check if a custom base branch should be
237
239
  ```
238
240
 
239
241
  3. **Check if project has defaultBase configured**:
240
- ```bash
241
- cat .sequant/settings.json 2>/dev/null | jq -r '.run.defaultBase // empty'
242
+ Use the Read tool to check settings:
243
+ ```
244
+ Read(file_path=".sequant/settings.json")
245
+ # Extract .run.defaultBase from JSON
242
246
  ```
243
247
 
244
248
  4. **If feature branch context detected**, include in plan output: