Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.sigilix.ai/llms.txt

Use this file to discover all available pages before exploring further.

deterministicChecks is the sigilix.json v3 field for regex rules that run before the LLM specialists. Matches surface as structured findings injected into specialist prompts as authoritative facts. This page is the practical reference. For the conceptual layer (why deterministic checks exist alongside LLMs), see Deterministic Checks.

Quick example

{
  "deterministicChecks": [
    {
      "id": "no-console-log",
      "pattern": "^\\+.*console\\.log\\(",
      "severity": "warning",
      "message": "Stray console.log left in committed code."
    }
  ]
}
That rule, on every review, scans added diff lines (lines starting with +) for console.log(. Any match becomes a warning finding the synthesizer must contend with.

Rule shape

{
  "id":       "kebab-case-id",
  "pattern":  "JavaScript regex source",
  "severity": "info | warning | critical",
  "message":  "what the finding says",
  "flags":    "i"
}
FieldTypeRequiredNotes
idstringyesKebab-case, unique within this config. Used in telemetry.
patternstringyesRegex source (no surrounding slashes). Standard JavaScript regex semantics.
severity"info" | "warning" | "critical"yesMaps to score 2 / 4 / 5.
messagestringyesOne-line finding text. Markdown is allowed.
flagsstringnoRegex flags. i for case-insensitive. Do not pass g — it’s implied.

What the regex runs against

Each rule runs against added diff lines — the lines starting with + in the unified diff, with the + itself included in the input. To anchor to a real added line, start your pattern with ^\+.
{
  "pattern": "^\\+.*XXX"
}
That matches + // XXX: revisit this but won’t match // XXX in an unchanged context line. This means deterministic checks don’t see deletions, context, or anything outside the changed hunks. If you want a check that fires on the presence of a pattern in the file (regardless of whether this PR touched it), that’s an AST rule pack, not deterministicChecks.

Severity mapping

SeverityScoreSynthesizer behavior
info2Surfaces as an inline finding only if no higher-severity findings dominate
warning4Always surfaces; included in the verdict body
critical5Always surfaces; sets the verdict to Request changes
Deterministic checks are authoritative within their domain. The synthesizer doesn’t down-grade a critical deterministic finding the way it can down-grade an LLM finding whose structural provenance is weak — by construction, a regex match has perfect provenance.

Writing the regex

The pattern is plain JavaScript regex syntax. Double-escape backslashes for JSON.
You wantYou write in JSON
\d+"\\d+"
\b"\\b"
\."\\."
^\+"^\\+"
`(?:foobar)`"(?:foo|bar)"
The harness implicitly compiles with the g flag so the rule can match multiple times per file. Don’t pass g yourself — it’s a no-op and may produce a warning.

Lookbehind & advanced features

Most ES2018+ regex features work: lookbehind ((?<=...)), named groups ((?<name>...)), unicode property escapes (\p{Letter}). If you need a feature that requires a specific flag (e.g., u for unicode property escapes), include it in flags.

Worked examples

Stray debug prints

{
  "id": "no-debug-prints",
  "pattern": "^\\+.*(?:console\\.(log|debug|trace)|System\\.out\\.println|print\\()",
  "severity": "warning",
  "message": "Debug print left in committed code."
}

Hardcoded secrets

[
  {
    "id": "no-aws-access-key",
    "pattern": "AKIA[0-9A-Z]{16}",
    "severity": "critical",
    "message": "Possible AWS access key leak."
  },
  {
    "id": "no-stripe-live-key",
    "pattern": "sk_live_[0-9a-zA-Z]{24,}",
    "severity": "critical",
    "message": "Live Stripe secret key detected. This must be rotated and removed."
  }
]
Sigilix also ships a built-in secret scanner (ARC-187) that catches the most common providers. Use deterministicChecks for repo-specific secret patterns the built-in scanner won’t know about (internal API key prefixes, partner credentials).

Forbidden imports

{
  "id": "no-moment",
  "pattern": "^\\+.*(?:from|require)\\s*\\(?['\"]moment['\"]",
  "severity": "warning",
  "message": "moment is deprecated; use date-fns or temporal."
}

Banned APIs in production paths

{
  "id": "no-eval-in-src",
  "pattern": "^\\+.*\\beval\\s*\\(",
  "severity": "critical",
  "message": "eval() is forbidden in src/. Use a parser if you need dynamic interpretation."
}
This catches eval( in any added line. To scope to a path subtree, combine with pathFilters to exclude tests where eval may be legitimate.

TODO / FIXME hygiene

{
  "id": "no-undated-todo",
  "pattern": "^\\+.*\\b(?:TODO|FIXME)\\b(?!.*\\(\\d{4}-\\d{2}-\\d{2}\\))",
  "severity": "info",
  "message": "TODO/FIXME without a (YYYY-MM-DD) marker — tag a date or owner."
}
The lookahead asserts the line does not contain a (YYYY-MM-DD) date. Inverted-assertion regexes get unwieldy fast; this is about the upper limit of complexity worth doing in deterministicChecks versus an AST rule pack.

Gotchas

The + is in the input

Forgetting this is the #1 mistake. "console\\.log" matches both added and context lines. "^\\+.*console\\.log" only matches added lines.

JSON escaping doubles the slashes

\b (word boundary) is "\\b" in JSON. \\b in JSON is a literal backspace character — wrong. If your rule isn’t firing, paste the pattern into an MDN regex tester and check that it compiles to the regex you think it should.

Don’t match the diff metadata

Diff headers (diff --git, +++ b/path) start with + too. To avoid matching +++ b/..., anchor with ^\+[^+] instead of just ^\+:
{ "pattern": "^\\+[^+].*console\\.log" }
This is rarely needed — most patterns are specific enough to not collide with diff metadata — but worth knowing if you see a phantom match on the file header.

Severity inflation costs trust

Tagging every TODO as critical is a fast way to teach your team to ignore Sigilix. Use info and warning liberally; reserve critical for things that genuinely should block merge (secrets, banned APIs, security regressions).

Validation

Sigilix validates each rule on every review:
  • id, pattern, severity, message are required.
  • pattern must be a compilable JavaScript regex. Invalid regex → that rule is dropped, warning logged in telemetry, review proceeds with remaining rules.
  • Duplicate id within a single config → second occurrence dropped.
  • Severity must be one of the three values; unknown severity → rule dropped.
A single broken rule doesn’t break the review. Defective rules are silently dropped so the rest of deterministicChecks still fires.

Deterministic Checks — how it works

The pre-LLM signal layer, end-to-end.

Configuration reference

Full sigilix.json schema.