Verify AI-generated code with deterministic algorithms — No LLM reviewing LLM.
English | 中文
CodeTrust is a fully local CLI tool designed to verify the quality of AI-generated code (Cursor, Copilot, ChatGPT, etc.). Instead of using an LLM to review LLM output, it applies deterministic static analysis to detect common hallucination patterns and quality issues.
- Hallucination Detection — Phantom imports, unused imports, missing
await, unnecessary try-catch, over-defensive coding, dead logic branches - Security Scanning — Hardcoded secrets, eval usage, query-like SQL injection, XSS vulnerabilities
- Structure Analysis — Cyclomatic/cognitive complexity, function length, nesting depth, parameter count
- Style Consistency — Mixed naming convention detection (camelCase / snake_case)
- Coverage Analysis — Detect files missing corresponding test files
- Auto-fix —
codetrust fixautomatically fixes safe issues (unused imports, debugger, loose equality, unused variables) with dry-run preview - Five-Dimension Scoring — Security, Logic, Structure, Style, Coverage, weighted into a trust score (0-100)
- Fully Local — No cloud uploads, zero external requests
- Bilingual — Automatic Chinese/English output based on system locale
npm install -g @gulu9527/code-trustBoth code-trust and codetrust commands are available after installation.
# Initialize config file
codetrust init
# Scan git staged files
codetrust scan --staged
# Scan diff against main branch
codetrust scan --diff origin/main
# Scan specific files
codetrust scan src/foo.ts src/bar.ts
# JSON output (for CI/CD)
codetrust scan --staged --format json
# Set minimum score threshold (exit code 1 if below)
codetrust scan --staged --min-score 70
# List all rules
codetrust rules list
# Install pre-commit hook
codetrust hook install
# Auto-fix issues (dry-run by default)
codetrust fix src/
# Apply fixes
codetrust fix src/ --apply
# Fix only a specific rule
codetrust fix src/ --apply --rule logic/type-coercionCodeTrust evaluates code across five dimensions, weighted into a total score (0-100):
| Dimension | Weight | Description |
|---|---|---|
| Security | 30% | Hardcoded secrets, eval, SQL injection, XSS |
| Logic | 25% | Hallucination detection: dead logic, unused variables, duplicate conditions |
| Structure | 20% | Complexity, function length, nesting depth |
| Coverage | 15% | Test file coverage |
| Style | 10% | Naming consistency |
Each issue deducts points based on severity, with diminishing penalties for repeated issues of the same severity:
| Severity | Base Penalty | Diminishing Factor |
|---|---|---|
| high | 15 | × 0.7 per repeat |
| medium | 8 | × 0.7 per repeat |
| low | 3 | × 0.7 per repeat |
| info | 0 | — |
For example, 3 high-severity issues deduct 15 + 10.5 + 7.35 = 32.85 (not 45). This prevents a single rule category from dominating the score unfairly.
Each issue is identified by a content-hash fingerprint (SHA256 of rule ID + file path + code snippet), making findings stable across unrelated line shifts.
| Score | Grade | Meaning |
|---|---|---|
| >= 90 | HIGH TRUST | Safe to merge |
| >= 70 | REVIEW | Recommended for review |
| >= 50 | LOW TRUST | Needs careful review |
| < 50 | UNTRUSTED | Should not be merged |
| Rule ID | Severity | Description |
|---|---|---|
logic/phantom-import |
high | Import from non-existent relative path (AI hallucination) |
logic/missing-await |
medium | Missing await on async function call |
logic/any-type-abuse |
medium | Excessive any type usage bypassing type safety |
logic/type-coercion |
medium | Loose equality (==) causing implicit type coercion |
logic/no-nested-ternary |
medium | Nested ternary expressions reducing readability |
logic/unnecessary-try-catch |
medium | Try-catch wrapping simple statements |
logic/dead-branch |
medium | Always true/false conditions, unreachable code |
logic/duplicate-condition |
medium | Duplicate conditions in if-else chains |
logic/empty-catch |
medium | Empty catch block or rethrow-only catch |
logic/identical-branches |
medium | If/else branches with identical code |
logic/no-non-null-assertion |
medium | Non-null assertion (!) risking runtime crashes |
logic/no-self-compare |
medium | Self-comparison (x === x) always true/false |
logic/no-return-assign |
medium | Assignment (=) in return statement, likely meant === |
logic/promise-void |
medium | Floating promise — async call not awaited or returned |
logic/unused-import |
low | Imported module never used |
logic/over-defensive |
low | Excessive null/undefined guards |
logic/unused-variables |
low | Declared but never used variables |
logic/redundant-else |
low | Unnecessary else after return/throw |
logic/magic-number |
low | Unexplained numeric literals (magic numbers) |
logic/duplicate-string |
low | Same string literal repeated 3+ times |
logic/no-reassign-param |
low | Reassigning function parameters |
logic/no-async-without-await |
low | Async function that never uses await |
logic/no-useless-constructor |
low | Empty or super-only constructor |
logic/console-in-code |
info | Leftover console.log debug statements |
| Rule ID | Severity | Description |
|---|---|---|
security/hardcoded-secret |
high | Hardcoded API keys, passwords, tokens |
security/eval-usage |
high | Executable eval(), new Function() and string-based timers; ignores regex/pattern definitions and plain string mentions |
security/sql-injection |
high | Interpolation or concatenation in query-like SQL construction/execution contexts |
security/no-debugger |
high | Debugger statements left in code |
security/dangerous-html |
medium | innerHTML / dangerouslySetInnerHTML |
codetrust fix can automatically fix certain safe issues. It runs in dry-run mode by default — no files are modified until you pass --apply.
| Rule ID | Fix Action |
|---|---|
security/no-debugger |
Delete the debugger line |
logic/unused-import |
Delete the unused import line |
logic/type-coercion |
Replace == with ===, != with !== |
logic/unused-variables |
Delete the unused variable declaration |
# Preview fixes (dry-run, no file changes)
codetrust fix src/
# Apply fixes to files
codetrust fix src/ --apply
# Fix only a specific rule
codetrust fix src/ --apply --rule logic/type-coercionRun codetrust init to generate .codetrust.yml:
version: 1
include:
- "src/**/*.ts"
- "src/**/*.js"
exclude:
- "**/*.test.ts"
- "**/node_modules/**"
weights:
security: 0.30
logic: 0.25
structure: 0.20
style: 0.10
coverage: 0.15
thresholds:
min-score: 70
max-function-length: 40
max-cyclomatic-complexity: 10
max-cognitive-complexity: 20
max-nesting-depth: 4
max-params: 5
rules:
disabled: []
overrides: {}security/eval-usageis intentionally scoped to executable usage. It still flagseval(...),new Function(...), and string-basedsetTimeout/setInterval, but it avoids false positives from detector metadata such aspattern: /.../and from plain string literals that merely mentioneval(.security/sql-injectionrequires both SQL keywords and query-like context such asquery,sql,statement,stmt, or calls like.query(...)/.execute(...). This keeps real query construction findings while reducing noise from non-query metadata or fingerprint assembly.
name: CodeTrust
on:
pull_request:
branches: [main]
jobs:
trust-scan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: GuLu9527/CodeTrust@main
with:
min-score: 70Or install manually:
- uses: actions/setup-node@v4
with:
node-version: '20'
- run: npm install -g @gulu9527/code-trust
- run: codetrust scan --diff origin/main --min-score 70codetrust hook installAutomatically runs CodeTrust scan on every git commit. Use git commit --no-verify to skip.
CodeTrust auto-detects system locale. To override:
# Force Chinese
CODETRUST_LANG=zh codetrust scan --staged
# Force English
CODETRUST_LANG=en codetrust scan --staged- Language: TypeScript 5.x
- Runtime: Node.js 20+
- AST Parsing: @typescript-eslint/typescript-estree
- CLI: Commander.js
- Git: simple-git
- Terminal UI: picocolors + cli-table3
- Config: cosmiconfig
- Testing: Vitest
- Build: tsup
