Skip to main content
packages/policy/src/index.ts exports PolicyEngine, PolicyRegistry, PolicyRouter, PolicyValidator, SignalValidator, the PolicyRepository interface plus its FilePolicyRepository implementation, and the Policy/PolicyCondition/PolicyRule/PolicySignals/PolicyDecision/PolicyAction/PolicyOutcome types.

PolicyEngine.evaluate()

class PolicyEngine {
  evaluate(policy: Policy, signals: PolicySignals): PolicyDecision;
}
Evaluation is first-match-wins: PolicyEngine walks policy.rules in array order and returns the outcome of the first rule whose condition matches the supplied signals — deterministic by construction, since the same policy + signals always walks the same rules in the same order. Conditions (PolicyCondition) support:
  • A leaf check against one named signal: greater_than (numeric), equals (any JSON value), or plain truthiness if neither is given.
  • all: [...] — logical AND over child conditions.
  • any: [...] — logical OR over child conditions.
PolicyAction (APPROVE, REQUIRE_OVERRIDE, REJECT) on the matched rule maps to a PolicyOutcome; no match falls through to REJECT with reason: "no_rule_matched". This is the same engine @parmana/replay’s (currently unused) ReplayEngine re-invokes to independently re-derive a decision.
// policies/vendor-payment/1.0.0/policy.json shape (illustrative)
{
  "policyId": "vendor-payment",
  "policyVersion": "1.0.0",
  "schemaVersion": "1.0.0",
  "signalsSchema": { "amount": "number", "vendorVerified": "boolean" },
  "rules": [
    {
      "id": "auto-approve-small",
      "condition": { "all": [{ "signal": "amount", "greater_than": 0 }, { "signal": "vendorVerified", "equals": true }] },
      "outcome": { "action": "APPROVE", "reason": "vendor verified" }
    }
  ]
}

Loading policies

class PolicyRouter {
  constructor(repository: PolicyRepository);
  load(name: string, version: string): Promise<Policy>; // validates via PolicyValidator before returning
}

class FilePolicyRepository implements PolicyRepository {
  constructor(basePath: string);
  load(name: string, version: string): Promise<Policy>; // reads <basePath>/<name>/<version>/policy.json
}
packages/api/src/application.ts constructs FilePolicyRepository directly, pointed at process.env.PARMANA_POLICY_DIR — the monorepo root’s policies/ directory. PolicyRouter additionally runs PolicyValidator before returning a loaded policy, but the POST /policies/validate route (REST API → Policies) calls policyRepository.load() directly, not through PolicyRouter — so that endpoint only confirms the file exists and parses as JSON, and never runs PolicyValidator’s checks.

Policy (concept)

The domain concept this package implements.

REST API → Policies

The one HTTP endpoint over this package.

replay

The other consumer of PolicyEngine.

Decision

What a PolicyDecision becomes downstream.