You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
id: design: ID serverless edition v1 (Cloudflare Workers) #2046
LIST 12 synthesis. Merge the Workers-fit and hosted-option investigations into the serverless edition v1 design: what ships first, the per-user data story, and the boundary with the self-hosted ID server.
Program: Drew's 2026-10-28 directive (full text: hatch-personal memory/topics/id-program-2026-10-28.md).
Working pattern: parallel investigations, then the named synthesis issue merges them into a full design. Route guidance: Workhorse by default; Specialist/Summit for synthesis and ramification-heavy work. A result that says "done" is not the endpoint — the orchestrator reviews it and may commission another round. Deliverables: a markdown design/investigation doc (mermaid/SVG diagrams welcome) linked from this issue, plus follow-up issues for anything buildable. Build a proof of concept where the design calls for one, but do NOT build the permanent feature on top of an unreviewed PoC.
Decision-ready synthesis — ID serverless edition v1
Decision: ship a hosted personal home-store as an HTTP/WebSocket service, not a Worker pretending to be an Iroh peer. Keep native/self-hosted ID as the full Iroh node. Keep static/local storage as the free, availability-free floor; make the first hosted tier one lazily-created SQLite-backed Durable Object (DO) per bound user, with content-addressed blobs in R2. Exclude shared-world hosting from v1.
Current-main grounding: reviewed main at a9e976ac245d94682ff7ada8dd5562cc58c9b00f. ID documents itself as Iroh/QUIC with node-key identity (lib.rs:1-18); world sessions use Iroh Endpoint and Tokio streams (world_net.rs:1-23). The current web AppState owns Iroh blob/tag stores and identity (web/mod.rs:142-174); Axum REST/WebSocket routes are at web/routes.rs:257-315, and Cargo's Iroh/Tokio/Axum dependencies are at Cargo.toml:41-58,75-99. A Worker therefore needs a separate storage/network adapter, not deployment of the present server binary.
Options and recommendation
Shape
Decision
Why
A. Static client + local storage
Keep as free fallback
No idle hosting cost or availability promise; device loss remains the user's risk unless synced.
Multi-writer throughput and cost attribution are separate decisions; wait for #2271 and #2284.
D. Container per user
Reject as a tier
Indefinite idle spend violates the program guardrail; only explicit time-boxed jobs with owner + auto-stop are allowed.
D1 per user/shared user SQL table
Reject for user content
Per-user DO is structurally isolated; a shared directory may be data-minimal only.
The #2044 fit report says Workers expose no UDP, so they cannot be Iroh QUIC peers; the hosted leg is HTTPS/WebSocket application semantics and a bridge (report:155-189). Its recommended split is Worker + UserDO + minimal D1 directory + R2; WorldDO is later (report:432-451).
Per-user data and identity
Key the account registry by Google's immutable sub; email is contact metadata, never identity. Google authenticates the account; the Iroh root key remains the ID identity.
Bind only through an expiring challenge signed by the Iroh root key and countersigned by the service. Sign-in alone creates an empty account; no custodial keys. Devices attach through existing grants.
Export signed objects + binding manifest to self-hosted ID. At quota caps, degrade to read-only plus export/reclaim, never silent deletion. Meter per user; batch journal writes; hibernate sockets; no always-on user process.
Boundary with self-hosted ID and invariants
Native ID keeps Iroh QUIC, discovery/gossip, hole-punching, native SSH/world rendering and local stores. Hosted clients add HTTPS/WSS transport beside native transport; hosted ID is not a QUIC peer and does not promise parity. Bridge only existing signed objects over HTTPS/WSS: no re-signing, server-assigned order, authoritative snapshot, or height-only sync. Current verified batch ingestion is event_store/ingest.rs:350-389 and store_traits.rs:118-140. The semantics PoC (#2276 / merged PR #2848) demonstrated convergence, fork proof, withholding detection and replay identity; it is not a production endpoint (findings).
Acceptance invariants: distinct/unique sub, binding_id, and Iroh key; fresh challenge and no silent rebind; binding- and jurisdiction-scoped access; signatures/hashes verified on ingest; original evidence preserved through sync; bounded/incremental replay; no blobs in SQLite; no per-user containers; hibernating sockets; graceful caps and export. Hosted storage is operator-readable unless client-side encryption is on; disclose degraded search/previews and per-user-only encrypted blob dedupe.
Parameters for Drew — recommendations, not silent defaults
Rebind wait: choose 14/30/90 days; recommend 30 days, with notice and old-key cancellation. Please accept/override; never minutes.
Free/paid quotas and prices: choose fixed preview cap then paid, or free hosted + metered paid. Recommend a low metered free cap and paid caps below provider hard ceilings (the report's 1GB/10GB are platform limits, not product quotas); choose numeric price/quotas after cost review.
Shape-C lapse attribution (later only): owner/sponsor vs participant split vs platform subsidy; recommend owner/sponsor and pause writes/export on lapse. This gates shared-world hosting, not UserDO v1.
Pairing-code rate limits are operational tuning: start conservative and make configurable/observable; no Drew-only decision.
Phased implementation routing
#2852 remains the parent tracker for the four #2258 spec slices; these child issues make them independently queueable. They have not-before 2026-11-02T00:00Z so the design and related routing gates can settle; packets explicitly say to park rather than guess if a prerequisite remains open.
Shared-world execution remains on existing #2271 (task 5598, PR #3726 open) and #2284 work; do not duplicate it or promise production portability yet. No shipped pkgs/id behavior changed in this synthesis.
Recommend v1 as a Workers-hosted personal home-server, not a port of the native Iroh peer.
Keep static/local storage as the free floor; the hosted tier is one lazy SQLite-backed UserDO per bound ID, with R2 blobs and data-minimal D1 registry.
Google SSO authenticates an account; a signed Iroh-key ceremony binds identity and provisions a stable binding_id store.
Sync with native nodes over a passive HTTPS/WebSocket bridge that preserves signed-event trust/order; native self-hosting remains intact.
Reuse the existing signed-event semantics PoC as evidence, not a production endpoint; validate Worker runtime/storage separately.
Production signed-object HTTPS/WS bridge with resumable sync.
Signed-object/blob export and verified import.
Allowlisted beta, cost measurement, operational guardrails and approved public caps/prices.
Each phase is a separate reviewable PR. The PoC is reviewed before permanent code builds on it.
Questions for Drew
Tier numbers/prices: publish numeric free/paid caps now, or beta with a low metered free cap, paid caps below provider hard limits, and finalize numbers/prices after cost review? Recommend the latter.
Lost-key rebind delay: 14, 30 or 90 days? Recommend 30 days, with old-key cancellation/early approval and notices to recorded contacts.
Client-side encryption default: off with a clear operator-readability disclosure and opt-in, or on with reduced hosted search/indexing/previews? Recommend off only with explicit disclosure; otherwise on. Please choose the product default.
Shape-C owner lapse (only before shared-world hosting): owner/sponsor attribution with writes paused and export available, participant split, or platform subsidy? Recommend owner/sponsor attribution and pause/export. This does not block UserDO v1.
No other Drew ruling is needed to start the PoC or account/binding work. Challenge/rate-limit thresholds are operational tuning; jurisdiction placement is gated by #2283, not a Drew question here.
agent-note:v1
state: triaged (coverage pass)
Coverage pass 2026-11-03: reviewed in the fleet-wide per-issue pass (drift / overlap / already-handled / stale / blockers / ordering). Verdict: still live; queued in repo-health-code-pilot as triage at priority 30 (priority/none). If this is already handled at current main, the triage closes it with evidence; if it needs splitting, the triage files the split.
Found via: coverage pass 2026-11-03
Outcome: The synthesis this issue asks for was already delivered and ruled on; nothing remains for this design issue itself. Closing on its merits (deliverable complete), not for age.
Design doc doc/2026-11-01_design_id2046.md landed via PR design(id): #2046 Workers v1 architecture #3827, MERGED 2026-11-02; verified present at current main (blob sha 20bf928fd6647f8dcea4209a98de68c8683fa7db).
Ruling recorded on this issue 2026-11-03: CSE default ON at binding, 30-day rebind wait, low metered free cap with prices after cost review, Shape-C lapse deferred — tasks 5814, 5815, 5816, 5823 unblocked by that ruling.
Activity
developing-today commentedon Oct 29, 2026
CODE-967
dezren39 commentedon Oct 29, 2026
Parent epic: #2056 — ID platform expansion (2026-10-28 directive).
dezren39 commentedon Oct 29, 2026
🤖 Agent note · handed off
dezren39 commentedon Nov 1, 2026
🤖 Agent note · picked up
dezren39 commentedon Nov 1, 2026
Decision-ready synthesis — ID serverless edition v1
Decision: ship a hosted personal home-store as an HTTP/WebSocket service, not a Worker pretending to be an Iroh peer. Keep native/self-hosted ID as the full Iroh node. Keep static/local storage as the free, availability-free floor; make the first hosted tier one lazily-created SQLite-backed Durable Object (DO) per bound user, with content-addressed blobs in R2. Exclude shared-world hosting from v1.
Current-main grounding: reviewed main at
a9e976ac245d94682ff7ada8dd5562cc58c9b00f. ID documents itself as Iroh/QUIC with node-key identity (lib.rs:1-18); world sessions use Iroh Endpoint and Tokio streams (world_net.rs:1-23). The current web AppState owns Iroh blob/tag stores and identity (web/mod.rs:142-174); Axum REST/WebSocket routes are at web/routes.rs:257-315, and Cargo's Iroh/Tokio/Axum dependencies are at Cargo.toml:41-58,75-99. A Worker therefore needs a separate storage/network adapter, not deployment of the present server binary.Options and recommendation
The #2044 fit report says Workers expose no UDP, so they cannot be Iroh QUIC peers; the hosted leg is HTTPS/WebSocket application semantics and a bridge (report:155-189). Its recommended split is Worker + UserDO + minimal D1 directory + R2; WorldDO is later (report:432-451).
Per-user data and identity
sub; email is contact metadata, never identity. Google authenticates the account; the Iroh root key remains the ID identity.sub, but id: investigate: hosted data option — per-user stores, Google SSO, static/local-storage variants, container-spend limits #2045 and the merged id: design: hosted provisioning + SSO→ID binding spec — account/binding records, challenge ceremony, delayed rebind, metering, export (from #2045) #2258 spec separate account and ID identity and makebinding_idstable across key rebind. Therefore account row bysub, UserDO name by immutablebinding_id—never email or a rebindable key. See #2258 spec §0-1 and id: investigate: hosted data option — per-user stores, Google SSO, static/local-storage variants, container-spend limits #2045's completed investigation.Boundary with self-hosted ID and invariants
Native ID keeps Iroh QUIC, discovery/gossip, hole-punching, native SSH/world rendering and local stores. Hosted clients add HTTPS/WSS transport beside native transport; hosted ID is not a QUIC peer and does not promise parity. Bridge only existing signed objects over HTTPS/WSS: no re-signing, server-assigned order, authoritative snapshot, or height-only sync. Current verified batch ingestion is event_store/ingest.rs:350-389 and store_traits.rs:118-140. The semantics PoC (#2276 / merged PR #2848) demonstrated convergence, fork proof, withholding detection and replay identity; it is not a production endpoint (findings).
Acceptance invariants: distinct/unique
sub,binding_id, and Iroh key; fresh challenge and no silent rebind; binding- and jurisdiction-scoped access; signatures/hashes verified on ingest; original evidence preserved through sync; bounded/incremental replay; no blobs in SQLite; no per-user containers; hibernating sockets; graceful caps and export. Hosted storage is operator-readable unless client-side encryption is on; disclose degraded search/previews and per-user-only encrypted blob dedupe.Parameters for Drew — recommendations, not silent defaults
Phased implementation routing
#2852 remains the parent tracker for the four #2258 spec slices; these child issues make them independently queueable. They have not-before
2026-11-02T00:00Zso the design and related routing gates can settle; packets explicitly say to park rather than guess if a prerequisite remains open.repo-health:v1:fix:developing-today/code:issue:3808repo-health:v1:fix:developing-today/code:issue:3809repo-health:v1:fix:developing-today/code:issue:3811repo-health:v1:fix:developing-today/code:issue:3818repo-health:v1:fix:developing-today/code:issue:3810Shared-world execution remains on existing #2271 (task 5598, PR #3726 open) and #2284 work; do not duplicate it or promise production portability yet. No shipped pkgs/id behavior changed in this synthesis.
docs(id): design serverless v1 (#2046)
dezren39 commentedon Nov 1, 2026
Design summary
binding_idstore.Design note: doc/2026-11-01_design_id2046.md
PR: #3827 (docs-only; does not close this issue)
Phased plan
Each phase is a separate reviewable PR. The PoC is reviewed before permanent code builds on it.
Questions for Drew
No other Drew ruling is needed to start the PoC or account/binding work. Challenge/rate-limit thresholds are operational tuning; jurisdiction placement is gated by #2283, not a Drew question here.
dezren39 commentedon Nov 1, 2026
🤖 Agent note · done (triaged)
7 remaining items
dezren39 commentedon Nov 3, 2026
agent-note:v1
state: triaged (coverage pass)
Coverage pass 2026-11-03: reviewed in the fleet-wide per-issue pass (drift / overlap / already-handled / stale / blockers / ordering). Verdict: still live; queued in repo-health-code-pilot as triage at priority 30 (priority/none). If this is already handled at current main, the triage closes it with evidence; if it needs splitting, the triage files the split.
Found via: coverage pass 2026-11-03
dezren39 commentedon Nov 3, 2026
🤖 Agent note · done (triaged — already done, closing with evidence)
doc/2026-11-01_design_id2046.mdlanded via PR design(id): #2046 Workers v1 architecture #3827, MERGED 2026-11-02; verified present at current main (blob sha 20bf928fd6647f8dcea4209a98de68c8683fa7db).