Skip to main content

Architecture

SigmaShake is designed as a deterministic rule engine that operates at the AI agent's tool-call boundary. It ships as a self-contained Go binary with a small, pinned set of modules (go.mod and go.sum in sigmashake-gov/go).

System overview​

User/Agent → Tool Call → ssg eval → Engine → Decision → Audit Log
↓
Dashboard (if ASK)

Core engine​

Parser (sigmashake-gov/go/internal/rules)​

Parses the .rules DSL into an AST of Rule objects. Features:

  • Line-by-line parsing with error recovery
  • Condition group splitting (AND/OR logic)
  • Validation of all fields, operators, and patterns
  • Support for input.<key> generic field syntax

Evaluator (sigmashake-gov/go/internal/goengine)​

The evaluation algorithm:

  1. Sort rules by priority (descending — higher first)
  2. Filter to enabled rules only
  3. For each rule in priority order:
    • Check target matches tool capability
    • Check condition groups (OR between groups, AND within)
    • Short-circuit on first match
  4. Default to allow if no rule matches

Key properties:

  • Deterministic — Same input always produces same output
  • Low latency — design target under 2 ms per evaluation; the only published measurement is the 2026-06-10 sigmashake-bench daemon-socket run (ssg 0.29.156, n=500): p50 0.39 ms, p99 1.91 ms
  • Fail-secure regex — Invalid regex patterns match (trigger the rule)
  • Fail-secure licensing & database — If the license.jwt is invalid, or if the underlying SQLite database becomes corrupted/inaccessible, the engine immediately halts all tool calls with a block decision to prevent governance bypasses.

Database (sigmashake-gov/go/internal/db)​

SQLite storage for persistent state:

  • rules table — Serialized rule definitions
  • audit_log table — Evaluation history (rotated: 50,000-row soft cap that never deletes rows newer than 24 hours, 500,000-row hard ceiling)
  • pending_approvals table — ASK decisions awaiting human review

Indexes on timestamp, decision, tool for fast queries.

Adapters (sigmashake-gov/go/internal/cli)​

Client adapters translate between different AI agent formats and SigmaShake's internal tool-call type. Each host has its own install code (init_<host>.go) and, where the host has a hook protocol, its own hook code (hook_<host>.go). Hosts with adapter code include Claude Code, Cursor, Copilot, Codex, Antigravity, Pi, OpenCode, Aider, Grok and Replit. Run ssg init --list to see the adapters that your build installs.

Note 2026-10-13: an earlier version of this page described the legacy TypeScript tree (src/engine/*.ts) and its ClaudeCodeAdapter, CodexAdapter, PiAdapter and GenericAdapter classes. The shipped ssg CLI and daemon are Go.

Capability taxonomy​

Tools are classified into 6 capability categories:

CapabilityTool examples
executeBash, shell, terminal, run
readRead, cat, head, view
writeWrite, Edit, create, save
searchGlob, Grep, find, rg
agentAgent, spawn, delegate
networkWebFetch, WebSearch, curl

Rule targets map to capabilities: DENY execution blocks all tools with execute capability.

Data flow​

Standard evaluation​

stdin JSON → parse ToolCall → load rules → evaluate → audit log → stdout JSON

Each ssg eval is a separate process. The daemon reloads rules when they change: it polls the rules directories about every 2 seconds and, on Linux, watches the project rules directory. The reload does not run on every evaluation.

ASK decision flow​

Decision = "ask"
→ Health probe of the dashboard (skip the wait if no live approver)
→ POST /api/pending (creates approval)
→ Long-poll GET /api/pending/{id}/wait?timeout=<ms>
→ User approves/denies in dashboard
→ Long-poll returns "decided" → hook exit 0 (allow) or exit 2 (deny)

Timeout: 20 seconds by default, 45 seconds at most (SSG_ASK_DASHBOARD_TIMEOUT_MS overrides the default, clamped to the 45-second ceiling). If the dashboard is down, has no live approver, or gives no answer in time, the hook returns the ASK decision to the host harness, and the harness applies its own ASK behavior. The wait never turns into an allow.

The Claude Code hook (ssg hook eval) sends no terminal bell and does not poll at a fixed interval. A terminal bell and an inline Allow? [y/N] prompt belong to the separate ssg eval terminal flow only (2026-10-13 note: an earlier version of this diagram showed a bell and 500 ms polling for the hook).

Safety mechanisms​

MechanismProtection
Regex length limit (500 chars)ReDoS prevention
Nested quantifier detectionReDoS prevention
Glob/regex caching (LRU, 1000)Performance
Loop guard (engine: 5 identical calls; ssg eval: 3)Infinite loop prevention
Audit input truncation (8,192 bytes, with a length and SHA-256 marker)Audit log size control. The engine does not truncate. The audit writer does (auditInputMaxBytes); the marker holds the original length and a short SHA-256 fingerprint.
Audit rotation (50K-row soft cap with a 24 h floor, 500K-row hard ceiling)SQLite growth control
Parameterized SQL onlyInjection prevention

Component diagram​