Decisions as a Service
Sign Up Now →Sign Up Now

Playbooks

A playbook is the source of a decision pack: a YAML file that names the pack, lists its actions, declares how facts are extracted and states the rules. This page explains each section, using the built-in example pack (data protection, compliance.regulatory_pii_guard.v1) as the worked example.

About the example

This page uses the built-in data-protection pack so you can read a complete, working playbook without writing one first. The same sections describe any decision pack: eligibility, limits, routing and so on. See Core concepts.

Adaptive strategy integration is planned

This page describes compiled decision packs. The proposed adaptive strategy loop does not add supported fields to this schema or make embedded evaluation read outcome memory. Hosted playbooks use a separate interface.

The whole file at a glance#

pack_id: compliance.regulatory_pii_guard.v1
version: 1.0.0
name: Regulatory PII and Sensitive Data Guard
kind: compliance
description: "Fail-closed PII inspection for GLBA, PCI-DSS, HIPAA and GDPR/CCPA."

budget:
  max_latency_ms: 1.0
  max_tokens: 0

actions:
  - permit_clean_payload
  - block_glba_ssn_leakage
  - block_pci_dss_pan_leakage
  - block_hipaa_phi_leakage
  - redact_and_permit_contact_pii

codons:
  - code: PII_SSN_EXTRACT
    kind: codon
    codon_type: extract_pattern
    trigger: on_input
    params:
      pattern: '\b(?!000|666|9\d{2})\d{3}-(?!00)\d{2}-(?!0000)\d{4}\b'
    binds_to: has_ssn
    matches_field: ssn_matches
    remedy_template: "[REDACTED_SSN]"
  # ... card (with checksum: luhn), health ID, email, phone, IP

hard_rules:
  - id: RULE-GLBA-SSN-BLOCK
    condition: state.has_ssn == True
    action: block_glba_ssn_leakage
    description: "Statutory violation: Social Security Number (GLBA / FCRA) detected"
    severity: fatal
  # ... PCI-DSS, HIPAA (fatal), contact details (warning)

default_action: permit_clean_payload

Quote descriptions that contain a colon

A value such as Statutory violation: ... must be quoted, or YAML reads the second colon as a new key and the file fails to parse.

Identity#

KeyPurpose
pack_idRequired. Stable, dotted, ends in a major version: <domain>.<name>.v<N>. Licenses grant packs by this ID, so changing it is a breaking change.
versionSemantic version of this revision. Bump it on every change you ship.
name, kind, descriptionHuman-facing metadata.

Budget#

budget.max_latency_ms and budget.max_tokens record the pack's intended envelope: under a millisecond, zero model tokens. A compiled pack enforces them (changed in 0.3.0): max_latency_ms is checked on every decision, a slower decision raises DecisionBudgetExceededError with its result withheld, and any other budget key is rejected at compile time. The built-in example pack does not check its budget. Set max_latency_ms with room for your slowest host.

Actions and the default#

actions is the closed set of outcomes the pack may return. default_action names the outcome when no rule fires; a compiled pack always returns permit_clean_payload then. A compiled pack enforces both (changed in 0.3.0): actions, when present, must list every action the pack can return, including the five of the built-in checks, and default_action may only be permit_clean_payload. See Playbook schema. Name actions so callers can route on the prefix, as the example pack does:

  • permit_… the payload may proceed unchanged,
  • redact_… the payload may proceed as remedy.clean_text,
  • block_… the payload must stop.

Codons#

Each codon extracts one typed fact from the input into state. The keys that matter:

KeyMeaning
codeUnique codon ID, upper snake case.
codon_typeextract_pattern for regular-expression extraction. Also defined: checksum_validator, range_filter, custom.
triggeron_input: run on every evaluation.
params.patternThe regular expression. params.flags takes MULTILINE, IGNORECASE, DOTALL, ASCII.
checksumluhn discards matches that fail the Luhn check.
binds_toThe boolean state field set when anything matches.
matches_fieldThe state field that holds the matches.
remedy_templateReplacement text for each match in remedy.clean_text.

Rules#

A rule pairs a condition over state with an action and a severity (fatal, warning or info). Rules are evaluated in file order; put the most severe first.

What runs in 0.3.1#

The playbook format is ahead of the pack compiler. Know which parts execute. The compiler rejects declarations a compiled pack would not execute, with UnsupportedPackDeclarationError, instead of sealing them silently:

SectionBuilt-in example packPack you compile
The example pack's built-in codons and rulesRunRun
rules entries with type: regex or type: luhn_checksumn/aRun on every payload, next to the built-in checks
Your own codonsn/aRejected at compile time; executing them is Planned
Your own hard_rulesn/aRejected at compile time; executing them is Planned
budget enforcementNot checkedmax_latency_ms checked on every decision (changed in 0.3.0)

To add your own detection today, declare regex rules:

pack_id: acme.project_codes.v1
version: 1.0.0
actions: [permit_clean_payload, block_project_code, block_glba_ssn_leakage,
          block_pci_dss_pan_leakage, block_hipaa_phi_leakage, redact_and_permit_contact_pii]
rules:
  - id: project_code
    type: regex
    pattern: '\bPROJ-[A-Z]+-\d[A-Z]\b'
    action: block
default_action: permit_clean_payload

How regex rules behave in 0.3.1:

  • Every rule and every built-in check runs on every payload, and every match is reported in triggers. The first fatal match decides the action, with your rules checked before the built-in ones; with no fatal match, the first warning decides.
  • The returned action is block_<id> (here block_project_code) with severity FATAL for action: block, and redact_<id> with severity WARNING for action: redact. Name the rule id so that the result reads well, and list the same name under actions for reviewers.
  • A redact rule replaces each match with [REDACTED_<ID>], the rule ID in upper case. Overlapping matches merge into one redaction. When any block rule fires, remedy.clean_text is [BLOCKED: Prohibited Content], even if another rule redacted something (changed in 0.3.0: in 0.2.1 the blocked value could stay in clean_text). Still, never forward the text of a blocked result.
  • The whole match is reported and redacted, whether or not the pattern has capturing groups (changed in 0.3.0: 0.2.1 used the first group's text).

Compile it with your license and run it; see Packs and the custom rules tutorial. The full key list is in the playbook schema reference.

Writing good playbooks#

  • Anchor patterns with \b and test them against both true and near-miss inputs.
  • Prefer a checksum where the identifier has one; it removes most false positives.
  • Avoid nested quantifiers such as (a+)+. Patterns run on every payload with no timeout.
  • Keep a golden test set next to the playbook and run it in CI before compiling. See Testing policies.