Policy & Governance

Configure the Formael policy engine - four orthogonal axes, capability slots, posture-driven defaults, multi-currency action-value ledgers, simulation, and immutable versioning.

Documentation

Policy & Governance

The policy engine is the governance kernel of Formael. Every intent passes through it before any external action is taken - no exceptions, no bypass paths. Each verdict is computed once, atomically, and pinned to the immutable rule versions that produced it.

There are exactly three legal outcomes:

VerdictMeaning
APPROVEDPass the intent to execution
DENIEDReject and record per-axis reasoning
PENDING_APPROVALPause and route to a human approver

The four axes - four orthogonal questions

The four axes are not four buckets of similar conditions. They are four different questions with different inputs and different stakeholders. The verdict is the conjunction of the four - every axis must pass for execution to proceed, and no axis can compensate for another.

AxisQuestionOwns
IdentityWho, in what context, may invoke this?Time-of-day, environment fencing, cool-downs, agent groups, credential context
SemanticWhat does this intent mean - and is that allowed?Slot-based content checks: value, counterparty, content, classification, volume
FiscalCan the organization (and this agent) afford this?Two separate ledgers: platform spend (what Formael bills) and action value (what the agent moves)
RiskIf this goes wrong, how bad is it?Intrinsic risk profile, org thresholds, per-capability HITL pins

Evaluation is short-circuit, cheapest-first:

Identity → Semantic → Fiscal → Risk

A fast Identity denial skips the remaining axes.


Capability slots - the governance contract

Policy rules are written against semantic slots, not raw parameter field paths. A slot is a typed role that a parameter plays in governance - the same slot exists across many capabilities, so one rule applies portably wherever the slot is declared.

SlotMeaningExample fields
monetary_valueThe financial magnitude of the actioninvoice total, refund amount, wire principal
counterpartyThe external party the action affectscustomer, vendor, beneficiary, recipient
principalThe internal subject the action is about (not the agent)employee being deprovisioned, user being granted a role
contentFree-text content the action transmitsmessage body, email body, ticket description
destinationWhere the action deliversSlack channel, email address, webhook URL
classificationDiscrete labels that change riskpriority=P1, role=OWNER, severity=critical
volumeA count that scales blast radiusline items, accounts affected, recipients

Each capability declares which of its parameters populate which slots. Once a capability emits monetary_value, a rule like "require approval when monetary value exceeds $10,000" applies to it - without rewriting field paths. The same rule covers finance.create.invoice, support.issue.refund, and contracting.create.contract identically.

See Capability Catalog & Definition Packs for how slots are declared on a capability.


Identity axis

Question: Who, in what context, may invoke this?

Per-agent grants - which capabilities is this agent allowed to call at all - belong on Agent Scope, not on policies. See Agent Authentication. The Identity axis handles cross-cutting contextual rules that apply across agents or change with runtime context.

Rule kindWhat it asksExample
time_windowIs this within an allowed time-of-day / day-of-week window?No identity.deprovision between 22:00 and 06:00
environment_fenceDoes the agent's environment match?Agents tagged staging may not call finance.*
cooldownIs the agent inside a minimum interval since its last call?At most one finance.create.invoice per 60 seconds per agent
agent_group_restrictionIs the agent in a permitted group?Agents tagged experimental cannot call monetarySensitive=true capabilities
credential_context_requiredDoes the credential context (JWT claims) satisfy a requirement?Require device_trust=verified for capabilities flagged requiresHitlDefault
{
  "axis": "identity",
  "kind": "time_window",
  "condition": {
    "daysOfWeek": ["MON", "TUE", "WED", "THU", "FRI"],
    "hours": "09:00-18:00",
    "timezone": "Europe/London",
    "applyTo": { "capabilityFlags": ["monetarySensitive"] }
  },
  "action": "deny",
  "description": "Block monetary actions outside business hours"
}

Agent groups are configured via Agent.tags in Agents → Scope, and referenced by agent_group_restriction rules in policy.


Semantic axis

Question: What does this intent mean, and does it comply with your rules?

Semantic rules operate on slots, not parameter paths. The vocabulary is small and stable:

