Phosra Link × Chirp, end to end

A parent sets one rule in their parental-control app, connects it to a Twitter-style site with Phosra Link, and the site enforces it — with a Cloudflare Worker in front of an unmodified site (this tab), with the Worker forwarding the policy to Chirp (option 2), and natively. All screenshots come from real runs of this repo (npm run demo:edge / demo:edge-header / demo:native).

🐦 ChirpThe platform: a Twitter-style site. Posts carry an age rating (All ages, 7+, 13+, 16+, 18+).
🛡 GuardianThe parent's parental-control app. Holds the rule: content rated up to 13+.
✳︎ Phosra LinkConsent screens, signed delivery, router-signed profile, signed receipts.
☁️ Cloudflare WorkerSits in front of Chirp; hosts Gatekeeper and filters Chirp's HTML and JSON.

1 · Chirp before any parental controls

One family account with three profiles. Maya is 12, and her feed shows everything, including 16+ and 18+ posts.

01Sign in to Chirp ChirpThe family account, dana@chirp.test.
02Pick a profile ChirpDana (parent), Leo (15) and Maya (12).
03Maya's feed, unrestricted ChirpAll 12 posts, including two 18+ and two 16+. Click to see the full page.

2 · The parent's control panel

Guardian is where the parent sets the rule, once, per child: content rated up to 13+. Each child has a Chirp connection that starts as “Not connected”.

04Parent signs in to Guardian GuardianPhosra never sees this login; it binds to the parent's existing session.
05Family controls GuardianMaya and Leo, each with the rule “Content rating: up to 13+” and Chirp not yet connected.

4 · The restriction in effect

Same site, same account, a few seconds later. Only Maya's profile changes.

Maya before12 postsratings 0 · 7 · 13 · 16 · 18
Maya after8 postsratings 0 · 7 · 13 only, plus a notice
Dana (parent)12 postsunchanged
03Maya, before Chirp18+ red-band trailer, 16+ comedy clip, 16+ thriller marathon, and more.
11Maya, after Worker“Managed with Phosra” notice; every 16+ and 18+ post is gone.
12Dana, unrestricted ChirpThe parent's own profile still sees 18+ and 16+ posts; the rule is per child.

5 · How the Cloudflare Worker does it (option 1)

In edge mode Chirp has no Phosra code. The Worker hosts Gatekeeper at /api/phosra/*, records what it enforces, and filters Chirp's responses with HTMLRewriter.

Want Chirp to enforce the rule in its own queries, with the Worker still owning everything Phosra? That is option 2.

11Maya through the Worker :3011 Worker8 posts, notice says “Enforced at the edge by a Cloudflare Worker”.
13Same session, origin directly :4011 originThe unmodified site still serves all 12 posts. Left open only so this demo can show the difference: in production the origin is reachable only through the Worker (Cloudflare Tunnel, mTLS origin pulls or Access), so this bypass does not exist.
14The JSON feed is filtered too WorkerGET /api/timeline as Maya: only ratings ≤ 13, with an x-phosra-edge: content_rating<=13 header.
15Gatekeeper status from the Worker WorkerPLATFORM_READY: credential, signing key, Trust List standing and database all verified at the edge.

6 · Native mode: the same rule, built into Chirp

With npm run demo:native, Chirp runs Gatekeeper itself (chirp/src/phosra.ts) and filters in its timeline query. Same parent flow, same result, plus Chirp can show the control in its own UI.

16Managed profile badge Chirp nativeMaya's profile card shows “🛡 Up to 13+”, read from the control Chirp applied.
17Maya's feed, filtered by Chirp Chirp nativeSame 8 posts (ratings 0, 7, 13), notice rendered by Chirp itself.