Skip to Content
Task guidesTechnical: Policy Simulation

Policy Simulation

Technical reference. This page is for integrations, advanced configuration, or platform operations. For portal tasks, start with the user guide.

Policy simulation lets you evaluate how a policy bundle responds to a set of inputs before any flow executes. It is a dry-run: no workload runs, no evidence is written, and no obligations are enforced. The result is a decision matrix that tells you exactly which inputs would be allowed, denied, sent for approval, or allowed with obligations under the current rules.

How simulation works

The simulation endpoint accepts one or more scenario objects. Each scenario is a map of input fields matched against the policy bundle’s rule conditions. The engine evaluates every rule, selects the highest priority among the matched rules and the earliest-listed rule on ties (decision_basis.selection is first_match, highest_priority or default_deny), exactly as it does at runtime. A structurally malformed bundle simulates as deny with the reason malformed_policy_bundle and an empty matched_rules list, distinct from the no_matching_policy_rule no-match.

Default 3-lane matrix

When no custom scenarios are provided, the engine runs the built-in standard / guided / restricted matrix. These cover the three most common governance postures:

LaneTypical inputs
standardUnclassified content, low token count, no PII
guidedModerate sensitivity, user-provided content
restrictedPII detected, medical content, elevated token count

The matrix gives you an at-a-glance view of where a policy bundle draws its boundaries across the governance spectrum.

Simulate endpoint

POST /v1/policies/{id}/simulate

Request body:

{ "scenarios": [ { "name": "standard", "input": { "contains_pii": false, "token_count": 500, "category": "general" } }, { "name": "pii-detected", "input": { "contains_pii": true, "token_count": 800, "category": "general" } }, { "name": "medical-large", "input": { "contains_pii": false, "token_count": 12000, "category": "medical" } } ] }

Response shape:

{ "policy_id": "p1a2b3c4-0000-0000-0000-000000000001", "evaluated_at": "2026-04-11T10:00:00Z", "results": [ { "scenario_name": "standard", "outcome": "allow", "reason_code": "DEFAULT_ALLOW", "matched_rule_index": 3 }, { "scenario_name": "pii-detected", "outcome": "deny", "reason_code": "PII_NOT_ALLOWED", "matched_rule_index": 0 }, { "scenario_name": "medical-large", "outcome": "allow_with_obligations", "reason_code": "MEDICAL_CONTENT", "matched_rule_index": 2, "obligations": [{ "type": "capture_evidence" }, { "type": "require_human_review" }] } ] }

Omit the scenarios array to run the default 3-lane matrix using the engine’s built-in inputs.

Custom scenarios for edge cases

Add as many scenario objects as needed to probe edge cases specific to your workload. Useful patterns:

  • Test a boundary value (e.g., token_count: 10000 vs 10001) to confirm threshold rule placement.
  • Include a scenario that should hit every rule to verify priority and tie-break selection.
  • Name scenarios clearly — names appear in the portal matrix and in CI output.

Policy diff

Compare two policy bundles to understand what changed between versions before promoting to production.

POST /v1/policies/diff

Request body:

{ "base_policy_id": "p1a2b3c4-0000-0000-0000-000000000001", "head_policy_id": "p1a2b3c4-0000-0000-0000-000000000002" }

Response shape:

{ "added_rules": [ { "index": 2, "condition": "input.category == 'financial'", "outcome": "require_approval", "reason_code": "FINANCIAL_CONTENT" } ], "removed_rules": [], "changed_rules": [ { "index": 1, "field": "outcome", "base": "allow", "head": "allow_with_obligations" } ], "unchanged_rules": 2 }

Release policy simulation

Every release can be compared against its predecessor’s policy automatically.

GET /v1/releases/{id}/policy-simulation

This endpoint:

  1. Resolves the policy bundle bound to the target release.
  2. Resolves the policy bundle bound to the predecessor release (the most recent active or approved release in the same environment).
  3. Runs the default 3-lane simulation against both bundles.
  4. Returns the diff alongside both decision matrices.

Response shape:

{ "release_id": "r1a2b3c4-0000-0000-0000-000000000010", "predecessor_release_id": "r1a2b3c4-0000-0000-0000-000000000009", "base_simulation": { "results": [ /* ... */ ] }, "head_simulation": { "results": [ /* ... */ ] }, "policy_diff": { "added_rules": [], "removed_rules": [], "changed_rules": [ /* ... */ ] } }

If the release or its predecessor has no policy bundle bound, the corresponding simulation field is null.

Portal: Policy tab on release detail

The Policy tab on the release detail view shows:

  • A color-coded decision matrix for the current policy and the predecessor policy, side by side.
  • Outcome colors: green (allow), red (deny), amber (require_approval), blue (allow_with_obligations).
  • A rule diff panel that highlights added, removed, and changed rules between the two releases.
  • A “Run custom scenario” form for ad-hoc simulation without leaving the portal.

SDK

from orqestra_sdk import OrqestraClient async with OrqestraClient() as client: # Simulate a policy against custom scenarios result = await client.policy_simulation.simulate_policy( policy_id="p1a2b3c4-0000-0000-0000-000000000001", scenarios=[ {"name": "standard", "input": {"contains_pii": False, "token_count": 500}}, {"name": "pii-detected", "input": {"contains_pii": True, "token_count": 800}}, ], ) for r in result.results: print(r.scenario_name, r.outcome, r.reason_code) # Diff two policy bundles diff = await client.policy_simulation.diff_policies( base_policy_id="p1a2b3c4-0000-0000-0000-000000000001", head_policy_id="p1a2b3c4-0000-0000-0000-000000000002", ) print(diff.added_rules, diff.changed_rules)

Omit scenarios in simulate_policy() to use the default 3-lane matrix.

CLI

Simulate a policy

orqestractl policy simulate <policy-id>

With custom scenarios from a JSON file:

orqestractl policy simulate <policy-id> --scenarios scenarios.json

Output:

SCENARIO OUTCOME REASON CODE standard allow DEFAULT_ALLOW pii-detected deny PII_NOT_ALLOWED medical-large allow_with_obligations MEDICAL_CONTENT

Diff two policies

orqestractl policy diff <base-policy-id> <head-policy-id>

Release policy simulation

orqestractl release policy-simulation <release-id>

Outputs the side-by-side matrix and the rule diff in a tabular format. Add --json for machine-readable output suitable for CI pipelines.