ConditionReads slotExample
value_abovemonetary_valueRefund > $500
value_currency_inmonetary_valueCurrency must be USD or EUR
counterparty_not_in_allowlistcounterpartyBeneficiary not in approved vendor list
content_matchescontentMessage contains an SSN regex
destination_externaldestinationSlack channel is not internal
classification_isclassificationPriority = P1, Role = OWNER
volume_abovevolumeLine items > 100
{
  "axis": "semantic",
  "kind": "value_above",
  "slot": "monetary_value",
  "threshold": { "amount": 10000, "currency": "USD" },
  "action": "require_approval",
  "description": "Require approval for monetary actions above $10,000"
}

Because the rule targets a slot, it applies to every capability that emits monetary_value - no per-capability rewrite required.

The reasoning trace

IntentEnvelope.context.reasoning - the agent's natural-language explanation of why it wants to act - is captured and stored as evidence. It is never gating. A policy verdict cannot fire solely on the content of the reasoning trace, because the trace is non-deterministic. Reasoning feeds audit and AI suggestion drafting only; the policy engine ignores it during evaluation.


Fiscal axis - two ledgers, one axis

The Fiscal axis answers "can the organization afford this?" - but "afford" has two unrelated meanings, and Formael keeps them separate.

Platform spend - what Formael bills your organization

  • Denomination: USD, always.
  • Inputs: the per-IEC platform fee (and AI inference cost when AI features are on).
  • Stakeholder: the CFO doing FinOps on Formael itself.
  • Configured at: Settings → Budgets → Platform Spend.

Rules cap your monthly/weekly/daily Formael bill: alert at 80% utilization, deny when the org-daily Formael budget is exhausted, etc.

Action value - what your agents move externally

  • Denomination: multi-currency. The amount is read from the monetary_value slot in its native currency. Each currency is enforced independently - there is no FX conversion at decision time.
  • Inputs: the monetary_value slot of the inbound intent, summed into the relevant action-value ledger row (org-wide, per-agent, per-domain, per-period).
  • Stakeholder: AP/AR, compliance, fraud, finance ops - not Formael billing.
  • Configured at: Settings → Budgets → Action Value. Off by default for new organizations; turn it on when you need it.
{
  "axis": "fiscal",
  "kind": "action_value_budget",
  "scope": { "domain": "finance", "agentId": null },
  "period": "daily",
  "limit": { "amount": 100000, "currency": "EUR" },
  "action": "deny",
  "description": "Cap daily AP outflow at €100k across all agents"
}

A $1,000,000 wire transfer has a platform-spend cost of roughly $0.002 (one IEC) and an action value of $1,000,000. These are different categories of harm, paid for by different budgets, owned by different people, and gated by different rules - never conflated.

Remaining budget is returned in every fiscal denial:

{
  "denial": {
    "axisResults": {
      "fiscal": {
        "verdict": "DENIED",
        "ledger": "action_value",
        "scope": "domain=finance",
        "period": "daily",
        "currency": "EUR",
        "currentSpend": 97250,
        "limit": 100000,
        "projected": 102100
      }
    }
  }
}

Multi-currency rule. Per-currency enforcement only. An intent denominated in EUR is never converted to USD to check a USD ledger - if no matching ledger row exists, the axis passes. FX rollup is a dashboard feature; it never affects a policy decision.

Non-monetary quotas (e.g. "tickets per hour") are not Fiscal. They belong on Identity as cooldown/rate-shaping rules.


Risk axis

Question: What is the blast radius if this action goes wrong?

Risk is composed from three independent inputs:

InputSource
Intrinsic riskThe capability's riskProfile (reversibility, visibility) - installed from the pack, adjustable in your registry
Org thresholdsA single risk_threshold rule per org: require approval above X, deny above Y
Per-capability HITL pinA field on your organization's capability override: INHERIT_PACK / PIN_ON / PIN_OFF

Composite formula:

risk_score = (1 − reversibility) × 0.40 + visibility × 0.35 + precedent × 0.25

Precedent quietly reflects platform learning: an agent that has executed this capability many times successfully is intrinsically less risky than one trying it for the first time. The first attempt scores 1.0; prior success drives the term toward 0.2; prior failure pushes it back up.

Evaluation order at runtime

  1. Did the org pin HITL on this capability? → PASS + requiresApproval=true. Done.
  2. Otherwise, compute the score from the capability's risk profile and this agent's precedent.
  3. Apply the org's thresholds (or the platform defaults if unset).

Tier defaults

TierrequireApprovalAbovedenyAbove
Starter0.5-
Business0.7-
Enterprise0.9 (configurable)configurable

