enum, the
allowed values are the real ones the census accepts.
The resource graph
The Phosra core object model. A Family owns Children and FamilyMembers; each Child owns ChildPolicies; each policy owns PolicyRules. Enforcing a policy creates an EnforcementJob that fans out to one EnforcementResult per platform. On the data plane, each rule compiles to a Verdict that the gatekeeper reads locally, and confirming it writes an EnforcementReceipt.
phosra_ key. The violet Verdict and
EnforcementReceipt live on the data plane: they are compiled
into a signed profile and evaluated locally, in-process by the gatekeeper — there is no
hosted POST /check. The rule_ref field is the thread that stitches a product-plane
PolicyRule to its data-plane Verdict and back to a receipt.Objects
Family — the household root
Family — the household root
FamilyMember — a guardian on the account
FamilyMember — a guardian on the account
Child.Child — a kid's profile
Child — a kid's profile
birth_date.ChildPolicy — a named set of rules
ChildPolicy — a named set of rules
status and a priority for ordering.PolicyRule — one category decision
PolicyRule — one category decision
EnforcementJob — one push to platforms
EnforcementJob — one push to platforms
EnforcementResult — per-platform outcome
EnforcementResult — per-platform outcome
Verdict — the gatekeeper's local decision
Verdict — the gatekeeper's local decision
CategoryEntry inside the signed
§8.3.6 enforcement profile. The @phosra/gatekeeper SDK reads it with gk.isAllowed({ category })
— entirely locally, zero network — and returns a Verdict.fail_mode with values
open/closed; the gatekeeper SDK surfaces the same signal as failMode with allow/block.
fail_mode:"closed" ⇔ failMode:"block". See Platform integration.EnforcementReceipt — the signed apply attestation
EnforcementReceipt — the signed apply attestation
verdict.confirm(...), which
signs and POSTs a §8.3.8 enforcement_result receipt. It is identity-free by construction
— no child ref, device id, or user id. The inner body is exactly five fields.Lifecycle & state
Three objects in the graph are state machines. Knowing the transitions saves you a class of “why isn’t this enforcing?” bugs.ChildPolicy — draft → active → paused
draft
POST /policies starts a policy in
draft unless you activate it.active
POST /policies/{id}/activate. When a child has
multiple active policies, priority (higher wins) breaks the tie.paused
POST /policies/{id}/pause. Re-activate any time.EnforcementJob — pending → running → completed | failed | partial
pending → running
202 Accepted) and begins fanning out to platforms.completed
EnforcementResult succeeded.partial
rules_skipped / rules_failed per result.
Common when a platform can’t express a category (manual_attested; see Platforms).failed
Verdict standing — allow · warn · block (fail-closed)
A verdict is not a stored row that transitions; it is recomputed locally on every
isAllowed() call from the current signed profile. Its standing is one of allow, warn,
or block. If the cached profile is missing or expired, a fail_mode: closed category
resolves to block with rule_ref: null — enforcement never silently passes.
Prove the graph is live
The product-plane objects are served today. No key gives you a401 (not a 404), which is
the correct answer — the surface exists:
phosra_ key (mint one in the
Developer Console); see Authentication. On the
open sandbox the product plane is keyless — the Quickstart’s POST /setup/quick
creates your first family → child → policy → rule → enforcement job end to end with no credential
at all (see Test in the sandbox).Where to go next
Quickstart →
POST /setup/quick call, then enforce it.