Sentinel — architecture guardrails on every commit
Sentinel is the Go validator that runs at commit time and blocks architecture violations, hardcoded secrets, layer leaks and bad naming before they reach a PR. Twenty-one built-in rules, fully extensible via YAML.
Updated: 2026-04-30
Sentinel is a Go binary (korva-sentinel) that scans staged files at commit time and blocks the commit on hard violations. It’s the second half of Korva — Vault gives the AI memory, Sentinel makes sure it can’t ship bad code even when the AI ignores its memory.
Three ways to run it
- Pre-commit hook (recommended). Installed by
korva sentinel install, runs automatically on everygit commit. - Manual scan.
korva sentinel checkruns the validator over the currently-staged files and prints findings without committing. - CI/CD.
korva-sentinel --format jsonemits a parseable report you can post to GitHub PRs or store as a build artefact.
CLI
korva-sentinel [--format text|json] [--profile minimal|standard|strict] [--fail-on-warning] [files...]Inputs:
- stdin:
git diff --cached --name-only | korva-sentinel - explicit args:
korva-sentinel src/domain/x.ts src/application/y.ts
Output:
text— coloured icons (✓ pass, ✗ error, ⚠ warning) withfile:line:coljson— structured report for tooling
Severity profiles
| Profile | Active rules | Suggested for |
|---|---|---|
minimal | SEC-001 only | Teams just starting out |
standard (default) | HEX-001/002/003, SEC-001 | Balanced architecture + security |
strict | All built-in rules | Mature teams, total enforcement |
Built-in rule families
| ID | Family | Severity | Catches |
|---|---|---|---|
| HEX-001 | Hexagonal | Error | Domain layer importing from infrastructure/application |
| HEX-002 | Hexagonal | Error | Application layer importing from infrastructure |
| HEX-003 | Hexagonal | Error | console.* in src/ (excluding tests) |
| HEX-004 | Hexagonal | Error | new XAdapter(...) outside *.module.ts |
| HEX-005 | Hexagonal | Warning | : any without a // korva-ignore: <reason> comment |
| NAM-001 | Naming | Error | Suffix Dto instead of DTO |
| NAM-002 | Naming | Error | DI port token not SCREAMING_SNAKE_CASE |
| NAM-003 | Naming | Warning | Files in /adapters/ not following *.adapter[.variant].ts |
| SEC-001 | Security | Error | Hardcoded secrets (password, api_key, secret, token literals) |
| TEST-001 | Testing | Warning | Tests in __tests__/ or test/ instead of co-located |
Documented rules (loaded via YAML)
You can drop a <rule-id>.yaml file in .korva/rules/ and Sentinel will pick it up. See sentinel/rules/AGENTS.md for the canonical reference. Highlights:
- ARC-001 — framework imports (
express,nestjs,prisma…) inside domain/core - ARC-002 — functions over 25 lines or DB calls inside HTTP handlers
- ARC-003 —
db.query,prisma.*,mongoose.*outside repository/store - SEC-002 —
logger.info(password),console.log(token)with sensitive variable names - SEC-003 — direct equality (
==/===) over token/secret/HMAC/signature values (timing attack) - SEC-004 — CORS with
origin: "*"orAccess-Control-Allow-Origin: * - SEC-005 — SQL in template literals with interpolation
- SEC-006 — admin/internal/user routes without an auth middleware
- QC-001 —
console.log,debugger;,breakpoint()insrc/ - QC-002 —
: any/as anywithout justification - DEPS-001 — imports of vulnerable packages (
lodash<4.17.21,moment,node-serialize,eval())
Suppressions
If a rule fires and you have a real reason to keep the code, add an inline comment on the same line:
const publicData: any = response.data // korva-ignore: external API, no static type availableA bare // korva-ignore (no reason) is itself a violation — Sentinel forces you to write down why you’re suppressing.
Hooks installer
korva sentinel installCreates / replaces:
.git/hooks/pre-commitRunskorva sentinel run --hook=pre-commit. Ifkorvais not on$PATH, the hook prints a warning and lets the commit through — graceful degradation, never blocks new contributors..git/hooks/post-commitNon-blocking, runskorva sync --vault --quiet. Used to push observations to Hive when enabled.
Architecture
sentinel/├── validator/│ ├── cmd/korva-sentinel/main.go → entry, flags, dispatch│ └── internal/│ ├── rules/ → Go implementations of each rule│ └── analyzer/ → text/json report generation├── hooks/│ ├── pre-commit│ ├── post-commit│ └── install.sh└── rules/ └── AGENTS.md → canonical doc for every ruleWhy a pre-commit gate?
The AI generates code fast. Code review is slow. The window between “AI wrote code” and “PR opened” is where bad patterns slip in. Sentinel closes that window — the developer sees the violation immediately, on their own machine, before it ever leaves their branch.
Next
- Forge SDD workflow — Sentinel runs as part of the Verify phase
- Sentinel rules reference — every rule with examples
- Self-hosting — running Sentinel in CI