Files
nucleic/cloud/nucleic-edge
abkslmandnucleic add3c817e4 Live Activity Refresh Delay
Nucleic-Session: 8C954A45-A16B-4E91-B9E6-9865809096D7
Co-authored-by: Nucleic <[email protected]>
2026-07-06 01:37:50 -07:00
..
2026-07-06 01:37:50 -07:00
2026-06-26 16:18:02 -07:00
2026-06-27 14:23:38 -07:00

nucleic-edge

Cloudflare Worker for Nucleic's cloud edge. See docs/CLOUD_INFRA.md for the full design.

  • Phase A (now): POST /v1/heartbeat — anonymous DAI (daily active installs) heartbeat → Workers Analytics Engine (nucleic_dai). Indexed by a random install UUID, so it counts installs, not users. GET /health for a liveness check.
  • Phase B/C (later): WebSocket relay (Durable Object Room) + APNS approval push. The relay also writes a true daily-active-user metric (nucleic_relay_dau), indexed by roomId ≈ account — see Relay DAU below.

Develop

npm install
npm run typecheck      # tsc --noEmit
npm test               # vitest — unit tests for the payload validator
npm run check          # wrangler deploy --dry-run (bundles, no upload, no auth)
npm run dev            # local server at http://localhost:8787

POST smoke test against a local npm run dev:

curl -i -XPOST http://localhost:8787/v1/heartbeat \
  -H 'content-type: application/json' \
  -d '{"installId":"11111111-2222-3333-4444-555555555555","platform":"macos","osVersion":"26.0","channel":"beta","appVersion":"0.1.0","build":"42","arch":"arm64","locale":"en"}'
# → 204

(AE writes are accepted but not queryable from local dev; verify counts after deploy.)

Provision (one-time, Cloudflare dashboard / API)

  1. Ensure the blakeslee.xyz zone is on this account (the routes custom domain needs it).

  2. Deploy: npm run deploy — provisions api.nucleic.blakeslee.xyz + cert and creates the nucleic_dai (and, once the relay is live, nucleic_relay_dau) dataset on first write.

  3. Query DAI — daily active installs (AE SQL API), e.g. last 30 days split by platform:

    SELECT toStartOfDay(timestamp) AS d, blob1 AS platform, count(DISTINCT index1) AS dai
    FROM nucleic_dai
    WHERE timestamp > now() - INTERVAL '30' DAY
    GROUP BY d, platform
    ORDER BY d
    

Blob/index layout (keep in sync with the client + the SQL above)

nucleic_dai — indexed by the anonymous install UUID (counts installs, not users):

Field Slot
installId index1
platform blob1
osVersion blob2
channel blob3
appVersion blob4
build blob5
arch blob6
locale blob7

Relay + APNS (Phase B/C)

The relay is E2EE-opaque: binary WebSocket frames are forwarded byte-for-byte and never inspected (Noise runs end-to-end through it). A separate text control plane carries non-secret relay metadata. See docs/CLOUD_INFRA.md §2–§3 and §2.1 for the token lifecycle.

Relay DAU

Every admitted /relay connection writes one data point to the nucleic_relay_dau Analytics Engine dataset, indexed by roomId. Because roomId is derived from the host's static public key (docs/CLOUD_INFRA.md §2.1), one room ≈ one user/account — so count(DISTINCT index1) is a true daily-active-user count, unlike nucleic_dai which counts installs. Same-day reconnects collapse under the DISTINCT.

Field Slot
roomId index1 user/account identity (host static-key hash)
role blob1 host | client
deviceId blob2 for "distinct devices per user" slices
SELECT toStartOfDay(timestamp) AS d, count(DISTINCT index1) AS dau
FROM nucleic_relay_dau
WHERE timestamp > now() - INTERVAL '30' DAY
GROUP BY d
ORDER BY d

Endpoints

Method & path Auth Purpose
GET /relay?t=<connToken> (Upgrade) connection token Join a room's WebSocket
POST /v1/relay/token RELAY_ADMIN_SECRET Host mints a 90-day membership token for a paired device
POST /v1/relay/connect membership token (Bearer) Trade membership → a ~2-min connection token
POST /v1/relay/revoke RELAY_ADMIN_SECRET Revoke a device on unpair ({deviceId})
POST /v1/push/notify RELAY_ADMIN_SECRET Out-of-band APNS wake for {deviceId}

