Static Analysis Engine

kern review

50-rule static analysis for TypeScript that sees structure, not just syntax. Replaces SonarQube with a 3-layer pipeline: AST, KERN IR, and optional LLM analysis.

$ npx kern review src/
50
Built-in Rules
8
Rule Categories
3
Analysis Layers
0
Config Required

Why kern review

Beyond token-matching. Structural analysis.

3-Layer Pipeline

Layer 1 — AST
ts-morph parses TypeScript. Pattern-matching rules run on the syntax tree. Zero false positives from string matching.
Layer 2 — KERN IR
TypeScript is inferred into KERN intermediate representation. Rules analyze machine, config, event, and fn nodes structurally.
Layer 3 — LLM
Optional. Send KERN IR + findings to an LLM for architectural review, pattern suggestions, and natural-language explanations.

Import Graph Tracing

--graph resolves the full import tree from entry files. Findings on upstream dependencies include their distance from the change, so you can prioritize what matters.

# Trace feature path from entry points
kern review --graph src/index.ts

# Only review files changed in current diff
kern review --diff --graph

Cognitive Complexity

Sonar-compatible S3776 implementation. Scores every function independently. Handles else if chains, nested functions, logical operator sequences, recursion, and the ?? operator correctly.

Default threshold: 15. Override with --max-complexity.

CI Quality Gate

--enforce fails the build when thresholds are exceeded. Configure max errors, max warnings, max complexity, and minimum KERN coverage.

kern review --enforce \
  --max-errors 0 \
  --max-warnings 10 \
  --max-complexity 20 \
  --min-coverage 60

SARIF Output

--sarif outputs SARIF 2.1.0 for GitHub Advanced Security integration. Findings appear as code scanning alerts directly in PRs.

Also supports --json for custom tooling and dashboards.

Framework-Aware

Set your target and get framework-specific rules automatically. React hooks violations, Vue reactivity bugs, Next.js Server Component errors, Express security issues.

React Vue Next.js Express Tailwind Native

Rule Reference

50 Rules. 8 Categories.

Base, security, and dead-logic rules are always active. Framework rules activate based on your build target.

Rule ID Description Severity Category
Base — Always Active (12 rules)
floating-promise Async function or .then() chain called without await, return, or void error bug
state-mutation Direct mutation of state via .push(), .splice(), delete on state-like objects error bug
empty-catch Empty catch block silently swallows exceptions warning bug
machine-gap Unreachable states, dead-end states, or transitions referencing unknown states in KERN machine nodes warning / error structure
config-default-mismatch Config interface fields missing from defaults object, or default keys not in the interface warning pattern
event-map-mismatch EventType values without handlers in EventMap, or map keys without matching event types warning pattern
non-exhaustive-switch Switch over a union or machine state type that misses cases (no default clause) warning pattern
cognitive-complexity Function exceeds cognitive complexity threshold (Sonar S3776-compatible) warning structure
template-available Library pattern detected that has a registered KERN template info pattern
handler-extraction Large inline handler (>300 tokens) that should be extracted to a separate fn node info structure
memory-leak Effect creates subscription (addEventListener, setInterval, WebSocket, etc.) without cleanup return error bug
unhandled-async Async function with await but no try/catch or .catch() — unhandled rejection risk warning bug
Security — Always Active (8 rules)
xss-unsafe-html dangerouslySetInnerHTML, v-html, or direct .innerHTML assignment — XSS vector error bug
hardcoded-secret String literals matching API key, JWT, AWS, GitHub, Slack, SendGrid, or Google key patterns error bug
command-injection exec() / spawn() with template literals or string concatenation error bug
no-eval eval() or new Function() — code injection risk error bug
insecure-random Math.random() in security-sensitive context (token, password, key generation) warning bug
cors-wildcard cors() with no options or origin: '*' — allows any domain warning bug
helmet-missing Express app created without helmet() middleware — missing security headers warning bug
open-redirect res.redirect() with unvalidated user input from req.query / req.params error bug
Security v2 — Always Active (6 rules)
jwt-weak-verification jwt.decode() for auth decisions, jwt.verify() without algorithms allowlist, or accepting "none" algorithm warning / error bug
cookie-hardening Auth cookies missing httpOnly, secure, or sameSite flags error / warning bug
csrf-detection Cookie-auth app with state-changing routes but no CSRF protection middleware warning / error bug
csp-strength Weak CSP directives: unsafe-inline, unsafe-eval, wildcard script-src, missing frame-ancestors warning / info bug
path-traversal File system operations or res.sendFile() with user input without path validation error bug
weak-password-hashing MD5/SHA1/SHA256 for passwords, low bcrypt rounds (<10), low PBKDF2 iterations (<100k) error / warning bug
Dead Logic — Always Active (8 rules)
identical-conditions Same condition repeated in an if / else if chain error bug
identical-expressions Both sides of a binary operator are identical: a === a, x - x, x && x error bug
all-identical-branches All branches of if/else or ternary produce the same code — condition has no effect error / warning bug
constant-condition if (true), if (false), while (false), ternary with boolean literal warning / error bug
one-iteration-loop Loop body always exits on first iteration (unconditional break/return/throw) warning bug
unused-collection Array, Map, or Set is populated but never read warning bug
empty-collection-access Collection initialized empty and read but never populated — reads always return empty warning bug
redundant-jump Unnecessary continue at end of loop body or bare return at end of void function info style
React — nextjs | tailwind | web | native (6 rules)
async-effect useEffect(async () => ...) — React does not support async effect callbacks error bug
render-side-effect setState or fetch() called directly in component render body, outside hooks or handlers error bug
unstable-key Missing key prop or key={index} in .map() JSX expressions warning bug
stale-closure Timer in useEffect with empty [] deps may capture stale state values warning bug
state-explosion Component has >5 useState calls — should use useReducer or a state machine warning pattern
hook-order React hook called inside if, loop, or after early return — violates Rules of Hooks error bug
Vue — vue | nuxt (4 rules)
missing-ref-value ref() result used in expression without .value access warning bug
missing-onUnmounted watch() or addEventListener without cleanup in onUnmounted error bug
setup-side-effect Top-level await in <script setup> without onMounted wrapper — SSR issue warning pattern
reactive-destructure Destructuring reactive() loses reactivity — use toRefs() warning bug
Next.js — nextjs only (3 rules)
server-hook Client hooks (useState, useEffect, etc.) used in Server Component without 'use client' error bug
hydration-mismatch Nondeterministic expressions (Date.now(), Math.random(), new Date()) in render cause hydration mismatch warning bug
missing-use-client Event handlers (onClick, onChange, etc.) in Server Component — needs 'use client' warning pattern
Express — express only (3 rules)
unvalidated-input req.body / req.params / req.query used without validation library (zod, joi, yup) error bug
missing-error-middleware Express app without error handling middleware (4-param function) warning pattern
sync-in-handler Synchronous file system or crypto operations in request handlers block the event loop warning pattern

