Skip to content
Press / to search

Decision Catalog

Typed Decision Specs — the catalog layer between model reasoning and governed business action.

Implementation GuideLast reviewed: Edit on GitHub
At a glance

The Decision Catalog is the registry of typed DecisionSpec entries that the Critic and the Policy Engine consume. Every governed action in ContextOS resolves to a DecisionSpec and produces a DecisionRecord.

Definition

A versioned catalog of typed decision contracts. Each DecisionSpec declares decision_key, version, required_evidence, allowed_outcomes, the required v1 approval_mode compatibility ceiling, and optional eligibility/input/output contracts. A conforming implementation produces a DecisionRecord carrying the accepted outcome and its evidence, controls, policy decisions, approvals, lineage, budget, and trace.

Why it exists

Free-form explanations alone do not identify a governed outcome or its acceptance criteria. Typed decisions let the runtime validate a closed outcome set, compare results, and retain evidence for replay and audit. Explanatory text can accompany that record; it does not substitute for the typed outcome or authorize an effect.

How it works

  1. Author a DecisionSpec for a kind of decision (e.g., support.refund.execute).
  2. Bind policy rules and tool capabilities to the decision_key via decision_binding.
  3. Compile — the pack supplies decision_layer.decision_specs[]; the ContextPackCompiler derives the applicable evidence gates and runtime controls. decision_layer is a pack field, not an additional CompiledContext field.
  4. Verify — at the decision checkpoint, the Critic checks required_evidence is resolved and the chosen outcome ∈ allowed_outcomes.
  5. Record — the runtime emits a DecisionRecord against the spec and persists it.

Evidence sufficiency and an allowed outcome establish decision eligibility. Before an external effect, the Gateway separately checks the exact ActionBinding and execution contract, current authority and policy, any required approval, boundary/data readiness, and reserved budget. A DECIDED record does not prove that a payment occurred; retain the operation’s verified effect observation and postcondition evidence.

DecisionSpec

{
  "decision_key": "support.refund.execute",
  "version": "1.0.0",
  "owner_role": "support_ops",
  "required_evidence": ["order_lookup", "policy.eval", "identity_verified"],
  "allowed_outcomes": ["approved", "denied", "escalated"],
  "approval_mode": "destructive",
  "inputs_schema_ref": "schema://decision.support.refund.execute.inputs.v1",
  "outputs_schema_ref": "schema://decision.support.refund.execute.outputs.v1",
  "eligibility_rules": {
    "and": [
      { "==": [{ "var": "intent" }, "support.refund"] },
      { ">": [{ "var": "request.context.refund_amount" }, 0] }
    ]
  },
  "decision_right": "execute",
  "challenge_required": false
}

Field semantics

FieldMeaning
decision_keystable identifier the policy and adapter layers bind to
required_evidencerequirement names resolved by admitted evidence’s satisfies[] entries or explicit structured request context; a name is not itself an immutable evidence artifact
allowed_outcomesthe closed set of legal outcomes the runtime may emit
approval_moderequired v1 compatibility ceiling; native capability and call risk remains multidimensional, and propose/approve/execute runs only when policy emits an approval obligation
eligibility_rulesJsonLogic predicate that gates whether this spec applies to a given Run Context
decision_rightone of propose, recommend, execute, escalate — what the runtime is allowed to do under this spec
owner_roleoptional in the base type; assign an accountable governance owner under the deployment’s change-control policy

DecisionRecord

The runtime emits one record per decision checkpoint. The dedicated guide is Decision Record; the compact envelope appears in API Contracts.

Base-schema required fields: record_id, decision_key, decision_version, timestamp, status, actor, evidence_refs, policy_decisions[], approvals[], controls_active, budget_usage, lineage, and trace_id. The active DecisionSpec can additionally require typed outputs and other domain fields.

Decision binding (in policy rules)

A policy rule binds to a decision via decision_binding:

