Quality Gates
Sequant enforces quality checks at every phase. Understanding these gates helps you write code that passes on the first try.
Overview
Section titled “Overview”Quality gates are automated checks that run during the /qa phase. They verify:
- AC Adherence — Does the code satisfy acceptance criteria?
- Type Safety — Are types properly defined?
- Security — Are there vulnerabilities?
- Scope — Are changes within the issue scope?
- CI Status — Are GitHub CI checks passing?
- Build Verification — Is build failure a regression or pre-existing?
AC Adherence
Section titled “AC Adherence”The most important gate: does the code do what the issue asked for?
How It Works
Section titled “How It Works”- Reads acceptance criteria from the issue
- Maps each AC item to code changes
- Verifies each criterion is satisfied
Example
Section titled “Example”Issue AC:
- [ ] AC-1: Add login button to header- [ ] AC-2: Button redirects to /login on click- [ ] AC-3: Button shows "Sign In" textQA Check:
✅ AC-1: LoginButton component added to Header.tsx✅ AC-2: onClick handler calls router.push('/login')✅ AC-3: Button text is "Sign In"- Write clear, testable acceptance criteria
- Each AC should map to a specific code change
- Use verifiable language (“Button shows X” not “Button looks good”)
Type Safety
Section titled “Type Safety”Catches type-related issues that can cause runtime errors.
What Gets Flagged
Section titled “What Gets Flagged”| Issue | Example | Why It’s Bad |
|---|---|---|
any type | const data: any = ... | Defeats TypeScript’s purpose |
as any cast | (data as any).field | Bypasses type checking |
| Missing types | function foo(x) {...} | Implicit any |
| Non-null assertions | data!.field | Assumes value exists |
Example
Section titled “Example”// ❌ Flaggedconst response: any = await fetch('/api/data');const name = (response as any).user.name;
// ✅ Goodinterface ApiResponse { user: { name: string };}const response: ApiResponse = await fetch('/api/data').then(r => r.json());const name = response.user.name;- Define interfaces for API responses
- Use generics instead of
any - Enable
strictmode in tsconfig.json
Security Scans
Section titled “Security Scans”Identifies common security vulnerabilities.
What Gets Checked
Section titled “What Gets Checked”| Vulnerability | Example |
|---|---|
| SQL Injection | Raw SQL with user input |
| XSS | Unescaped HTML output |
| Command Injection | exec() with user input |
| Path Traversal | File paths from user input |
| Hardcoded Secrets | API keys in code |
Example
Section titled “Example”// ❌ Flagged: Command injectionconst output = exec(`git log --author="${userInput}"`);
// ✅ Good: Sanitized inputconst sanitized = userInput.replace(/[^a-zA-Z0-9]/g, '');const output = exec(`git log --author="${sanitized}"`);- Never trust user input
- Use parameterized queries
- Escape output before rendering
- Store secrets in environment variables
Semgrep Static Analysis
Section titled “Semgrep Static Analysis”Semgrep provides AST-aware static analysis that catches issues regex patterns miss.
How It Works
Section titled “How It Works”- Detects your project stack (Next.js, Python, Go, etc.)
- Applies stack-specific rulesets (e.g.,
p/typescript,p/react,p/security-audit) - Loads custom rules from
.sequant/semgrep-rules.yamlif present - Reports findings by severity (critical, warning, info)
What Gets Checked
Section titled “What Gets Checked”| Category | Examples |
|---|---|
| Security | SQL injection, XSS, command injection, hardcoded secrets |
| Code Quality | Unused variables, unreachable code, deprecated APIs |
| Best Practices | Missing error handling, unsafe type assertions |
Severity Impact
Section titled “Severity Impact”| Severity | Verdict Impact |
|---|---|
ERROR / Critical | Blocks merge — AC_NOT_MET |
WARNING | Non-blocking — noted for review |
INFO | Non-blocking — suggestions only |
Custom Rules
Section titled “Custom Rules”Add project-specific rules in .sequant/semgrep-rules.yaml:
rules: - id: no-console-log pattern: console.log(...) message: "Remove console.log before merging" severity: WARNING languages: [typescript, javascript] paths: exclude: - "**/*.test.*"See docs/examples/semgrep-rules.example.yaml for more examples.
Graceful Degradation
Section titled “Graceful Degradation”If Semgrep is not installed, /qa skips the scan with a message:
⚠️ Semgrep not installed (optional) Install with: pip install semgrepThis ensures Semgrep is opt-in and doesn’t block workflows.
CI Status Awareness
Section titled “CI Status Awareness”QA checks GitHub CI status before finalizing verdicts. This prevents premature READY_FOR_MERGE when CI is still running.
How It Works
Section titled “How It Works”- Detects if a PR exists for the current branch
- Runs
gh pr checksto get CI status - Maps CI status to AC status for CI-related criteria
- Factors CI status into the final verdict
CI Status Mapping
Section titled “CI Status Mapping”| CI State | CI Conclusion | AC Status | Verdict Impact |
|---|---|---|---|
completed | success | MET | No impact |
completed | failure | NOT_MET | Blocks merge |
in_progress | - | PENDING | → NEEDS_VERIFICATION |
queued | - | PENDING | → NEEDS_VERIFICATION |
| (no checks) | - | N/A | No CI configured |
CI-Related AC Detection
Section titled “CI-Related AC Detection”QA identifies AC items that depend on CI by matching patterns:
- “Tests pass in CI”
- “CI passes”
- “Build succeeds in CI”
- “GitHub Actions pass”
- “Pipeline passes”
Example
Section titled “Example”AC-1: Add login button → METAC-2: Tests pass in CI → PENDING (CI still running)
Verdict: NEEDS_VERIFICATIONReason: CI checks not yet completeNo CI Configured
Section titled “No CI Configured”If the repository has no CI checks, CI-related AC items are marked N/A with no impact on verdict.
Build Verification
Section titled “Build Verification”When npm run build fails, QA verifies whether the failure is a regression (new) or pre-existing (already on main).
Why This Matters
Section titled “Why This Matters”Without verification, QA might dismiss build failures as “unrelated to our changes” when they’re actually regressions introduced by the PR.
How It Works
Section titled “How It Works”- Run
npm run buildon feature branch - If build fails, run build on main branch (via main repo directory)
- Compare exit codes and error messages
- Classify as regression, pre-existing, or unknown
Verification Logic
Section titled “Verification Logic”| Feature Build | Main Build | Error Match | Classification |
|---|---|---|---|
| ❌ Fail | ✅ Pass | N/A | Regression — failure introduced by PR |
| ❌ Fail | ❌ Fail | Same error | Pre-existing — not blocking |
| ❌ Fail | ❌ Fail | Different | Unknown — manual review needed |
| ✅ Pass | * | N/A | N/A — no verification needed |
Verdict Impact
Section titled “Verdict Impact”| Classification | Verdict Impact |
|---|---|
| Regression detected | Blocks merge — AC_NOT_MET |
| Pre-existing failure | Non-blocking — documented only |
| Unknown | AC_MET_BUT_NOT_A_PLUS — manual review |
| Build passes | No impact |
Example Output
Section titled “Example Output”### Build Verification
| Check | Status ||-------|--------|| Feature branch build | ❌ Failed || Main branch build | ❌ Failed || Error match | ✅ Same error || Regression | **No** (pre-existing) |
**Note:** Build failure is pre-existing on main branch. Not blocking this PR.QA Verdicts
Section titled “QA Verdicts”After running all checks, QA issues one of four verdicts:
| Verdict | Meaning | Action |
|---|---|---|
READY_FOR_MERGE | All AC met, high code quality | Merge the PR |
AC_MET_BUT_NOT_A_PLUS | All AC met, minor improvements suggested | Can merge, consider suggestions |
NEEDS_VERIFICATION | All AC met or pending, awaiting external verification | Complete verification, re-run QA |
AC_NOT_MET | One or more AC not fully met | Fix issues before merge |
Verdict Determination
Section titled “Verdict Determination”Verdicts are determined by AC status counts:
- If any AC is
NOT_METorPARTIALLY_MET: →AC_NOT_MET - If any AC is
PENDING: →NEEDS_VERIFICATION - If improvements are suggested: →
AC_MET_BUT_NOT_A_PLUS - Otherwise: →
READY_FOR_MERGE
Important:
PARTIALLY_METis treated asNOT_METfor verdict purposes. Partial implementations block merge.
Example
Section titled “Example”AC-1: Add login button → METAC-2: Button redirects → METAC-3: CI passes → PENDING (awaiting CI)
Verdict: NEEDS_VERIFICATIONReason: AC-3 requires external verificationScope Analysis
Section titled “Scope Analysis”Detects changes unrelated to the issue being worked on.
What Gets Flagged
Section titled “What Gets Flagged”- Files changed that aren’t mentioned in the plan
- Refactors unrelated to the AC
- “While I was here” improvements
- Formatting changes to untouched code
Example
Section titled “Example”Issue: “Add logout button”
// ❌ Flagged: Unrelated change import { Button } from './Button'; import { Button } from '@/components/Button'; // Unrelated path change
// ❌ Flagged: Scope creep // Also refactored the login button while here const LoginButton = () => ...
// ✅ Good: Only the requested change const LogoutButton = () => <Button onClick={logout}>Sign Out</Button>;- Keep changes focused on the issue
- Save “while I was here” improvements for separate issues
- If you find a bug, create a new issue instead of fixing inline
Quality Loop
Section titled “Quality Loop”When gates fail, the quality loop automatically fixes issues.
How It Works
Section titled “How It Works”┌──────┐ ┌───────────┐ ┌──────────┐│ QA │───▶│ Analyze │───▶│ Fix │──┐└──────┘ │ Failures │ └──────────┘ │ ▲ └───────────┘ │ │ │ └───────────────────────────────────────┘ (up to 3 iterations)Triggering Quality Loop
Section titled “Triggering Quality Loop”# Automatic with run commandnpx sequant run 123 --quality-loop
# Manual after QA/loop 123What Gets Fixed
Section titled “What Gets Fixed”- Type errors (adds proper types)
- Missing AC items (implements missing features)
- Security issues (applies safe patterns)
- Test failures (fixes failing tests)
What Requires Manual Intervention
Section titled “What Requires Manual Intervention”- Architectural decisions
- Ambiguous requirements
- Breaking changes to public APIs
- Security issues requiring design changes
Custom Gates
Section titled “Custom Gates”Projects can add custom quality gates via constitution:
## Quality Requirements
1. Test coverage must exceed 80%2. All public functions need JSDoc comments3. No console.log in production codeThese get checked during /qa along with standard gates.