Policy Engine

Define YAML rules that gate merges based on behavioral signals. Policies are version-controlled alongside your code.

Policy file structure

spooled-policy.yml
name: "My Policy"
enabled: true
block_merges: true

rules:
  - name: "Block new tools"
    description: "Prevent unauthorized tool additions"
    severity: high
    fail_if:
      new_side_effects: true

  - name: "Warn on latency"
    severity: medium
    warn_if:
      latency_spike:
        threshold_percent: 50.0

Top-level fields

FieldTypeDefaultDescription
namestring""Policy name
enabledbooleantrueEnable/disable the entire policy
block_mergesbooleanfalseExit code 1 when violations exist
ruleslist[]Array of rule objects
profilesdictNonePer-agent policy overrides

Rule structure

Each rule has a fail_if block (violations that block), a warn_if block (warnings only), or both.

FieldTypeDescription
namestringRule identifier
descriptionstringHuman-readable description
severity"high" | "medium" | "low"Default: "medium"
fail_ifdictConditions that cause rule to fail
warn_ifdictConditions that cause rule to warn

Supported conditions

Signal-based conditions

fail_if:
  new_side_effects: true
  latency_spike:
    threshold_percent: 50.0
  retry_explosion:
    threshold: 5
  error_increase:
    threshold: 1
  new_tools: true
  tool_usage_change:
    threshold_percent: 50.0
  token_usage_spike:
    threshold_percent: 50.0
  component_latency_drift:
    threshold_percent: 100.0
  tool_overuse:
    threshold_percent: 50.0
  retrieval_regression:
    threshold: 0.2

Content-blind conditions (Pro)

fail_if:
  output_schema_drift:
    fail_on_removed: true
    fail_on_added: false

Behavioral conditions

fail_if:
  # Block when behavioral fingerprint doesn't match
  on_variant: true
  # Or with minimum similarity threshold
  on_variant:
    min_similarity: 0.75

  # Require specific tools to be present
  required_tools:
    tools: ["check_pii", "detect_hallucination"]
    message: "Compliance guardrails must be present"

Per-agent profiles

Override policy rules for specific agents:

spooled-policy.yml
profiles:
  default:
    block_merges: true
    rules:
      - name: "Standard checks"
        fail_if:
          new_side_effects: true

  payment_agent:
    block_merges: true
    rules:
      - name: "Strict: low latency tolerance"
        fail_if:
          latency_spike:
            threshold_percent: 25.0
          new_side_effects: true

When agent_id matches a profile key, that profile is used. Otherwise, the default profile applies. If no profiles section exists, top-level rules apply to all agents.

CLI commands

spooled policy init      # Create default policy file
spooled policy validate  # Check policy YAML syntax
spooled policy show      # Display current configuration

Policy templates

Three built-in templates:

TemplateDescription
strictBlock on any behavioral change, variant, or new tool
moderateBlock on high-severity signals, warn on medium
permissiveWarn only, never block

Evaluation flow

When spooled ci run or spooled ci compare is called with a policy:

Trace  Fingerprint  Compare to baseline  Status
     Detect signals  Evaluate policy rules
     Result: { passed, violations, warnings, should_block }

The policy engine returns:

FieldDescription
passedtrue if no violations
should_blockblock_merges AND violations exist
violationsList of fail_if violations from all rules
warningsList of warn_if warnings from all rules
violation_countTotal violations
warning_countTotal warnings