Skip to main content
A governance decision is made by the closed governor (the gateway). This page is about where it is written down, which is a separate question with a separate answer per record.

The three records that exist

Live, all three fan out over the company SSE stream at GET /v1/events.
activity_events is not an audit ledger, by design. logTenantEvent catches its own insert failure, logs a warning, and returns false — deliberately, so that an audit-log write can never fail the business action it describes. That is the right trade-off for a log and the wrong property for a ledger: an absent row does not prove an absent act.Reconcile against approvals, which is committed on the transaction path, not against the activity log. If you need a complete count of gated actions, count approvals.

What policy_decisions is, and why it answers 501

The design calls for one ledger — policy_decisions — carrying every verdict with its inputs, its trace_id and a stable decision_id, so that “why was this denied?” is a lookup rather than a reconstruction. That table does not exist in this build. Nothing writes it and nothing reads it. Rather than fabricate a decision_id, the operations that would return one return null beside a sibling field naming the reason:
A fabricated id would be indistinguishable downstream from a real one, which is precisely the failure a ledger exists to prevent. Operations that refuse for this reason:
POST /v1/policy/waives answers 501, not 403. A 403 would tell you the platform refused to waive something it never evaluated — there is no statute layer to waive against. The 403 becomes the correct answer the day a statute exists.

What you can answer today without the ledger

POST /v1/policy/explain is pure (it declares side_effects: [] on the wire so you do not have to take this page’s word for it) and calls the same isPrimitiveEnabled / capabilityAllowed / resolveApprovalRequirement the gate calls. It reports the engine’s verdict vocabulary — park, never “approve” — plus the layer that decided and the exact config path:
  • layer: "company" → an AccountKit field, named (account_kit.primitives_config.<p>.enabled)
  • layer: "platform" → the built-in DEFAULT_APPROVAL_ACTIONS
  • layer: "call" → nothing refuses this action
GET /v1/policy/statute enumerates that built-in set — and reports waivable: true, because it is a set of defaults a kit can opt out of with requiresApproval: false, not a statute. Calling it a statute without saying so would overstate what cannot be waived.