What's shipped, what to do next — prioritized by what unblocks others, what's needed before outside users, and what widens the category. Honest about the debt.
The v1 loop is built, deployed, and verified live end-to-end.
*.protocontent.app content routingnpx bridge → real publish verifiedBuilt, merged, and verified live this pass (PRs 1–7 on GitHub).
sandbox opaque origin?k=).protocontent/ gitignore conventionCheap moves that either unblock distribution or close a real hole.
Done — live as protocontent@0.1.0 (the name was free), so npx protocontent
works for anyone. Note: a client-side minimumReleaseAge npm policy can delay installs.
Verified — no hole. ensureSpace rejects a publish to another project's space with 403;
list/unpublish/keep are guarded by requireOwnedSpace. Confirmed live: a second project gets 403 on
publish/list/unpublish while the owner keeps full access. (Artifact reads stay public by capability-URL design — see #5.)
The bridge has client-side rails, but the Worker API has none. Add request/file size limits and
basic per-token rate limits on /v1/publish and /v1/projects (anonymous mint is unauthenticated).
The line between "personal tool" and "service other people put content on."
Done: artifacts now serve on *.protocontent.app — a separate registrable domain
from the .com control plane, so untrusted HTML can't share cookies with it. Legacy .com
links 301→.app. Remaining: submit protocontent.app to the Public Suffix List for
inter-artifact isolation (review takes weeks — do it before sensitive third-party content).
The session index currently shows everything to anyone with the (unguessable) subdomain. Add an optional private flag / token gate for the index — it's the one URL that exposes a whole thread at once.
Phishing/malware scanning on upload, a report/takedown path, and a kill switch. Unavoidable once the link is public and anyone can mint a project.
Measure publish/serve latency and load-test the live push + D1/R2 under concurrency before real
traffic. The first run already paid off. A 2 KB→2 MB sweep ruled out payload (publish ~340→~730 ms,
sub-linear). The real spike was a Durable Object cold start on the first publish to an idle space (~700 ms,
because publish awaited the live-push notify). Fixed & shipped via ctx.waitUntil —
cold penalty ~700 ms → ~130 ms. Warm publish p50 ~335 ms, serve ~165 ms, mint ~50 ms.
Next: concurrent throughput, R2/D1 ceilings, a CI perf gate.
The general primitive is already MIME-agnostic — these are the views worth building.
The one type that needs a server-side renderer (raw .md shows as plain text). Images
& PDFs already serve natively.
Serving works; add thumbnails + a lightbox so a space full of screenshots reads as a gallery, not a file list.
history already tracks versions — add a visual diff between two versions of an artifact.
A durable landing page listing all your spaces across threads — the "project" half of the model that exists in the schema but has no view yet.
Named projects, shared spaces, Workers OAuth provider — when you outgrow anonymous tokens.
The build was the cheap part. This is what answers the actual question.
Show HN, an awesome-mcp-servers PR, MCP discussions, X — lead every post with a 30-second
GIF of the phone-live-view moment.
Frame it as "the missing 'upload it' step from The Unreasonable Effectiveness of HTML." That single resonance is product validation and the hire signal at once.