sequant 1.11.0 → 1.12.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.
@@ -16,6 +16,9 @@ allowed-tools:
16
16
  - Bash(gh pr view:*)
17
17
  - Bash(gh pr diff:*)
18
18
  - Bash(gh pr comment:*)
19
+ - Bash(semgrep:*)
20
+ - Bash(npx semgrep:*)
21
+ - Bash(npx tsx scripts/semgrep-scan.ts:*)
19
22
  - Task
20
23
  - AgentOutputTool
21
24
  ---
@@ -120,11 +123,11 @@ If no feature worktree exists (work was done directly on main):
120
123
 
121
124
  **Spawn ALL THREE agents in a SINGLE message:**
122
125
 
123
- 1. `Task(subagent_type="quality-checker", model="haiku", prompt="Run type safety and deleted tests checks on the current branch vs main. Report: type issues count, deleted tests, verdict.")`
126
+ 1. `Task(subagent_type="general-purpose", model="haiku", prompt="Run type safety and deleted tests checks on the current branch vs main. Report: type issues count, deleted tests, verdict.")`
124
127
 
125
- 2. `Task(subagent_type="quality-checker", model="haiku", prompt="Run scope and size checks on the current branch vs main. Report: files count, diff size, size assessment.")`
128
+ 2. `Task(subagent_type="general-purpose", model="haiku", prompt="Run scope and size checks on the current branch vs main. Report: files count, diff size, size assessment.")`
126
129
 
127
- 3. `Task(subagent_type="quality-checker", model="haiku", prompt="Run security scan on changed files in current branch vs main. Report: critical/warning/info counts, verdict.")`
130
+ 3. `Task(subagent_type="general-purpose", model="haiku", prompt="Run security scan on changed files in current branch vs main. Report: critical/warning/info counts, verdict.")`
128
131
 
129
132
  **Add RLS check if admin files modified:**
