Jadpo is experimental and not ready for production. These docs follow the compiler's main branch as of 5 Nov 2026. What's built · Install 0.3.0
jadpo
ReferencePolicy

APIsPolicy

Protecting policy

An agent can edit policy, but the change can't ship without a person's approval, wherever it is written. The compiler compares the application before and after, because access widens wherever policy is written and also when a route becomes public.

Each widening needs an acceptance: a file in acceptances/ in which a person accepts that change (Acceptances). Breaking API changes and database drops are accepted the same way. jadpo check compares the change with the default branch at its merge base through access.jadpo_record, who can do what, which it keeps at the root beside api/, and the API record. These need a person:

  • a caller added to any grant list, an entity's or a field's (library.Book.read: PolicyChange.widened);
  • a field's own row, or its FieldAccess.server_only, removed (PolicyChange.restriction_removed);
  • tenancy loosened: an entity that belonged to the tenant now shared by every tenant, or the app's tenant gone (PolicyChange.tenancy_loosened), or a new entity shared by every tenant (PolicyChange.shared_entity_added);
  • an action's line under actions: added or removed, since a listing replaces its entities' grants (PolicyChange.listing_added, .listing_removed), and a caller added to an action's line;
  • a listed query's line removed, or a caller added to it;
  • a route that needed a signed-in caller made open to anyone ("main GET /books": PolicyChange.route_public);
  • a route that needed the person's passkey no longer asking for it ("main POST /payouts/{payout_id: Uuid}/send": PolicyChange.confirmation_removed);
  • a decline of policy.call_ungranted, a security rule (PolicyChange.call_ungranted_declined).

Narrowing needs no one: a caller removed, a restriction added, a query newly listed, a new route even one anyone may call, a new entity that belongs to the tenant. Access also widens when an output gains a field or an action starts touching another entity; jadpo approval shows those ways there.

Schedules and subscribers act as the system (Policy and background work), and what Access.system is granted shows in the permissions report. The compiler's own purge of soft-deleted records (The purge schedule) is the only operation outside policy. Erasing a person needs delete on their record, and then reaches every record of theirs as purge does (Erasure).

Markdown for agents: /docs/protecting-policy.md.Built from Jadpo main at aee2e8f.