CLI Reference

Usage & Flags

# Basic usage — review a file or directory
kern review src/server.ts
kern review src/

# Recursive scan of all .ts/.tsx files
kern review --recursive src/

# Only review files changed in current git diff
kern review --diff

# Include import graph tracing (feature-path analysis)
kern review --graph src/index.ts

# Enable LLM layer (requires KERN_LLM_KEY or configured provider)
kern review --llm src/

# Run as linter (exit 1 on any error, for pre-commit hooks)
kern review --lint src/

Output Flags

# JSON output for custom tooling
kern review --json src/

# SARIF 2.1.0 output for GitHub Advanced Security
kern review --sarif src/ > results.sarif

Enforcement Flags

# Enforce quality gate — fail if thresholds are exceeded
kern review --enforce src/

# Custom thresholds
kern review --enforce \
  --max-errors 0           # Zero errors allowed (default)
  --max-warnings 10       # Max 10 warnings
  --max-complexity 20     # Max cognitive complexity per function
  --min-coverage 60       # Min KERN coverage percentage

All Flags

Flag Description Default
--json Output findings as JSON false
--sarif Output SARIF 2.1.0 for GitHub code scanning false
--enforce Enable quality gate enforcement (exit 1 on failure) false
--max-complexity Maximum cognitive complexity per function 15
--max-errors Maximum errors allowed (enforcement mode) 0
--max-warnings Maximum warnings allowed (enforcement mode) unlimited
--min-coverage Minimum KERN coverage percentage (enforcement mode) 0
--graph Enable import graph tracing from entry files false
--llm Enable LLM analysis layer (architectural review) false
--diff Only review files changed in current git diff false
--recursive Recursively scan directories for .ts/.tsx files false
--lint Lint mode: exit 1 on any error finding false

CI Integration

GitHub Actions + SARIF

Upload SARIF results to GitHub Advanced Security. Findings appear as code scanning alerts inline on pull requests.

# .github/workflows/kern-review.yml
name: kern review
on: [push, pull_request]

jobs:
  review:
    runs-on: ubuntu-latest
    permissions:
      security-events: write
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: 20

      - run: npm ci

      # Run kern review with SARIF output + enforcement
      - name: kern review
        run: |
          npx kern review --sarif --enforce \
            --max-errors 0 \
            --max-warnings 20 \
            --max-complexity 20 \
            --recursive src/ > results.sarif

      # Upload SARIF to GitHub Advanced Security
      - name: Upload SARIF
        if: always()
        uses: github/codeql-action/upload-sarif@v3
        with:
          sarif_file: results.sarif
          category: kern-review

Diff-Only Mode for PRs

Use --diff to only review files changed in the PR. Combine with --graph to also trace upstream dependencies.

# Only review changed files + their import graph
npx kern review --diff --graph --sarif > results.sarif