130
133
  ```bash
@@ -133,10 +136,52 @@ admin_modified=$(git diff main...HEAD --name-only | grep -E "^app/admin/" | head
133
136
 
134
137
  See [quality-gates.md](references/quality-gates.md) for detailed verdict synthesis.
135
138
 
136
- ### Using MCP Tools (Optional)
139
+ ### MCP Tools (Optional - Graceful Degradation)
137
140
 
138
- - **Sequential Thinking:** For complex multi-step analysis
139
- - **Context7:** For broader pattern context and library documentation
141
+ MCP tools enhance `/qa` but are **not required**. The skill works fully without them.
142
+
143
+ #### MCP Availability Check
144
+
145
+ Before using MCP tools, verify they are available. If unavailable, use the fallback strategies.
146
+
147
+ | MCP Tool | Purpose | Fallback When Unavailable |
148
+ |----------|---------|---------------------------|
149
+ | Sequential Thinking | Complex multi-step analysis | Use explicit step-by-step reasoning in response |
150
+ | Context7 | Library documentation lookup | Use WebSearch or codebase pattern search |
151
+
152
+ #### Sequential Thinking Fallback
153
+
154
+ **When to use Sequential Thinking:**
155
+ - Complex architectural trade-offs during code review
156
+ - Multi-dimensional quality assessment
157
+ - Analyzing interconnected issues across files
158
+
159
+ **If unavailable:**
160
+ 1. Structure your analysis with explicit numbered steps
161
+ 2. Document each concern systematically before synthesizing verdict
162
+ 3. Use a pros/cons format for trade-off decisions
163
+
164
+ ```markdown
165
+ ## Analysis Steps (Manual Sequential Thinking)
166
+
167
+ **Step 1:** [Analyze first dimension - correctness]
168
+ **Step 2:** [Analyze second dimension - maintainability]
169
+ **Step 3:** [Analyze third dimension - performance]
170
+ **Step 4:** [Synthesize findings into verdict]
171
+ ```
172
+
173
+ #### Context7 Fallback
174
+
175
+ **When to use Context7:**
176
+ - Verifying implementation matches library best practices
177
+ - Checking if API usage follows recommended patterns
178
+ - Understanding framework-specific conventions in reviewed code
179
+
180
+ **If unavailable:**
181
+ 1. Search codebase with Grep for existing usage patterns
182
+ 2. Use WebSearch for official library documentation
183
+ 3. Check similar implementations in the codebase as reference
184
+ 4. Review library's README or documentation in node_modules
140
185
 
141
186
  ### 1. Context and AC Alignment
142
187
 
@@ -180,9 +225,32 @@ See [testing-requirements.md](references/testing-requirements.md) for edge case
180
225
 
181
226
  Provide an overall verdict:
182
227
 
183
- - `READY_FOR_MERGE` — AC met and code quality is high ("A+")
184
- - `AC_MET_BUT_NOT_A_PLUS` — AC met, but meaningful improvements recommended
185
- - `AC_NOT_MET` — AC not fully met; additional implementation needed
228
+ - `READY_FOR_MERGE` — ALL ACs are `MET` and code quality is high ("A+")
229
+ - `AC_MET_BUT_NOT_A_PLUS` — ALL ACs are `MET`, but meaningful improvements recommended
230
+ - `NEEDS_VERIFICATION` — ALL ACs are `MET` or `PENDING`, at least one requires external verification
231
+ - `AC_NOT_MET` — One or more ACs are `NOT_MET` or `PARTIALLY_MET`
232
+
233
+ **Verdict Determination Algorithm (REQUIRED):**
234
+
235
+ ```text
236
+ 1. Count AC statuses:
237
+ - met_count = ACs with status MET
238
+ - partial_count = ACs with status PARTIALLY_MET
239
+ - pending_count = ACs with status PENDING
240
+ - not_met_count = ACs with status NOT_MET
241
+
242
+ 2. Determine verdict (in order):
243
+ - IF not_met_count > 0 OR partial_count > 0:
244
+ → AC_NOT_MET (block merge)
245
+ - ELSE IF pending_count > 0:
246
+ → NEEDS_VERIFICATION (wait for verification)
247
+ - ELSE IF improvement_suggestions.length > 0:
248
+ → AC_MET_BUT_NOT_A_PLUS (can merge with notes)
249
+ - ELSE:
250
+ → READY_FOR_MERGE (A+ implementation)
251
+ ```
252
+
253
+ **CRITICAL:** `PARTIALLY_MET` is NOT sufficient for merge. It MUST be treated as `NOT_MET` for verdict purposes.
186
254
 
187
255
  See [quality-gates.md](references/quality-gates.md) for detailed verdict criteria.
188
256
 
@@ -221,9 +289,11 @@ Produce a Markdown snippet for the PR/issue:
221
289
  ### 7. Update GitHub Issue
222
290
 
223
291
  Post the draft comment to GitHub and update labels:
292
+
224
293
  - `AC_NOT_MET`: add `needs-work` label
225
294
  - `READY_FOR_MERGE`: add `ready-for-review` label
226
295
  - `AC_MET_BUT_NOT_A_PLUS`: add `needs-improvement` label
296
+ - `NEEDS_VERIFICATION`: add `needs-verification` label
227
297
 
228
298
  ### 8. Documentation Reminder
229
299
 
@@ -9,14 +9,56 @@ Combine agent outputs into a unified quality assessment:
9
9
  | Type Safety Checker | Type issues count, verdict | High - blocking if issues > 3 |
10
10
  | Scope/Size Checker | Files changed, LOC, assessment | Medium - warning if very large |
11
11
  | Security Scanner | Critical/warning/info counts | High - blocking if criticals > 0 |
12
+ | Semgrep Static Analysis | Critical/warning findings | High - blocking if criticals > 0 |
12
13
  | RLS Checker (conditional) | Violations found | High - blocking if violations |
13
14
 
14
15
  **Synthesis Rules:**
15
16
  - **Any FAIL verdict** → Flag as blocker in manual review
16
- - **Security criticals** → Block merge, require fix before proceeding
17
+ - **Security criticals (including Semgrep)** → Block merge, require fix before proceeding
17
18
  - **All PASS** → Proceed with confidence to manual review
18
19
  - **WARN verdicts** → Note in review, verify manually
19
20
 
21
+ ## Semgrep Integration
22
+
23
+ Semgrep provides static analysis for security vulnerabilities and anti-patterns.
24
+
25
+ ### Verdict Mapping
26
+
27
+ | Semgrep Result | QA Verdict Impact |
28
+ |----------------|-------------------|
29
+ | Critical findings > 0 | **BLOCKING** - `AC_NOT_MET` |
30
+ | Warning findings only | Non-blocking - note in review |
31
+ | No findings | Pass - no impact |
32
+ | Semgrep not installed | Skipped - graceful degradation |
33
+ | Semgrep error | Non-blocking - log error |
34
+
35
+ ### Output Format
36
+
37
+ ```markdown
38
+ ## Static Analysis (Semgrep)
39
+
40
+ ✅ No critical findings
41
+ ⚠️ 2 warnings:
42
+ - src/api/users.ts:47 - Potential SQL injection (user input in query)
43
+ - src/utils/exec.ts:12 - Command injection risk (unsanitized shell arg)
44
+ ```
45
+
46
+ ### Stack-Aware Rulesets
47
+
48
+ Semgrep uses stack-specific rulesets for targeted analysis:
49
+
50
+ | Stack | Rulesets |
51
+ |-------|----------|
52
+ | Next.js | p/typescript, p/javascript, p/react, p/security-audit, p/secrets |
53
+ | Python | p/python, p/django, p/flask, p/security-audit, p/secrets |
54
+ | Go | p/golang, p/security-audit, p/secrets |
55
+ | Rust | p/rust, p/security-audit, p/secrets |
56
+ | Generic | p/security-audit, p/secrets |
57
+
58
+ ### Custom Rules
59
+
60
+ Projects can add custom rules in `.sequant/semgrep-rules.yaml`. These are loaded alongside stack rules automatically.
61
+
20
62
  ## Verdict Criteria
21
63
 
22
64
  ### `READY_FOR_MERGE`
@@ -43,6 +85,17 @@ AC met, but one or more issues:
43
85
 
44
86
  **Action:** List specific improvements, but don't block merge if working
45
87
 
88
+ ### `NEEDS_VERIFICATION`
89
+
90
+ All AC items are `MET`, but one or more items have `PENDING` status requiring external verification:
91
+
92
+ - ⏳ CI/CD verification pending
93
+ - ⏳ Manual testing not yet performed
94
+ - ⏳ External dependency verification needed
95
+ - ⏳ Production environment validation required
96
+
97
+ **Action:** Complete pending verification, then re-run `/qa`
98
+
46
99
  ### `AC_NOT_MET`
47
100
 
48
101
  Any of:
@@ -55,6 +108,37 @@ Any of:
55
108
 
56
109
  **Action:** Block merge, list required fixes
57
110
 
111
+ ## Verdict Determination Algorithm
112
+
113
+ **CRITICAL:** Follow this algorithm exactly when determining the verdict. Do NOT give `READY_FOR_MERGE` unless ALL conditions are met.
114
+
115
+ ```text
116
+ 1. Count AC statuses:
117
+ - met_count = ACs with status MET
118
+ - partial_count = ACs with status PARTIALLY_MET
119
+ - pending_count = ACs with status PENDING
120
+ - not_met_count = ACs with status NOT_MET
121
+
122
+ 2. Determine verdict (in order):
123
+ - IF not_met_count > 0 OR partial_count > 0:
124
+ → AC_NOT_MET (block merge)
125
+ - ELSE IF pending_count > 0:
126
+ → NEEDS_VERIFICATION (wait for verification)
127
+ - ELSE IF improvement_suggestions.length > 0:
128
+ → AC_MET_BUT_NOT_A_PLUS (can merge with notes)
129
+ - ELSE:
130
+ → READY_FOR_MERGE (A+ implementation)
131
+ ```
132
+
133
+ | Verdict | When to Use |
134
+ |--------------------------|----------------------------------------------------------|
135
+ | `READY_FOR_MERGE` | ALL ACs are `MET`, no improvements needed |
136
+ | `AC_MET_BUT_NOT_A_PLUS` | ALL ACs are `MET`, but minor improvements suggested |
137
+ | `NEEDS_VERIFICATION` | ALL ACs are `MET` or `PENDING`, at least one is `PENDING`|
138
+ | `AC_NOT_MET` | ANY AC is `NOT_MET` or `PARTIALLY_MET` |
139
+
140
+ **Important:** `PARTIALLY_MET` is NOT sufficient for merge. It must be treated as `NOT_MET` for verdict purposes.
141
+
58
142
  ## Code Review Decision Framework
59
143
 
60
144
  ### 1. Purpose Test
@@ -0,0 +1,207 @@
1
+ # Semgrep Integration Guide
2
+
3
+ This guide explains how to configure and use Semgrep static analysis in the `/qa` workflow.
4
+
5
+ ## Overview
6
+
7
+ Semgrep is a fast, open-source static analysis tool that finds bugs and enforces code standards. The `/qa` skill integrates Semgrep to automatically scan code changes for security vulnerabilities and anti-patterns.
8
+
9
+ ## Installation
10
+
11
+ Semgrep is **optional**. If not installed, the `/qa` skill will gracefully skip Semgrep analysis.
12
+
13
+ ### Install Semgrep
14
+
15
+ ```bash
16
+ # Using pip (recommended)
17
+ pip install semgrep
18
+
19
+ # Using Homebrew (macOS)
20
+ brew install semgrep
21
+
22
+ # Using npm (via npx - no install required)
23
+ npx semgrep --version
24
+ ```
25
+
26
+ ### Verify Installation
27
+
28
+ ```bash
29
+ semgrep --version
30
+ # Or
31
+ npx semgrep --version
32
+ ```
33
+
34
+ ## How It Works
35
+
36
+ 1. During `/qa`, the quality checks script detects if Semgrep is installed
37
+ 2. If installed, it runs Semgrep with stack-appropriate rulesets
38
+ 3. Findings are categorized by severity (critical, warning, info)
39
+ 4. Critical findings block the merge verdict (`AC_NOT_MET`)
40
+ 5. Warnings are noted but don't block merges
41
+
42
+ ## Default Rulesets
43
+
44
+ Semgrep uses stack-specific rulesets for targeted analysis:
45
+
46
+ | Stack | Rulesets Applied |
47
+ |-------|------------------|
48
+ | **Next.js** | p/typescript, p/javascript, p/react, p/security-audit, p/secrets |
49
+ | **Astro** | p/typescript, p/javascript, p/security-audit, p/secrets |
50
+ | **SvelteKit** | p/typescript, p/javascript, p/security-audit, p/secrets |
51
+ | **Remix** | p/typescript, p/javascript, p/react, p/security-audit, p/secrets |
52
+ | **Nuxt** | p/typescript, p/javascript, p/security-audit, p/secrets |
53
+ | **Python** | p/python, p/django, p/flask, p/security-audit, p/secrets |
54
+ | **Go** | p/golang, p/security-audit, p/secrets |
55
+ | **Rust** | p/rust, p/security-audit, p/secrets |
56
+ | **Generic** | p/security-audit, p/secrets |
57
+
58
+ ## Custom Rules
59
+
60
+ You can add project-specific rules by creating `.sequant/semgrep-rules.yaml` in your project root.
61
+
62
+ ### Getting Started
63
+
64
+ Copy the example template to your project:
65
+
66
+ ```bash
67
+ # Copy the example template
68
+ cp docs/examples/semgrep-rules.example.yaml .sequant/semgrep-rules.yaml
69
+ ```
70
+
71
+ ### Custom Rules File Location
72
+
73
+ ```
74
+ your-project/
75
+ ├── .sequant/
76
+ │ └── semgrep-rules.yaml # Your custom rules
77
+ ├── src/
78
+ └── package.json
79
+ ```
80
+
81
+ ### Example Custom Rules
82
+
83
+ ```yaml
84
+ rules:
85
+ # Prevent console.log in production code
86
+ - id: no-console-log
87
+ pattern: console.log(...)
88
+ message: "Remove console.log before merging"
89
+ severity: WARNING
90
+ languages: [typescript, javascript]
91
+ paths:
92
+ exclude:
93
+ - "**/*.test.*"
94
+ - "**/__tests__/**"
95
+
96
+ # Require explicit return types on exported functions
97
+ - id: explicit-return-type
98
+ pattern: |
99
+ export function $FUNC(...): $RET { ... }
100
+ pattern-not: |
101
+ export function $FUNC(...): void { ... }
102
+ message: "Exported functions should have explicit return types"
103
+ severity: INFO
104
+ languages: [typescript]
105
+
106
+ # Detect potential SQL injection
107
+ - id: sql-injection-risk
108
+ patterns:
109
+ - pattern: $DB.query($SQL + ...)
110
+ - pattern: $DB.query(`...${...}...`)
111
+ message: "Potential SQL injection - use parameterized queries"
112
+ severity: ERROR
113
+ languages: [typescript, javascript]
114
+
115
+ # Prevent hardcoded API keys
116
+ - id: no-hardcoded-api-key
117
+ pattern-regex: "(api[_-]?key|apikey|secret[_-]?key)\\s*[:=]\\s*['\"][^'\"]{8,}['\"]"
118
+ message: "Don't hardcode API keys - use environment variables"
119
+ severity: ERROR
120
+ languages: [typescript, javascript, python]
121
+ ```
122
+
123
+ ### Rule Severity Levels
124
+
125
+ | Severity | Verdict Impact | Description |
126
+ |----------|----------------|-------------|
127
+ | `ERROR` | **Blocking** | Critical issues that must be fixed |
128
+ | `WARNING` | Non-blocking | Issues that should be reviewed |
129
+ | `INFO` | Non-blocking | Style suggestions |
130
+
131
+ ## Running Semgrep Manually
132
+
133
+ You can run Semgrep manually using the provided script:
134
+
135
+ ```bash
136
+ # Scan entire project with auto-detected stack
137
+ npx tsx scripts/semgrep-scan.ts
138
+
139
+ # Scan only changed files (faster, recommended)
140
+ npx tsx scripts/semgrep-scan.ts --changed-only
141
+
142
+ # Scan specific directories
143
+ npx tsx scripts/semgrep-scan.ts src/api/ src/lib/
144
+
145
+ # Override detected stack
146
+ npx tsx scripts/semgrep-scan.ts --stack python
147
+
148
+ # Get JSON output
149
+ npx tsx scripts/semgrep-scan.ts --json > semgrep-results.json
150
+ ```
151
+
152
+ ## Interpreting Results
153
+
154
+ ### Clean Output
155
+
156
+ ```
157
+ ## Static Analysis (Semgrep)
158
+
159
+ ✅ No security issues found
160
+ ```
161
+
162
+ ### Issues Found
163
+
164
+ ```
165
+ ## Static Analysis (Semgrep)
166
+
167
+ ❌ 1 critical finding(s)
168
+ ⚠️ 2 warning(s)
169
+
170
+ ### ❌ Critical Issues
171
+
172
+ - `src/api/users.ts:47` - Potential SQL injection (user input in query) (security.sql-injection)
173
+
174
+ ### ⚠️ Warnings
175
+
176
+ - `src/utils/exec.ts:12` - Command injection risk (unsanitized shell arg) (security.command-injection)
177
+ - `src/lib/logger.ts:8` - Remove console.log before merging (custom.no-console-log)
178
+ ```
179
+
180
+ ## Troubleshooting
181
+
182
+ ### Semgrep Not Running
183
+
184
+ 1. Check if Semgrep is installed: `semgrep --version`
185
+ 2. If not installed, install it or use `npx semgrep`
186
+ 3. Check for error messages in the quality checks output
187
+
188
+ ### False Positives
189
+
190
+ If a rule produces false positives:
191
+
192
+ 1. Add a `# nosemgrep: rule-id` comment to ignore specific lines
193
+ 2. Create custom rules that exclude specific patterns
194
+ 3. Use path exclusions in your custom rules
195
+
196
+ ### Performance
197
+
198
+ - Semgrep only scans changed files by default (via `--changed-only`)
199
+ - Large codebases may take longer on first scan
200
+ - Results are not cached between runs
201
+
202
+ ## Resources
203
+
204
+ - [Semgrep Documentation](https://semgrep.dev/docs/)
205
+ - [Semgrep Rule Registry](https://semgrep.dev/r)
206
+ - [Writing Custom Rules](https://semgrep.dev/docs/writing-rules/overview/)
207
+ - [Rule Syntax Reference](https://semgrep.dev/docs/writing-rules/rule-syntax/)
@@ -92,5 +92,59 @@ else
92
92
  echo " npx not available, skipping security scan"
93
93
  fi
94
94
 
95
+ # 9. Semgrep static analysis (optional - graceful skip if not installed)
96
+ echo ""
97
+ echo "🔍 Running Semgrep static analysis..."
98
+
99
+ # Check if Semgrep is available
100
+ semgrep_available=false
101
+ if command -v semgrep &> /dev/null; then
102
+ semgrep_available=true
103
+ semgrep_cmd="semgrep"
104
+ elif command -v npx &> /dev/null && npx semgrep --version &> /dev/null 2>&1; then
105
+ semgrep_available=true
106
+ semgrep_cmd="npx semgrep"
107
+ fi
108
+
109
+ if [[ "$semgrep_available" == "true" ]]; then
110
+ # Get changed files for targeted scan
111
+ changed_files=$(git diff main...HEAD --name-only | grep -E '\.(ts|tsx|js|jsx|py|go|rs)$' || true)
112
+
113
+ if [[ -n "$changed_files" ]]; then
114
+ # Run Semgrep with security rules on changed files
115
+ echo " Scanning $(echo "$changed_files" | wc -l | xargs) changed file(s)..."
116
+
117
+ # Run with basic security rules, JSON output for reliable parsing
118
+ # Use --quiet to suppress progress
119
+ semgrep_output=$($semgrep_cmd --config p/security-audit --config p/secrets \
120
+ --quiet --no-git-ignore --json \
121
+ $changed_files 2>&1) || semgrep_exit=$?
122
+
123
+ if [[ -z "$semgrep_output" ]] || ! echo "$semgrep_output" | grep -q '"results"'; then
124
+ echo " ✅ Semgrep: No security issues found"
125
+ else
126
+ # Count findings by severity from JSON output
127
+ # Semgrep JSON uses "severity":"ERROR" (uppercase) for critical, "WARNING" for warnings
128
+ critical_count=$(echo "$semgrep_output" | grep -o '"severity":"ERROR"' | wc -l | xargs)
129
+ warning_count=$(echo "$semgrep_output" | grep -o '"severity":"WARNING"' | wc -l | xargs)
130
+
131
+ if [[ "$critical_count" -gt 0 ]]; then
132
+ echo " ❌ Semgrep: $critical_count critical finding(s) - REVIEW REQUIRED"
133
+ fi
134
+ if [[ "$warning_count" -gt 0 ]]; then
135
+ echo " ⚠️ Semgrep: $warning_count warning(s)"
136
+ fi
137
+ if [[ "$critical_count" -eq 0 && "$warning_count" -eq 0 ]]; then
138
+ echo " ✅ Semgrep: No security issues found"
139
+ fi
140
+ fi
141
+ else
142
+ echo " No source files changed, skipping Semgrep scan"
143
+ fi
144
+ else
145
+ echo " ⚠️ Semgrep not installed (optional)"
146
+ echo " Install with: pip install semgrep"
147
+ fi
148
+
95
149
  echo ""
96
150
  echo "✅ Quality checks complete"