Skip to content

Governance and security

Governance documentation

Policy syntax and lifecycle, risk evaluation and approval flows, plus how accountability is modelled when an AI system is the thing doing the work.

How a rule is written, versioned, evaluated and replayed, and how accountability is modelled when the thing doing the work is not a person. This is the page to read closely if you will be writing policies.

Policy syntax

A policy compiles to a bound. The syntax is deliberately small — there is no general-purpose language here, because a rule that can express anything cannot be reviewed by the team that owns the risk.

refund.ceiling · v7
# what a refund may be — not what a model may say
bound issue.refund {
  amount     <= INR 25_000
  scope      == order.placed_by(request.subject)
  requires   order.status in ["delivered","cancelled"]
  rate       <= 5 / hour / agent
  on_exceed  deny + escalate(owner)
}

Read that as the team that wrote it would say it out loud. That is the design constraint: a bound is expressed in business terms rather than as a resource ACL, because the person who has to agree it is correct is the person who carries the risk, not the person who deployed it.

The 8 bounds in the sample estate are owned by 6 different teams. Policy ownership being distributed rather than centralised is not an implementation detail — a platform team cannot know what a refund ceiling should be.

Policy lifecycle

A bound is versioned, and a version is published rather than edited. The history for refund.ceiling:

  1. v7tightened after a review (30 Jun 2026) · in force
  2. v6scope widened to a second system (11 May 2026)
  3. v1first published by Finance (24 Mar 2026)

Publishing rather than editing is what makes the next section possible. An edited rule destroys the record of what the rule used to say, which means every past decision it produced becomes unexplainable.

Replay

Any past action can be re-evaluated against any version of the bound that governed it. Two questions this answers, both of which come up in real reviews:

  • Was this decision correct at the time? Replay against the version in force when it happened.
  • What would this rule change have done? Replay a window of past actions against a proposed version before publishing it.
Replay before publishing
const result = await opsai.bounds.replay({
  bound: 'refund.ceiling',
  // The version you are considering, not yet published.
  version: 'draft_8',
  // Actions to re-evaluate. Refusals included — they are the interesting half.
  window: { from: '2026-06-01', to: '2026-09-01' },
});

result.changed;   // actions whose outcome would differ
result.newly_denied;
result.newly_authorized;

Risk evaluation

Risk is scored by a pure function over 4 dimensions. The weights are fixed and published:

  • What does it touch? 0.35 A write to a system that holds money, a ledger or a customer record is a different act from a read. The target is the single strongest signal and it is knowable before anything runs.
  • How much does it move? 0.25 Scored against the bound, not in absolute terms. A refund at 90% of its ceiling is near the edge of what anyone agreed to; the same amount under a larger ceiling is not.
  • Can it be undone? 0.3 The input teams forget and usually the one that decides the outcome. An action that can be reversed within the hour is a different proposition from one that has left the building.
  • How many subjects? 0.1 One order is one problem. A dataset export is every row in it, and the difference is not a matter of degree.

The score maps to one of 4 bands. The canonical refund scores 0.8490000000000001, which is grade critical.

Note also that risk and decision are independent. The canonical refund is grade critical and authorized: it is a consequential action that was within its ceiling. Treating high risk as a reason to refuse would make the system useless for exactly the work it is meant to govern.

Approval flows

When a bound requires a person, the action is held. A hold has three properties worth stating precisely:

  • It expires. It does not queue. If nobody responds within the window, the outcome is a refusal, and the expiry is recorded as its own event.
  • The approver sees the evaluation. Not a notification asking for a yes — the action, the checks that ran, the risk grade and the reason a person was needed.
  • The decision is attributed. A named human, a timestamp, and the bound version in force. An approval nobody can be identified with is not an approval.

The expiry default is the important one, and it is a deliberate inversion of how most queues behave. The default outcome of inattention should be no. The full argument.

Accountability

Every AI system has one accountable human. Not a team, not a rota — one person, because “the platform team” is not an answer to “who approved this”.

Delegation is capped at 3 levels. The cap exists because authority that can be passed on indefinitely cannot be reasoned about: past the third hop nobody can say whose authority is being exercised, and the whole point of the chain is that somebody can.

Read the authority chain
const { chain } = await opsai.actions.get('ACT-7512');

// Ordered from the accountable human down to the acting system.
chain.map((hop) => `${hop.kind}:${hop.id}`);
// ['person:priya', 'agent:refund-resolver']

How accountability is modelled covers the RACI treatment, including why the Accountable role is the only one that cannot be held by an AI system.