# Policy SDK

URL: https://docs.nexart.io/docs/policy-sdk

@nexart/policy declares producer-side predicates over captured execution fields as data, never as executable code, and can be sealed into a CER as producer-declared evidence.

## Overview

`@nexart/policy` 0.1.0 is a producer-side, standalone package. It lets a producer declare a set of declarative predicates (&quot;rules&quot;) that are evaluated against a captured execution&#x27;s fields. A policy MUST be data: it is a plain JSON-serializable structure. A policy MUST NOT contain executable code. This keeps a policy inspectable, hashable, and diffable without running untrusted logic.

A resulting evaluation MAY later be sealed into an AI Execution CER&#x27;s `policyEvaluation` field. See Versions for how the package version relates to other axes.

## The Closed v1 Type System

Policy SDK v1 defines a closed, non-extensible set of types:

- FieldType: `'number' | 'boolean' | 'string' | 'timestamp' | 'uuid' | 'identifier' | 'enum'`
- Operator: `eq, neq, lt, lte, gt, gte, between, exists, in, matches, before, after, within-window`
- Combinator: `'all' | 'any'`
- Verdict: `'PASS' | 'FAIL' | 'ERROR'`

ERROR is not FAIL
A rule verdict of `FAIL` means the predicate was evaluated and did not hold. A verdict of `ERROR` means the rule could not be evaluated at all (for example, a field type mismatch or an unknown operator). Consumers of a `PolicyEvaluation` MUST treat these as distinct outcomes.

## CapturedExecutionSchema, Policy, PolicyRule

A CapturedExecutionSchema declares the field names and `FieldType` of each field that may be referenced by a policy. A Policy is a combinator (`'all' | 'any'`) applied to a list of PolicyRule entries. Each PolicyRule names a field, an operator valid for that field&#x27;s type, and any operator-specific arguments (for example, a literal for `eq`, bounds for `between`, or a safe pattern for `matches`).

## The Operator / Type Matrix

Not every operator is valid for every field type. `OPERATOR_MATRIX` is the exported, authoritative table of which `Operator` is valid for which `FieldType`. Use `isOperatorValidForType(type, operator)` to check a single combination, `isKnownOperator` to check the operator is one of the closed set in `KNOWN_OPERATORS`, and `isSupportedCombinator` to validate `'all' | 'any'` against `SUPPORTED_COMBINATORS`. An invalid operator/type pairing MUST produce an `ERROR` verdict during evaluation, or a `PolicyValidationError` during `validatePolicy`.

## Core Functions

- `evaluatePolicy(schema, policy, execution)`: evaluates a Policy against a captured execution and returns a PolicyEvaluation with per-rule verdicts and an overall verdict.
- `validateSchema(schema)`: validates a CapturedExecutionSchema structurally.
- `validatePolicy(policy)`: validates a Policy against the closed operator/type matrix and combinator set.
- `hashSchema(schema)` / `hashPolicy(policy)`: deterministic hashes over the canonicalized schema or policy, built on `canonicalize`, `canonicalJson`, and `hashCanonical`.

## Deterministic, Clock-Independent within-window

The `within-window` operator compares timestamp fields captured in the execution against each other. It does NOT read the wall clock at evaluation time. This makes evaluation deterministic: re-running `evaluatePolicy` on the same schema, policy, and captured execution always produces the same verdicts, regardless of when evaluation happens. `isValidTimestamp` and `timestampToMs` are exported to validate and normalize timestamp fields consistently.

## Safe Pattern Constraints for matches

The `matches` operator only accepts patterns that pass `validateSafePattern` and can be built with `compileSafePattern`. This rejects pattern constructs known to cause catastrophic backtracking. A policy author MUST NOT assume arbitrary regular expression syntax is accepted; only the safe subset validated by these functions is permitted.

## Sealing a policyEvaluation Into a CER

A `PolicyEvaluation` produced by `evaluatePolicy` MAY be passed into `sealCerV2` or `certifyDecisionV2` as the `policyEvaluation` option. When present, it is covered by `certificateHash`. This makes the evaluation producer-declared evidence: the attestation node never re-executes the policy. It only seals and later returns what the producer declared, exactly like every other producer-declared field. See AIEF for how a sealed CER is later verified end to end.

## Scope Boundary

What the Policy SDK does not own
The Policy SDK MUST NOT be treated as owning sealing, certificateHash computation, node signing, RFC 3161 timestamping, Project Bundles, or provider calls. Those responsibilities belong to `@nexart/ai-execution`, the attestation node, and the relevant provider integration respectively.

## Runnable Example

Define a schema and policy, evaluate, then seal the evaluation

```
import { evaluatePolicy, validateSchema, validatePolicy, hashPolicy } from "@nexart/policy";
import { certifyDecisionV2 } from "@nexart/ai-execution";

const schema = {
  fields: {
    amount: { type: "number" },
    requestedAt: { type: "timestamp" },
    approvedAt: { type: "timestamp" },
  },
};

const policy = {
  combinator: "all",
  rules: [
    { field: "amount", operator: "lte", value: 5000 },
    {
      field: "approvedAt",
      operator: "within-window",
      reference: "requestedAt",
      windowMs: 60_000,
    },
  ],
};

validateSchema(schema);
validatePolicy(policy);

const execution = {
  amount: 4200,
  requestedAt: "2026-08-18T10:00:00.000Z",
  approvedAt: "2026-08-18T10:00:12.000Z",
};

const evaluation = evaluatePolicy(schema, policy, execution);
// evaluation.verdict is 'PASS' | 'FAIL' | 'ERROR'

const bundle = await certifyDecisionV2({
  provider: "openai",
  model: "gpt-4o-mini",
  input: { amount: execution.amount },
  output: { approved: evaluation.verdict === "PASS" },
  executionRole: "operative",
  policyEvaluation: evaluation,
});

// policyEvaluation is now producer-declared evidence sealed inside certificateHash
console.log(hashPolicy(policy));
```

## Next

- AIEF: verifying a bundle that may include a sealed policyEvaluation.
- Versions: how the Policy SDK version relates to package, schema, and protocol versions.
- Glossary: definitions for verdict, sealing, and related terms.
