@capyn/policy-engine is the core public technical artifact. Its single operation is pure:
evaluatePolicy(input: PolicyEvaluationInput): PolicyEvaluation
It has no database, network, clock or chain dependency. The caller supplies an ISO timestamp and spend totals loaded under a transaction lock.
Evaluation order
- Validate configuration and mandate cardinality.
- Require an active agent.
- Require exactly one active mandate.
- Check mandate validity window.
- Check the requested capability.
- Check the normalized vendor ID against the allowlist.
- Check the hard transaction ceiling.
- Check projected UTC-day spend.
- Check projected calendar-month spend.
- If every hard rule passes, apply the approval threshold.
Any hard-rule failure produces DENY, even when the amount also crosses the approval threshold. Human approval is not a hard-limit override.
Decisions
ALLOW: every hard rule passes and human review is not required (or was already granted for this request).DENY: one or more hard rules fail, or policy cannot be interpreted safely.REQUIRE_APPROVAL: every hard rule passes and the amount is strictly above the review threshold.
The output contains decision-driving reasonCodes and a complete trace. A deny can contain multiple independent reasons so operators do not have to fix one rule at a time.
Example trace
[
{
"rule": "capability",
"result": "PASS",
"reasonCode": "CAPABILITY_ALLOWED",
"details": { "requested": "spend.compute" }
},
{
"rule": "dailyLimit",
"result": "PASS",
"reasonCode": "DAILY_LIMIT_OK",
"details": {
"currentSpendMinor": "1800",
"projectedSpendMinor": "13800",
"limitMinor": "20000"
}
},
{
"rule": "approvalThreshold",
"result": "REVIEW",
"reasonCode": "APPROVAL_THRESHOLD_EXCEEDED"
}
]
Money and time
USD 18.42becomes the string"1842"minor units.- JavaScript
numberis never used for money arithmetic. - Daily periods begin at
00:00:00 UTC. - Monthly periods begin on day one at
00:00:00 UTC. - Mandate
validUntilis exclusive.
Fail-closed cases
POLICY_CONFIGURATION_ERROR is returned for malformed minor units, mismatched currency, empty grants/allowlists, invalid validity windows, unordered limits or multiple active mandates. The safe public description does not disclose internal configuration details; the audit trace can retain a bounded diagnostic.
Tests
The suite covers capabilities, vendors, transaction/daily/monthly limits, expiry, inactive agents, approval, combined failures, absent mandates and malformed configuration. Run:
pnpm --filter @capyn/policy-engine test
When behavior changes, update this document, the REST response contract where relevant, and the catalog review date as described in Documentation policy.