AI-powered code quality gates for GitHub PRs. Runs as a GitHub Action. Built for multi-agent development teams but works for any repo.
Hawky enforces quality standards across your codebase by automatically validating pull requests against 10 categories of gatesβfrom TypeScript type safety and ESLint compliance to security scanning, design system enforcement, frontend checks, and more. Uses AI for semantic code review and supports visual regression testing.
Perfect for teams that need consistent, automated, cross-functional collaboration on pull requests.
- TypeScript Type Checking β Catch type errors before merge
- ESLint Linting β Enforce code style and best practices
- Build Verification β Ensure your build succeeds
- Test Execution β Require passing tests before merge
- Semgrep Security Scanning β Custom rules for auth, injection, secrets (p/security-audit ruleset)
- Gitleaks Secret Detection β Prevent API keys and credentials in commits
- npm Audit β Scan dependencies for known vulnerabilities
- Response Shape Validation β Detect breaking changes in API responses
- Breaking Change Detection β Warn when endpoints alter request/response contracts
- Banned Classes Detection β Flag use of deprecated utility classes
- Hardcoded Color Detection β Ensure colors use design tokens
- Spacing Enforcement β Validate spacing values against design system
- Concurrent PR Detection β Warn when multiple PRs modify the same contract/file
- Stale Branch Warnings β Alert when branch is significantly behind main
- Ownership Collision Detection β Prevent uncoordinated changes to shared code
- Story ID Validation β Verify PR references valid sprint story
- Auto-Labeling β Automatically tag PRs based on scope
- Scope Creep Detection β Flag when PR changes exceed story scope
- Unhandled Async State Detection β Catch missing loading/error states in async operations
- Key Prop Analysis β Detect missing or index-based keys in lists
- useEffect Dependency Analysis β Find missing or stale dependencies
- Re-render Trap Detection β Catch unnecessary React re-renders
- Server/Client Boundary Check β Validate proper use of 'use client' directives
- Accessibility Interactive Element Check β Detect a11y violations on interactive elements
- Bundle Size Delta β Monitor JavaScript bundle size changes
- Image Without Dimensions β Flag images missing width/height attributes
- TypeScript Strict Mode Checks β Enforce strict TypeScript patterns
- Import Cycle Detection β Find circular import dependencies
- Component Graph Impact β Analyze component dependency chains
- Import Path Consistency β Ensure consistent import patterns
- Screenshot Diffing β Automated visual testing via Playwright
- Configurable Thresholds β Set tolerance for visual changes
- Semantic Review β AI analyzes code for logical issues, patterns, security
- Powered by Kimi β Uses kimi-2.5 via Azure AI Foundry for optional LLM analysis
- Context-Aware β Understands your team's code patterns and style
- Onboarding Existing Repos β Generate baseline to track only new violations
- Tech Debt Dashboard β Automatic onboarding report shows violations by category
- Hawkyignore File β Permanently suppress false positives or intentional exceptions
- Auto-Detection β Automatically detects TypeScript, Go, Rust, Python, Terraform, Docker, Kubernetes
- Stack-Specific Checks β Runs appropriate gates based on tech stack
Add to your repository's .github/workflows/hawky.yml:
name: Hawky Code Review
on: [pull_request]
jobs:
hawky:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: the-crux-squad/hawky@v1That's it. Hawky uses sensible defaults for all gates.
Create .hawky.yml in your repository root to customize gates:
fail_fast: true
gates:
typescript:
enabled: true
blocking: true
timeout: 300
eslint:
enabled: true
blocking: true # Blocking by default (set to false for warnings-only)
build:
enabled: true
blocking: true
timeout: 600
# command: "yarn build" # Optional: override build command
test:
enabled: true
blocking: true
timeout: 600
semgrep:
enabled: true
blocking: true
timeout: 600
# rulesets: "p/security-audit p/typescript"
gitleaks:
enabled: true
blocking: true
timeout: 300All settings are optional. If not specified, Hawky uses sensible defaults. Core gates (typescript, build, test, eslint, semgrep, gitleaks, npm-audit) are enabled and blocking by default. Optional gates (design-system, frontend-checks, visual) are disabled by default and must be explicitly enabled.
Complete reference of all available gates and their configuration:
| Gate | Type | Default Enabled | Default Blocking | Timeout | Description |
|---|---|---|---|---|---|
typescript |
Core | β | β | 300s | TypeScript type checking |
build |
Core | β | β | 600s | Build verification (npm run build, etc) |
test |
Core | β | β | 600s | Test suite execution |
eslint |
Core | β | β | 300s | ESLint linting |
semgrep |
Security | β | β | 600s | Semgrep security scanning |
gitleaks |
Security | β | β | 300s | Secret detection |
npm-audit |
Security | β | β | 300s | Dependency vulnerability scan |
design-system |
Compliance | β | β | 300s | Design system enforcement (opt-in) |
frontend-checks |
QA | β | β | 300s | React/Next.js pattern detection (12 checks) |
visual |
QA | β | β | 600s | Visual regression testing |
Each gate supports these options:
gates:
<gate_name>:
enabled: boolean # Run this gate? (default: per gate)
blocking: boolean # Block merge on failure? (default: per gate)
timeout: number # Timeout in seconds (default: per gate)
command: string # Override command (build/test gates only)The coordination module detects conflicts between concurrent work across agents and PRs. Configure in .hawky.yml:
coordination:
enabled: true # Master toggle (default: true)
# Individual checks β BLOCK tier (can fail the action)
contract_divergence: true # Detect conflicting API contract changes
parallel_migrations: true # Detect concurrent DB migrations
dependency_enforcement: true # Enforce dependency ordering
# Individual checks β WARN tier (non-blocking)
concurrent_prs: true # Detect PRs modifying same files
stale_branch: true # Warn when branch is behind main
spec_mismatch: true # Detect spec/implementation drift
ownership_collision: true # Detect ownership conflicts
session_handoff: false # Generate handoff notes (opt-in)
test_count_regression: true # Detect test count drops
authorship_attribution: false # Track mixed authorship (opt-in)
# Thresholds
stale_branch_commits: 10 # Commits behind main to trigger warning
stale_branch_days: 2 # Days since last sync to trigger warning| Check | Tier | Default | Description |
|---|---|---|---|
concurrent_prs |
WARN | on | Detects other open PRs modifying the same files |
contract_divergence |
BLOCK | on | Detects conflicting API contract changes |
parallel_migrations |
BLOCK | on | Detects concurrent database migrations |
stale_branch |
WARN | on | Warns when branch is significantly behind main |
spec_mismatch |
WARN | on | Detects drift between specs and implementation |
ownership_collision |
WARN | on | Detects files owned by multiple teams being modified |
dependency_enforcement |
BLOCK | on | Enforces PR dependency ordering |
session_handoff |
WARN | off | Generates handoff notifications for team context |
test_count_regression |
WARN | on | Detects when test count decreases |
authorship_attribution |
WARN | off | Tracks mixed human/AI authorship |
BLOCK tier checks will fail the GitHub Action if violations are found. WARN tier checks add warnings to the PR comment but do not block merge.
Opt-in checks (session_handoff, authorship_attribution) require additional team configuration and are disabled by default.
# Global fail-fast setting
fail_fast: true
# Gate configuration
gates:
typescript:
enabled: true
blocking: true
timeout: 300
build:
enabled: true
blocking: true
timeout: 600
# command: "yarn build" # Optional: override
test:
enabled: true
blocking: true
timeout: 600
# command: "yarn test:ci" # Optional: override
eslint:
enabled: true
blocking: true # Blocking by default
timeout: 300
semgrep:
enabled: true
blocking: true
timeout: 600
# rulesets: "p/security-audit p/typescript" # Custom rulesets
gitleaks:
enabled: true
blocking: true
timeout: 300
npm-audit:
enabled: true # Enabled by default
blocking: true # Blocking by default
timeout: 300
design-system:
enabled: false # Opt-in: disabled by default
blocking: false
timeout: 300
frontend-checks:
enabled: false # Opt-in: disabled by default
blocking: false
timeout: 300
visual:
enabled: false # Opt-in: disabled by default
blocking: false
timeout: 600
# threshold: 0.1 # 0.1% pixel difference tolerance
# Grace period mode (optional)
# Makes all violations warnings during adoption phase
grace_period:
end_date: "2026-04-01" # or use: sprints: 2
# Baseline mode (optional)
# Only NEW violations block merge; existing ones are tracked
# baseline_enabled: true # Generated via workflow_dispatchHawky respects these optional environment variables:
# LLM API key for AI code review (if llm-review gate enabled)
AZURE_AI_FOUNDRY_KEY=your_key_here
AZURE_AI_FOUNDRY_ENDPOINT=https://your-endpoint.azure.com
# GitHub token for cross-repo access (usually not needed)
HAWKY_GITHUB_TOKEN=ghp_...
# Fail-fast mode (stop on first blocking failure)
HAWKY_FAIL_FAST=trueHawky auto-detects your tech stack and runs appropriate gates:
| Stack | Detected By | Gates |
|---|---|---|
| TypeScript/JavaScript | tsconfig.json, package.json |
TypeScript, ESLint, Build, Test |
| Go | go.mod |
Build, Test, Semgrep |
| Rust | Cargo.toml |
Build, Test, Clippy |
| Python | setup.py, requirements.txt, pyproject.toml |
Type checking, Linting, Test, Semgrep |
| Terraform | *.tf files |
Validation, Security scanning |
| Docker | Dockerfile |
Validation, Security scanning |
| Kubernetes | *.yaml in k8s/ or kubernetes/ |
Validation, Security scanning |
Detection is automatic β just enable the gates you want. Hawky intelligently skips gates that don't apply to your stack.
Example: A TypeScript monorepo with Terraform modules will run TypeScript gates on .ts files and Terraform gates on .tf files.
Enable AI-powered semantic code review:
gates:
llm-review:
enabled: true
blocking: false # Typically non-blocking, for visibility
timeout: 600Then set the Azure AI Foundry credentials:
# In your GitHub Actions workflow
env:
AZURE_AI_FOUNDRY_KEY: ${{ secrets.AZURE_AI_FOUNDRY_KEY }}
AZURE_AI_FOUNDRY_ENDPOINT: ${{ secrets.AZURE_AI_FOUNDRY_ENDPOINT }}The LLM gate uses kimi-2.5 via Azure AI Foundry to analyze your code for:
- Logical correctness and potential bugs
- Security vulnerabilities and anti-patterns
- Performance issues and optimization opportunities
- Code clarity and maintainability
- Architectural concerns
Results are posted as a collapsible section in the PR comment for review.
Enable visual regression detection:
gates:
visual:
enabled: true
blocking: false
timeout: 600
# threshold: 0.1 # Allow up to 0.1% pixel differenceHawky uses Playwright to screenshot components/pages and detect visual changes.
Configure in .hawky.yml:
visual:
enabled: true
threshold: 0.1 # 0.1% pixel difference tolerance (default)
headless: true # Run browser headless (default: true)Visual diffs are posted as image comparisons in the PR comment.
Hawky includes features designed specifically for teams where multiple engineers work on shared code:
Warns when multiple PRs modify the same API contract or shared component.
β οΈ Concurrent modifications detected
PR #123 is also modifying POST /api/users response shape
Coordinate with @Luna before merging
Alerts when your branch falls too far behind main (common conflict source).
β οΈ Your branch is 15 commits behind main
Rebase to avoid merge conflicts
Auto-validates that PR references a valid story ID and flags scope creep:
β Story S102 found
β οΈ PR modifies 8 files; S102 scope is "Login form" (typically 3-5 files)
Prevents one team member from using banned utility classes or hardcoded colors.
β 2 design system violations
- src/Button.tsx:42: Banned class '.mt-8' (use spacing tokens)
- src/Card.tsx:15: Hardcoded color '#FF0000' (use $color-error)
For existing codebases with technical debt, use baseline mode to onboard Hawky gradually:
Go to Actions β Hawky Code Review β Run workflow
Select:
- Mode:
baseline(creates new) orbaseline-update(updates existing) - Branch:
main(usually)
Click Run. This creates:
.hawky/baseline.json # Hash of existing violations
.hawky/onboarding-report.md # Human-readable tech debt summary
.hawky/onboarding-report.json # Machine-readable data
After baseline is created:
- Existing violations (in baseline) are non-blocking β
- New violations (not in baseline) are blocking β
- Your team has time to fix baseline violations gradually
Example:
PR adds 2 new ESLint violations + 50 existing violations in modified file
β
Only the 2 NEW violations block merge
The 50 existing ones are already tracked
Automatically generated report shows:
# Hawky Onboarding Report
## Overview
Total violations: 1,247
- Security: 43
- TypeScript: 156
- ESLint: 801
- Other: 247
## Top 10 Files (Hot Spots)
1. src/api/auth.ts: 67 violations
2. src/db/queries.ts: 54 violations
...
## Estimated Effort
~80 hours to resolve all issues
## Recommendations
1. Focus on security violations first (high impact, medium effort)
2. Run ESLint auto-fix on 5 most common rules
3. Schedule tech debt sprints every other week
Create .hawkyignore to permanently suppress violations:
# Ignore all rules in legacy folder
legacy/**
# Ignore specific rule everywhere
eslint:no-console
typescript:TS2345
# Ignore rule in specific folder
semgrep:*:test/fixtures/**
gitleaks:*:test/fixtures/**
# Ignore generated files
*.generated.ts
src/generated/**
Use hawk-ignore comments in code:
// hawk-ignore: This is a workaround for legacy API
const result = eval(userCode);
// hawk-ignore [semgrep:dangerous-eval]: Evaluated in sandbox context
const sandbox = eval('(' + untrusted + ')');Supported formats:
// hawk-ignore: reason
// hawk-ignore [rule]: reason
// hawk-ignore [rule] (missing reason β flagged in review)
// hawk-ignore (missing reason β flagged in review)
Suppressions appear in PR comments for team review:
### Suppressions
β¨ This PR adds 3 new suppression(s)
β οΈ 1 suppression(s) missing justification
| File | Line | Rule | Reason | Status |
|------|------|------|--------|--------|
| src/api.ts | 42 | semgrep:eval | Sandbox context | π New |
| src/db.ts | 15 | eslint:no-console | Debug logging | Existing |
# .hawky.yml
fail_fast: trueAll defaults: every gate enabled and blocking.
gates:
eslint:
blocking: false # Violations don't block mergegates:
test:
command: "npm run test:ci -- --coverage"gates:
typescript:
enabled: true
blocking: true
eslint:
enabled: false # Disabled for this repo
build:
enabled: false
test:
enabled: falsefail_fast: true
gates:
typescript:
enabled: true
# Go build is auto-detected and will run on .go files
build:
enabled: true
# No command needed - auto-detects 'go build' for Go code# All violations become warnings for 2 weeks
grace_period:
sprints: 2 # or: end_date: "2026-03-15"During grace period, violations are reported but don't block. Perfect for team onboarding.
Hawky uses the default github.token for:
- Reading PR metadata
- Posting PR comments
- Reading issues
You don't need to set anything β it's automatic.
Only add a custom token if you need cross-repo access:
- uses: the-crux-squad/hawky@v1
with:
github_token: ${{ secrets.HAWKY_GITHUB_TOKEN }}If using the llm-review gate, add your Azure AI Foundry credentials as secrets:
- uses: the-crux-squad/hawky@v1
env:
AZURE_AI_FOUNDRY_KEY: ${{ secrets.AZURE_AI_FOUNDRY_KEY }}
AZURE_AI_FOUNDRY_ENDPOINT: ${{ secrets.AZURE_AI_FOUNDRY_ENDPOINT }}Get your credentials from Azure AI Foundry. Hawky uses kimi-2.5 as the default model.
If using baseline mode with auto-commit, the action needs contents: write permission (default in Hawky workflow).
Each PR gets a step summary with full details. Click Details on the Hawky check to see:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
HAWKY CODE REVIEW REPORT
βββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β TypeScript (3s)
β Build (12s)
β Test (8s)
β ESLint (2s) - 5 violations
β οΈ Semgrep (18s) - 1 warning
[Full violations table...]
Push a new commit to your PR to re-run all gates. Or check Workflow Runs to manually trigger:
Actions > Hawky Code Review > Run workflow > Select run
View detailed gate logs in Actions > Your PR Run > hawky job.
- uses: the-crux-squad/hawky@v1- uses: the-crux-squad/hawky@v1.0.0- uses: the-crux-squad/hawky@main- Full Configuration Reference β All
.hawky.ymloptions - Integration Guide β Step-by-step setup for different stacks
- API Contracts Guide β Configure contract validation
- Design System Guide β Enforce design tokens
- LLM Review Setup β Configure AI code review
- Visual Regression Guide β Set up screenshot testing
- Troubleshooting β Common issues and solutions
name: Hawky Code Review
on: [pull_request]
jobs:
hawky:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0 # Full history for Gitleaks
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install Dependencies
run: npm ci
- name: Run Hawky
uses: the-crux-squad/hawky@v1
with:
config_path: .hawky.yml
fail_fast: true# .hawky.yml
fail_fast: true
gates:
typescript:
enabled: true
blocking: true
timeout: 300
build:
enabled: true
blocking: true
timeout: 600
test:
enabled: true
blocking: true
timeout: 600
eslint:
enabled: true
blocking: false
semgrep:
enabled: true
blocking: true
rulesets: "p/security-audit"
gitleaks:
enabled: true
blocking: true- Developer opens PR
- Hawky runs automatically on pull request (via
on: [pull_request]) - Each gate executes in sequence
- Failed gates post detailed comments with violations
- Developer fixes issues and pushes a new commit
- Hawky re-runs automatically
- Once all gates pass, PR can be merged
We welcome contributions! Areas looking for help:
- New gates β Add support for additional tools (Clippy, pylint, etc.)
- Stack detection β Improve detection for edge cases
- Documentation β Expand guides and examples
- Bug fixes β Report and fix issues
# Clone
git clone https://github.com/the-crux-squad/hawky.git
cd hawky
# Install
npm install
# Build
npm run build
# Test
npm test
# Lint
npm run lint
# Type check
npm run typecheckCreate a test workflow in a branch:
# .github/workflows/test-hawky.yml
name: Test Hawky
on: [pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ./ # Uses local version, not marketplaceMIT License β See LICENSE file for details.
Hawky is built by The Crux, a team of six engineers. We use Hawky ourselves and refine it continuously.
Questions? Open an issue or start a discussion.
Feature request? We'd love to hear what your team needs. Open a feature request.
Made with β€οΈ by The Crux Squad