Risk-axis rules are threshold-only. There is no allow/deny action selector on a Risk-axis rule - a threshold rule can only force approval or denial. Per-capability HITL pins are configured on the capability itself in Capabilities → [capability] → Risk Profile, not as a policy rule.


Risk Posture - opinionated defaults

Onboarding asks each organization to pick one Risk Posture. The posture applies a fixed set of templates and threshold defaults so a new org has working governance the moment a pack is installed.

PosturePosture templates appliedrequireApprovalAbove
Conservative7tighter than tier default
Balanced3tier default
Permissive0tier default

Most SMEs never need to leave Balanced. You can override any individual template or threshold after onboarding - the posture is a starting point, not a lock-in.


Policy templates

Templates are pre-authored bundles named in compliance English, mapped to slot-based rules so they work portably across packs.

TemplateAxisWhat it configures
finance-high-value-approvalSemanticRequire approval when monetary_value.amount > $10,000
ap-outflow-daily-capFiscal (action value)Cap daily AP outflow per organization
contracting-sign-approvalRisk (HITL pin)Always require approval before contracting.sign.*
identity-deprovision-approvalRisk (HITL pin)Always require approval before deprovisioning accounts
identity-privileged-hitlSemantic + RiskRequire approval when granting admin roles (classification.role=OWNER)
support-refund-thresholdSemanticRequire approval for refunds above $500 (via monetary_value)
support-pii-blockSemanticDeny outbound content matching PII patterns (SSN, PAN, etc.)
messaging-external-recipientsSemanticRequire approval when destination.address is external
after-hours-monetary-blockIdentityBlock monetary actions outside business hours (time_window)
experimental-agent-guardrailsIdentityAgents tagged experimental cannot call monetary-sensitive capabilities

To apply a template, navigate to Policies → Apply Template. Generated rules can be reviewed and edited before activation.


Policy simulation - replay against your own history

Before activating any rule, simulate it against your organization's last 30 days of IEC history. Simulation runs the full four-axis evaluation deterministically; it writes no audit record and executes no action.

Policies → Simulate returns:

  • The number of IECs the rule would have matched
  • Per-IEC verdict deltas - actual verdict vs counterfactual verdict
  • A false-positive estimate - successful transactions that would have been blocked
  • The HITL load delta per approval group
  • Aggregate change in transaction value for blocked IECs
  • The five most-affected agents

Simulation is the single best way to evaluate a policy change before it ships. Use it on every non-trivial rule edit.


Policy versioning

Every rule update creates an immutable PolicyRuleVersion snapshot before taking effect. The live engine reads the active version; the historical chain stays intact forever. Every verdict in your audit trail references the exact policyRuleVersionId that produced it - enabling full point-in-time policy auditability.

Navigate to Policies → [rule] → Version History to browse snapshots, diff versions, and revert.


Human-in-the-loop approval

When any axis returns PASS + requiresApproval=true, the IEC enters PENDING_APPROVAL. The approver sees the full context: the agent's submitted intent, the agent's reasoning trace, the slot projections, the risk score breakdown, and the proposed action in plain language.

ActionOutcome
ApproveExecution proceeds with the original parameters
DenyIEC closes with a denied outcome; agent is notified

Approval requests expire after a configurable window (default: 24 hours). Expired requests close as denied.


Approval groups

Approval groups route HITL requests to the right team. Each domain is assigned an approval group - when an intent from that domain is deferred, only that group is notified.

DomainExample group
financeFinance Approvers
contractingLegal
identityIT Operations

Approval groups are managed in Settings → Approval Groups; domain assignments live in the Domains section of the console.


Default behavior when no rules match

AxisIf no rules match
IdentityAllow (agent scope already gated capability access)
SemanticAllow
FiscalAllow (no budget configured → no cap to exceed)
RiskEvaluated against your org thresholds; HITL pin still applies

To switch any axis to default-deny, configure the explicit catch-all rule on that axis. Per-agent capability access is not a policy concern - manage it on Agent Scope.


Policy verdicts in the audit trail

Every policy evaluation is recorded permanently as a PolicyVerdict row, immutable and append-only:

  • The four per-axis verdicts (PASS / FAIL / PASS+requiresApproval)
  • The specific policyRuleVersionIds that contributed
  • The computed risk score and its inputs (reversibility, visibility, precedent)
  • The slot projections used in evaluation
  • The evaluation timestamp

This record is the source of truth for compliance reporting, point-in-time replay, and post-hoc analysis.