Skip to main content

Architecture

SigmaShake is designed as a deterministic, zero-dependency rule engine that operates at the AI agent's tool-call boundary.

System overview

User/Agent → Tool Call → ssg eval → Engine → Decision → Audit Log

Dashboard (if ASK)

Core engine

Parser (src/engine/parser.ts)

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 (src/engine/evaluate.ts)

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
  • Sub-millisecond — Typically < 2ms per evaluation
  • Fail-secure — Invalid regex patterns match (trigger the rule)

Database (src/engine/db.ts)

SQLite storage for persistent state:

  • rules table — Serialized rule definitions
  • audit_log table — Evaluation history (auto-rotated at 50K rows)
  • pending_approvals table — ASK decisions awaiting human review

Indexes on timestamp, decision, tool for fast queries.

Adapters (src/engine/adapter.ts)

Client adapters translate between different AI agent formats and SigmaShake's internal ToolCall type.

Built-in adapters:

  • ClaudeCodeAdapter — Native Claude Code integration with hook installation
  • GenericAdapter — Universal JSON format fallback

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. Rules loaded fresh every time — hot reload with zero downtime.

ASK decision flow

Decision = "ask"
→ Terminal bell
→ POST /api/pending (creates approval)
→ Poll /api/pending/{id}/status (500ms interval)
→ User approves/denies in dashboard
→ Poll returns result → stdout JSON

Timeout: 60 seconds. If no response, defaults to deny.

Safety mechanisms

MechanismProtection
Regex length limit (500 chars)ReDoS prevention
Nested quantifier detectionReDoS prevention
Glob/regex caching (LRU, 1000)Performance
Loop guard (3 identical calls)Infinite loop prevention
Circuit breaker (5 consecutive denies)Agent lockout prevention
Input truncation (4KB)Audit log size control
Auto-rotation (50K rows)SQLite growth control
Parameterized SQL onlyInjection prevention

Component diagram

┌─────────────────────────────────────────────────────┐
│ sigmashake-gov │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │
│ │ Parser │──→│ Evaluator│──→│ Audit Logger │ │
│ └──────────┘ └──────────┘ └──────────────────┘ │
│ ↑ ↑ ↓ │
│ ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │
│ │ .rules │ │ Adapters │ │ SQLite DB │ │
│ │ files │ └──────────┘ └──────────────────┘ │
│ └──────────┘ ↓ │
│ ┌──────────────────┐ │
│ │ Dashboard UI │ │
│ │ (Hono + HTMX) │ │
│ └──────────────────┘ │
└─────────────────────────────────────────────────────┘

┌─────────────────┐ ┌─────────────────┐
│ sigmashake-mcp │ │ sigmashake-hub │
│ (CF Worker) │ │ (CF Worker) │
│ MCP over SSE │ │ Rules Registry │
│ KV storage │ │ D1 + KV │
└─────────────────┘ └─────────────────┘