Skip to content

Rule Reference

Statusnone420 edited this page Jun 11, 2026 · 4 revisions

Rule Reference

Diff Drift rules run over changed TS/TSX/JS/JSX AST nodes and package.json dependency drift. They favor useful review prompts over complete static analysis.

Most code rules match structurally: the changed node's before/after source is re-parsed with the file's tree-sitter grammar and matched against a compiled query, so a pattern inside a string literal or comment never triggers a flag and reformatting cannot evade one. A match type column below records how each rule matches. Rules marked differential compare the node's before and after versions — a question only a diff-aware tool can ask — and a few intentionally stay text-based where that is the correct tool (secret markers, env-var assignments). When a structural parse fails, a rule falls back to its text pattern rather than going silent.

Severity

  • High: likely security-sensitive and should be reviewed before commit.
  • Medium: suspicious or dependency-related drift that may be intentional.
  • Low: weaker signal, usually a review reminder.

Rules

Rule Severity Match type Triggers On Notes
Hardcoded secret High Text (markers) AWS-style keys, OpenAI-style keys, or private key markers added to source Flagged everywhere, including test files — a real key in a fixture is still a leak (other rules still suppress in test paths). Marker-based, like gitleaks; does not detect every secret format.
Dynamic code execution High Structural Newly added eval(...)/window.eval(...) or new Function(...) Matches the real call syntax (incl. optional chaining and member form); the words inside a string or comment never flag.
Child process execution High Text Newly added child_process imports or subprocess calls Suppressed in test-like files.
Disabled TLS verification High Structural + text rejectUnauthorized: false (object property) or NODE_TLS_REJECT_UNAUTHORIZED=0 (env var) introduced The object-property form matches quoted or unquoted keys; the env-var form is text. Review for local-dev exceptions before dismissing.
Broadened CORS High Structural CORS origin opened to *, true, or ['*'] Matches the property value structurally, including the array form. Suppressed in test-like files.
Weakened cookie flags High Text (differential) Removal of httpOnly, secure, or weakening sameSite Only fires on modified nodes where the before/after comparison shows weakening.
Loose regex pattern High Structural (differential) Validation regex widened to a catch-all, or — on a modified node — its anchors dropped or length bound removed Extracts regex literals from before and after and compares them; the flag names exactly what weakened. Tightening a pattern stays quiet. Not a full regex semantic analyzer.
Crypto downgrade Medium Structural (differential) A verify/sign call replaced by a newly introduced decode/parse call Compares real callee names, so async variants (verifyAsync, decodeJwt) count and generic parseInt/parseFloat do not. Only fires when the decode is new.
Guard removed Medium Structural (differential) A call that ran only inside an if guard before now runs unconditionally Suppresses the common refactor to an early-return/throw guard clause. A diff-only signal.
Error handling removed Low Structural (differential) A try that wrapped surviving calls is gone after the change Suppressed when the change converts to a .catch() promise chain.
Undeclared import Medium Node field New bare package import not declared in root package.json Ignores relative imports, Node built-ins, and common path aliases.
Disabled guard Low Structural Guard condition rewritten to a constant-falsy value (if (false), if (0), if (null), if (undefined)) Closes the if (0) bypass of the old literal-only check.
Removed sanitization Low Structural (differential) A sanitize/escape/validate call removed, including wrapper-stripping (save(escapeSql(x))save(x)) Compares real callee names, so a name surviving only in a comment neither flags nor masks. A rename to a still-validating name can still prompt.
Permissive logging config Low Text (differential) Redaction emptied or log level lowered Review before committing sensitive logging changes.

Dependency Drift Rules (package.json)

When a drifted package.json changes its dependency or script sections, each changed entry becomes a node with these rules:

Rule Severity Triggers On Notes
Dependency not in lockfile High A dependency added to package.json whose name the lockfile can't vouch for The slopsquatting guard: agents sometimes hallucinate package names. Only fires when a lockfile exists — no lockfile, no accusation. package-lock.json is parsed as JSON; yarn.lock (classic and berry) and pnpm-lock.yaml (v5/v6/v9) entry names are parsed exactly, so a real left-pad cannot vouch for a hallucinated pad. Unrecognized lockfile formats fall back to a loose text check — a false "present" is safer than a false alarm.
New dependency Medium A dependency added and present in the lockfile Verify it's intended and vetted.
Dependency version changed Low A version range changed Confirm the bump is intentional.
npm script changed Medium A script added or modified Scripts run arbitrary shell commands during install and dev.

Removed dependencies and scripts are shown as drift nodes without flags.

False Positives

False positives are expected. Use dismiss when a flag is reviewed and not actionable. If a rule repeatedly flags normal code, open a GitHub Discussion or issue with the code shape and expected behavior.

Adding Rules

Source rules live in src-tauri/src/rules.rs. The tree walker that attaches flags lives in src-tauri/src/heuristics.rs. Dependency drift rules live in src-tauri/src/deps_diff.rs. Add focused Rust tests for every new rule and false-positive suppression.

Clone this wiki locally