Control-plane frames (text JSON over the room socket):

  • phone → relay: {"t":"register","pushToken":"<hex>","env":"sandbox|production"}
  • host → relay: {"t":"wake","deviceId":"<id>"} — pushes only if that device's socket is absent
  • relay → all: {"t":"presence","peers":[{deviceId,role}]}

Provision (one-time)

  1. KV: wrangler kv namespace create NUCLEIC_RELAY_TOKENS and ... NUCLEIC_PUSH_TOKENS; paste the ids into wrangler.jsonc.
  2. Relay secrets: wrangler secret put RELAY_TOKEN_SECRET (random 32+ bytes), RELAY_ADMIN_SECRET.
  3. APNS: create a .p8 auth key (Apple Developer → Keys, Push enabled), then wrangler secret put APNS_KEY_P8 (paste the PEM), APNS_KEY_ID, APNS_TEAM_ID (L7UDTQ6F5W), APNS_TOPIC (xyz.blakeslee.nucleic.remote), APNS_ENV (sandbox for TestFlight/dev, production for App Store).
  4. Enable Push Notifications on the xyz.blakeslee.nucleic.remote App ID; ship the iOS app with aps-environment.
  5. npm run deploy (creates the Room DO on first deploy).

Smoke test (after deploy)

M=$(curl -s -XPOST https://api.nucleic.blakeslee.xyz/v1/relay/token \
      -H "authorization: Bearer $RELAY_ADMIN_SECRET" \
      -d '{"roomId":"r1","deviceId":"host1","role":"host"}' | jq -r .token)
C=$(curl -s -XPOST https://api.nucleic.blakeslee.xyz/v1/relay/connect \
      -H "authorization: Bearer $M" | jq -r .token)
websocat "wss://relay.nucleic.blakeslee.xyz/relay?t=$C"     # then a second client in room r1

APNS delivery must be exercised from the deployed Worker — local wrangler dev can't do HTTP/2 to Apple (workerd #4841).

Trusted Tester program

The iOS companion ships through TestFlight; rather than hand out the public join link, outside people apply to become trusted testers (form at website/trusted-tester.html, plus in-app links in the macOS Remote settings and iOS Settings). Each application is gated behind the owner's one-click email approval; on approval the owner hand-invites the applicant into the internal TestFlight group (Apple can't add an outside email to an internal group via API). Source: src/testers.ts.

Endpoints

Method & path Auth Purpose
POST /v1/tester/apply open (CORS'd to the site; rate-limited; optional Turnstile) Site form submits an application → stored pending, owner emailed
GET /v1/tester/review?id&action&token HMAC in the link Owner clicks Approve/Reject in the email → flips status, renders a page
  • Storage (KV NUCLEIC_TESTER_APPS): app:<uuid> → JSON record; email:<addr> dedupe index (a rejected applicant may re-apply); rl:<ip> coarse rate-limit counter.
  • Review links are stateless HMAC-SHA256 over "<id>:<action>" (TESTER_APP_SECRET), so only the owner — who receives the email — can act. Approve/Reject is idempotent (safe to re-click).
  • Owner email uses the OWNER_EMAIL send_email binding, pinned to [email protected], so the Worker can only ever mail the owner. We never email applicants (Apple's TestFlight invite is the applicant-facing mail once the owner adds them).

Provision (one-time)

  1. KV: wrangler kv namespace create NUCLEIC_TESTER_APPS; paste the id into wrangler.jsonc.
  2. Secret: wrangler secret put TESTER_APP_SECRET (random 32+ bytes).
  3. Email: enable Email Routing on the blakeslee.xyz zone and verify [email protected] as a destination address (one confirmation-link click) so the send_email binding can reach it. Optionally wrangler secret put TESTER_FROM_ADDRESS (defaults to [email protected]).
  4. (Optional) Turnstile: create a widget, add the site key to website/trusted-tester.html, and wrangler secret put TURNSTILE_SECRET. Without it the form still works (rate-limit + honeypot only).
  5. npm run deploy.

Smoke test

curl -i -XPOST https://api.nucleic.blakeslee.xyz/v1/tester/apply \
  -H 'content-type: application/json' \
  -d '{"firstName":"Ada","lastName":"Lovelace","email":"[email protected]","jobTitle":"Engineer","employer":"AE Ltd","experienceYears":"12","techBackground":"Swift, TS","agentExperience":"Claude Code daily","applePlatform":"iOS 8y","testDevices":"iPhone 15 / iOS 18.1","motivation":"sharp repro bug reports"}'
# → 200 {"ok":true}; the owner receives an email with Approve/Reject links.