← Docs

Writing policies

A policy is the unit of Computable Governance — a formula (temporal logic over the finite trace, plus structural predicates) checked over a trace, which ponens evaluates to pass / fail with an exit code. Policies live in the public gallery or in your own local source — this page covers the formula language and how to write, add, and check your own.

The policy object

A policy is a JSON file named <id>.json:

{
  "id": "tests_before_commit",          // snake_case, must match the filename
  "name": "Tests Before Commit",
  "category": "workflow",               // see categories below
  "severity": "error",                  // error | warning | info
  "description": "Every commit must be preceded by a successful test run.",
  "formula": "G(GitCommit → P(RunTests ∧ completed))",
  "language_level": "pure_temporal",    // pure_temporal | scoped_temporal | structural
  "rationale": "Prevents untested code from entering the repository.",
  "tags": ["ci", "testing", "git"],
  "domain": "general",
  "examples": {
    "passes": "ReadFile → RunTests(pass) → EditFile → RunTests(pass) → GitCommit",
    "fails":  "ReadFile → EditFile → GitCommit (no test run before commit)"
  }
}

The formula language

Formulas are written over the trace's ordered actions, its artifacts, and its residual surface. Operators may be written with unicode or ASCII (/->, //\, /\/, ¬/!, /!=, /EMPTY).

Atoms (what holds at an action)

Temporal operators

OperatorMeaning
G φglobally — φ holds at every action
F φfinally — φ holds at some action
P φpreviously — φ held at some earlier action
H φhistorically — φ held at every earlier action
X φnext — φ holds at the immediately following action
φ U ψuntil — ψ holds eventually, and φ holds until then
φ S ψsince — ψ held in the past, and φ has held since

Scoped operators (lineage-aware)

OperatorMeaning
P_target φsome earlier action sharing the same target satisfied φ
P_chain φsome earlier action in the dependency chain satisfied φ

Quantifying over the residual surface

Policies can govern a trace's declared negative space with / over residuals, with field access on the bound variable:

¬∃ r ∈ residuals . r.severity = Critical ∧ r.status = Open
∀ r ∈ residuals . r.kind = Unverified → r.suggested_check ≠ ∅

Fields: r.kind, r.severity, r.status, r.target, r.suggested_check, r.related_artifact_ids. Severity is ordered (info < low < medium < high < critical), so r.severity ≥ High works.

Worked examples

# pure temporal — tests before commit
G(GitCommit → P(RunTests ∧ completed))

# scoped — research before edit
G(EditFile → P_target(ReadFile ∨ AnalyzeCode ∨ SearchCode))

# reasoning required for high-stakes edits
G(EditFile ∧ high_stakes_path → P_chain(VerificationResult ∨ Decomposition))

# residual surface — no open critical gap at approval
¬∃ r ∈ residuals . r.severity = Critical ∧ r.status = Open

Write your own & use it

  1. Create .ponens/policies/my_rule.json using the shape above.
  2. Register a local source:
    ponens sources add team --type local --path .ponens/policies
    (or add a [[source]] block to .ponens/sources.toml).
  3. Find it, add it to a trace, and check:
    ponens policies search my_rule          # shows source = team
    ponens policies add team/my_rule --into ./trace.json
    ponens trace check ./trace.json

The materialized policy carries its provenance (source: team) into the trace, so a reviewer sees which source governed it.

Validate as you go

ponens trace check compiles each formula and reports syntax/semantic errors before evaluating. Unrecognized operators or unbalanced parentheses are caught there. Use ponens trace validate <file> to check the trace's own structure.

Reference

Categories: auditability, communication, conformance, reasoning, safety, security, structural, workflow.   Severities: error, warning, info.

Language levels: pure_temporal (only temporal operators), scoped_temporal (uses P_target/P_chain), structural (quantifiers / first-order, incl. residual policies). The gallery records whether the reference compiler can evaluate each formula. See the Policy Specification for the full grammar.