{
  "rule_id": "R_HIGH_VALUE_REQUIRES_APPROVAL",
  "applies_to": { "intent": "support.refund" },
  "if": { "and": [
    { "==": [{ "var": "user.role" }, "support_agent"] },
    { ">": [{ "var": "request.context.refund_amount" }, 3000] }
  ]},
  "then": {
    "allow": true,
    "approval_mode": "destructive",
    "requires_approval_gate": "GATE_FINANCE_APPROVAL"
  },
  "decision_binding": "support.refund.execute"
}

Use the exact registered decision_key. The decision. prefix inside this page’s illustrative schema URIs is not part of that key. An applicable policy-expression error stops compilation with a structured ContextCompileError; it must not silently select another outcome or authorize execution.

Status values

DECIDED, DEFERRED, REJECTED, ESCALATED, IN_FLIGHT, CLOSED. The Critic chooses the status based on its scoring verdict and the gate state.

Interfaces

Inputs

  • Run Context (with claims, role, tenant)
  • Compiled evidence_manifest
  • Tool transcripts that produced the evidence
  • Active policy decisions

Outputs

  • DecisionRecord with all required fields populated
  • Memory write proposals tagged by decision_key

Failure modes

  • Spec missing the required required_evidence field — reject the malformed spec. An intentionally empty list is structurally legal; the workflow’s admission and acceptance policy must determine whether it is sufficient.
  • Outcome chosen outside allowed_outcomes — runtime rejects.
  • The DecisionSpec v1 ceiling is lower than the capability’s conservative projection — deny or escalate through an explicit policy path; never silently lower the capability projection.
  • A governed capability lacks native ActionRisk under an active action_risk_policy — fail closed.
  • Decision Record emitted without policy_decisions[] — audit gap; release-gate failure.
  • Spec versions drift across environments.

Operational concerns

  • Spec versioning per environment; promotion is deliberate.
  • Schema-ref availability is in the critical path.
  • Append-only persistence of decision records for replay and audit.
  • Owner-role assignment for every spec; orphan specs flagged.
  • Evaluator scoring per spec, not just per intent.

Evaluation metrics

  • Decision-correctness on golden set per decision_key.
  • Outcome distribution drift across releases.
  • Evidence-resolution rate for decisions admitted to commit (target: 100%); separately measure blocked and unresolved cases.
  • Native-risk policy mismatch rate and v1 projection mismatch rate.
  • Mean time from challenge to decision under challenge_required.

Example

Refund-eligibility decision spec and one resulting record:

{
  "decision_spec": {
    "decision_key": "support.refund.eligibility",
    "version": "1.2.0",
    "required_evidence": ["order_lookup", "policy.eval"],
    "allowed_outcomes": ["eligible", "ineligible"],
    "approval_mode": "read_only",
    "decision_right": "recommend"
  },
  "decision_record": {
    "record_id": "dr_2026_05_04_a17",
    "decision_key": "support.refund.eligibility",
    "decision_version": "1.2.0",
    "timestamp": "2026-05-04T09:31:42Z",
    "status": "DECIDED",
    "actor": { "type": "AGENT", "id": "agt_support" },
    "outputs": { "outcome": "eligible", "reason": "within_window_and_idv_passed" },
    "evidence_refs": ["tool:orders.lookup:tc_117", "tool:policy.eval:tc_119"],
    "policy_decisions": [{ "policy_decision_id": "pol_9900", "rule_ids": ["R_REFUND_REQUIRES_IDV"] }],
    "approvals": [],
    "controls_active": { "must_refuse": [], "must_escalate": [], "approval_gates_active": [], "redaction_rules_active": [] },
    "budget_usage": { "tokens": 1280, "tool_calls": 2, "cost_usd_cents": 0.22, "wall_clock_ms": 640 },
    "lineage": { "pack_version": "ctxpack.support@5.2.0", "decision_spec": "support.refund.eligibility@1.2.0" },
    "trace_id": "4bf92f3577b34da6a3ce929d0e0e4736"
  }
}

Common misconceptions

  • A decision is not a prediction. It is a typed, validated, evidence-bound outcome from allowed_outcomes.
  • A DecisionRecord is not a log line. It is the audit and replay artifact.
  • Decision binding is not optional for governed actions. Without it, policy and the spec drift apart.