Skip to content

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

  1. Pre-commit hook (recommended). Installed by korva sentinel install, runs automatically on every git commit.
  2. Manual scan. korva sentinel check runs the validator over the currently-staged files and prints findings without committing.
  3. CI/CD. korva-sentinel --format json emits a parseable report you can post to GitHub PRs or store as a build artefact.

CLI

Terminal window
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) with file:line:col
  • json — structured report for tooling

Severity profiles

ProfileActive rulesSuggested for
minimalSEC-001 onlyTeams just starting out
standard (default)HEX-001/002/003, SEC-001Balanced architecture + security
strictAll built-in rulesMature teams, total enforcement

Built-in rule families

IDFamilySeverityCatches
HEX-001HexagonalErrorDomain layer importing from infrastructure/application
HEX-002HexagonalErrorApplication layer importing from infrastructure
HEX-003HexagonalErrorconsole.* in src/ (excluding tests)
HEX-004HexagonalErrornew XAdapter(...) outside *.module.ts
HEX-005HexagonalWarning: any without a // korva-ignore: <reason> comment
NAM-001NamingErrorSuffix Dto instead of DTO
NAM-002NamingErrorDI port token not SCREAMING_SNAKE_CASE
NAM-003NamingWarningFiles in /adapters/ not following *.adapter[.variant].ts
SEC-001SecurityErrorHardcoded secrets (password, api_key, secret, token literals)
TEST-001TestingWarningTests 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-003db.query, prisma.*, mongoose.* outside repository/store
  • SEC-002logger.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: "*" or Access-Control-Allow-Origin: *
  • SEC-005 — SQL in template literals with interpolation
  • SEC-006 — admin/internal/user routes without an auth middleware
  • QC-001console.log, debugger;, breakpoint() in src/
  • QC-002: any / as any without 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 available

A bare // korva-ignore (no reason) is itself a violation — Sentinel forces you to write down why you’re suppressing.

Hooks installer

Terminal window
korva sentinel install

Creates / replaces:

  • .git/hooks/pre-commit Runs korva sentinel run --hook=pre-commit. If korva is not on $PATH, the hook prints a warning and lets the commit through — graceful degradation, never blocks new contributors.
  • .git/hooks/post-commit Non-blocking, runs korva 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 rule

Why 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