โ† Back to roadmap/

Markdown Viewer   ๐Ÿฐ


Launch roadmap

Re-cut of the 63-item backlog around one question: what is the shortest path to a product worth showing strangers, and what comes after it.

Order is unchanged from the previous revision. This revision re-costs the work against a real team, corrects estimates that assumed greenfield where code already exists, and adds per-item specs and acceptance criteria.


Team model

Costing assumes a standing team of five:

Role Count Reads as
Backend 2 Supabase schema, RLS, migrations, triggers, API routes, Workers
Frontend 2 React Server Components, forms, feeds, client state, design system
Designer 1 Flows, specs, design-system extensions, QA against the built thing
Delivery 4 eng Designer is not a parallel build stream

Units. eng-wks is one engineer working one week. cal-wks is calendar time for the whole team on that item. They differ because most items do not split four ways.

Parallelism factor. Each item carries how many engineers it genuinely absorbs:

The designer is a lead indicator, not a lane. Design for item N+1 happens while engineering builds item N. Where an item is marked design-gated, engineering cannot start until the flows exist. Those are the items that stall a team when design runs late โ€” the designer's queue must lead the build queue by roughly one item throughout.

Overheads. All figures below are build-only. Add 30% for review, QA, the bug tail and deployment. The Calendar section applies this; per-item tables do not.


Corrections to the previous revision

Four estimates were wrong, and one sizing convention was.

Item Was Now Why
33 Search L (4 wks) M (2 wks) api/search/route.ts and queries/search.ts already exist โ€” ilike across profiles, organisations, projects, articles. Not greenfield
35 Transactional email L (4 wks) M (2.5 wks) lib/email/ has a working Resend client, types and a user-email service. Domain auth, templates and preference centre remain
25 Content reporting S (0.5) S (1 wk) Split-out report button still needs a table, RLS, four entry points and an outcome notice. 0.5 was optimistic
08 Legal pages M (1.5) M (1 wk) In flight and further along than the backlog records

Sizing convention. The previous revision used S=0.5, M=1.5, L=4, XL=9, XXL=18 dev-weeks โ€” roughly a third of the source backlog's own scale (S=2, M=3, L=6, XL=12, XXL=20). That gap was never reconciled and is the single largest source of disagreement between the two documents.

This revision keeps the compressed scale, for one defensible reason: the backlog's scale prices items for a team with no context on this codebase, and this team has 798 source files and 76 migrations of accumulated context. Where the two scales disagree, the backlog's figure is the outside view and should be treated as the pessimistic bound. The Calendar section carries both.


Where we are

Articles, projects, comments, organisations, publish and hard-delete flows, automated moderation, mobile. That is a working content platform.

Verified against the tree, three things the backlog lists as unstarted are partly built:

The gap between "works" and "survives public traffic" is narrower than 63 items suggest โ€” but it is not zero, and the items that close it are currently scattered across Phase 2.


Launch 0 โ€” public beta

~6 eng-wks ยท ~3 cal-wks. Everything here is either a legal obligation or a thing that breaks the moment the platform is public. Nothing here is optional and nothing else belongs.

# Item Size eng-wks Par Owner Why it can't wait
08 Legal pages (wip) M 1.0 ร—1 FE ToS, Privacy, Cookie. No EU signups without them
15 Feed filters (wip) S 0.5 ร—1 FE Already in flight โ€” finish it
28 Security hardening M 1.5 ร—2 BE+FE Turnstile on signup. Without it, bot floods in week one
27 Rate limiting & monitoring M 1.5 ร—1 BE Sentry and rate limits. You need to see what breaks
30 SEO & metadata S 0.5 ร—1 FE OG cards, sitemap. A content platform nobody can share isn't launched
25 Content reporting โ€” report button only S 1.0 ร—2 BE+FE DSA notice-and-action route

Specs

08 โ€” Legal pages. Three static routes plus a consent modal. Cookie consent must gate analytics scripts, not merely record a preference โ€” a banner that sets a flag while GTM has already fired is not consent. Consent state in a first-party cookie readable server-side, so the modal does not flash on every load. Designer: modal states and the mobile treatment.

15 โ€” Feed filters. In flight on feat/tozn-441-feed-filters. Remaining: finish the uncommitted FeedFilters.tsx / InputSelectBadge.tsx work, then resolve the filter-detection bug already documented in docs/plans/feed-ssr-unfiltered.md โ€” Object.keys(filters).length > 0 counts keys whose value is undefined, so ?published=abc reads as a filtered request.

28 โ€” Security hardening. Turnstile on signup, login and password reset. XSS sanitation of all TipTap rich-text output โ€” server-side on write, never client-side only. Cloudflare Pro bot protections. Backend owns sanitation and token verification; frontend owns widget placement and challenge-failure states.

27 โ€” Rate limiting & monitoring. Sentry with source maps through the OpenNext build. Rate limits on auth, write and upload routes, keyed per user and per IP โ€” Workers KV or Durable Objects, not in-memory, because Workers isolates do not share state. Analytics/GTM behind the #08 consent gate.

30 โ€” SEO & metadata. generateMetadata on every public route, OG images for articles and projects, sitemap.xml from published content, robots.txt, PWA manifest. Must not regress the static-prerender path โ€” a cookies() call added here makes public pages dynamic.

25 โ€” Content reporting (button only). reports table, RLS allowing insert-by-any- authenticated-user and read-by-staff-only, report action on articles, projects, comments and profiles, reason taxonomy, duplicate suppression per reporter per object. Ships without a queue.

On splitting #25. The full item is M and includes a moderation queue that assumes the admin console exists. The legal obligation is narrower: a route for users to flag illegal content. A report button writing to a table, plus a person reading it, discharges that. The queue waits for #32.

Acceptance

Launch 0 is done when: an EU visitor can accept or reject cookies and rejection actually suppresses analytics; a bot cannot mass-register; an error in production reaches Sentry with a readable stack; a shared article renders a correct OG card; and any logged-in user can report any piece of content.

Deliberately out: notifications, search, i18n, versioning, payments. None block a beta, and three are XL.

Reordering note. Items 27, 28 and 30 sit in Phase 2 in the source backlog. Turnstile and error monitoring are launch-day infrastructure, not month-six polish. Moving them up is the single most consequential change in this document.

Why ~3 cal-wks and not 1.5. Six eng-wks across four engineers looks like 1.5 weeks. It is not: #08 and #15 are single-owner frontend items that serialise against each other, and #27 is single-owner backend. The critical path is FE1 running 08 โ†’ 15 โ†’ 30 at two weeks, plus integration and the consent/analytics interaction. Three weeks is the honest figure.


Launch 1 โ€” retention

~19 eng-wks ยท ~7 cal-wks. Launch 0 gets people in the door. This is what stops them leaving. Ordered by retention impact per eng-week.

Tier A โ€” a reason to come back

# Item Size eng-wks Par Owner Note
35 Transactional email M 2.5 ร—1 BE Must come first; 16 and 26 both sit on it
16 Notifications, first release L 4.0 ร—2 BE+FE The single biggest return-visit driver
42 Article reactions S 0.5 ร—1 FE Cheapest engagement signal, and it feeds ranking later
38 Notes & bookmarks M 1.5 ร—2 BE+FE A personal library makes the platform sticky

Tier B โ€” a reason to bring others

# Item Size eng-wks Par Owner Note
26 User-to-user invites L 4.0 ร—2 BE+FE The growth loop; alpha badges already prime it
39 Connections & blocking M 2.0 ร—2 BE+FE The social graph; blocking is a safety floor
40 Privacy settings M 1.5 ร—1 FE Depends on 39

Tier C โ€” findability

# Item Size eng-wks Par Owner Note
33 Search M 2.0 ร—2 BE+FE Re-sized down โ€” partial build exists

Specs

35 โ€” Transactional email. Builds on the existing Resend client. Remaining: SPF/DKIM/DMARC on the sending domain, a template system beyond the single hard-coded ID in lib/email/templates.ts, plain-text fallbacks, per-type routing with unsubscribe and a preference centre, bounce and complaint suppression, transactional/marketing separation with consent records. Domain warm-up is calendar time, not work โ€” start DNS in Launch 0 so reputation is building before #16 needs it.

16 โ€” Notifications, first release. Five live groups only: posts, projects, articles, organisation membership, own membership. Bell with unread count, dropdown, dedicated page, read/seen state. Cross-account addressing so a notification belongs to an organisation or a person โ€” this is the schema decision that is expensive to retrofit; get it right now. Interval-polled count, realtime deferred. Registration hooks so later features add types without a migration. Design-gated: bell, panel, empty and overflow states.

42 โ€” Article reactions. Extends the existing reactions table. Optimistic UI, per-user uniqueness enforced in the database rather than the client.

38 โ€” Notes & bookmarks. Extends the existing bookmarks table with private notes. Personal library view with filtering. RLS: owner-only read and write, no exceptions.

26 โ€” User-to-user invites. Per-user invite links with attribution, acceptance bound at signup, quota and abuse limits, inviter-facing status list. Depends on #35 for delivery. Attribution must survive the auth round trip โ€” cookie set pre-signup, consumed in the callback.

39 โ€” Connections & blocking. Rewire the existing connection system into profile pages and re-enable blocking. Blocking must be enforced in RLS or shared query helpers, not per-call โ€” every feed, search and comment path has to honour it, and a per-call check will be missed somewhere. This is the item most likely to overrun.

40 โ€” Privacy settings. Settings area binding visibility rules to the #39 enforcement layer. Adds no new enforcement of its own.

33 โ€” Search. Replace ilike with Postgres full-text: tsvector columns, GIN indexes, websearch_to_tsquery, trigger-maintained on write. Ranking, filters, result-type tabs, permission-aware results honouring drafts and #39 blocks. Re-index hooks for later content types. No external search infrastructure at this volume.

Build order

Unchanged: 35 โ†’ 16 โ†’ 42 โ†’ 26 โ†’ 39 โ†’ 40 โ†’ 38 โ†’ 33.

Two streams, as before:

BE1+FE1  35 โ”€โ”€โ”€โ”€ 16 โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ 26 โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
BE2+FE2       42 โ”€โ”€ 38 โ”€โ”€ 39 โ”€โ”€ 40 โ”€โ”€ 33
Design   16 โ”€โ”€ 26 โ”€โ”€ 39/40 โ”€โ”€ 33

Tier C sits last by intent. At current content volume browsing works and feed filters cover it; ship search when the archive is large enough that browsing fails.

Acceptance

A user who leaves for a week receives a reason to return that is not an email blast; blocking holds across every surface including search; and an invited user's attribution survives signup.


Launch 2 โ€” learning

~11 eng-wks ยท ~5 cal-wks. Chosen over the creator-economy track. Reasoning below.

12 Versioning (M)
   โ”œโ”€โ”€ 13 Articles โ€” reviews (M)
   โ””โ”€โ”€ 23 Educational Resources (L) โ†’ 52 Quizzes (L)
# Item Size eng-wks Par Owner Note
12 Content versioning M 1.5 ร—1 BE Blocks everything below it
23 Educational Resources L 4.0 ร—3 BE+FE Widest item in this launch
13 Articles โ€” reviews M 2.0 ร—2 BE+FE Binds to a version, not to a row
52 Quizzes L 3.5 ร—2 BE+FE Anti-cheat before PRG is on the line

Specs

12 โ€” Content versioning. Immutable snapshot on every publish and republish. History and diff views. Reviews, citations and later PRG rewards bind to a version_id. Restore from an earlier version. Interaction with retention windows and hard deletion โ€” a version cannot outlive a GDPR erasure. Storage and pruning policy, because unbounded snapshots of TipTap JSON grow fast.

Versioning goes first, and this is not negotiable. Reviews and citations bind to a specific version of a piece, not to whatever the author edits it into afterwards. Ship reviews before versioning and every review collected becomes unbindable โ€” retrofitting means invalidating them. #12 is M. Doing it after is not.

23 โ€” Educational Resources. Category/subcategory hierarchy and subject pages, resource authoring, Foundation curation workflow, reference and citation handling. Curation is Foundation-run here; the DAO inclusion queue is Phase 4. Design-gated โ€” the heaviest design load in the roadmap, and the designer must lead by two items, not one.

13 โ€” Articles โ€” reviews. Structured peer review against a pinned version. Reviewer eligibility, review lifecycle, public display. The attestation surface Phase 4 later pays PRG against โ€” keep the review record shaped so an attestor signature can attach without a migration.

52 โ€” Quizzes. Authoring, question bank, answer storage, taking, scoring, attempt history, per-learner progress. Answers never reach the client. Scoring is server-side, and the question payload excludes the correct answer โ€” retrofitting that after Learn2Earn pays PRG means re-issuing every grade.

Why learning before the creator economy

The alternative track is 19 โ†’ 21 โ†’ 20 โ†’ 22 (Stripe, tipping, funding, paywalls) at roughly 31 eng-weeks, and 20/21/22 all want the admin console (#32, XL) underneath them for refunds and disputes.

Learning is ~3ร— cheaper, differentiates the platform, matches the conservation positioning, and carries no regulatory surface. Its weakness is that it pays nobody.

The hedge: after the learning track, ship 19 (Stripe) โ†’ 21 (Tipping) as a narrow slice โ€” about 13 further eng-weeks. That proves the money rail works and gives contributors a reason to show up, without committing to funding rounds, paywalls, tax reporting and dispute handling before anyone has asked for them.

Stripe Connect onboarding is the long pole inside #19, and it is partly external: KYC verification states are Stripe's timeline, not yours.

Total for learning plus tipping: ~24 eng-weeks.


Calendar

Build-only figures above, +30% overhead applied, four engineers.

Milestone eng-wks +30% Compressed scale Backlog scale
Launch 0 โ€” public beta 6 7.8 ~3 wks ~6 wks
+ Launch 1 โ€” retention 25 32.5 ~10 wks ~20 wks
+ Launch 2 โ€” learning 36 46.8 ~15 wks ~30 wks
+ Stripe & tipping 49 63.7 ~21 wks ~40 wks

Read the two right-hand columns as a range, not a choice. The compressed column assumes the team keeps its current context and nobody leaves. The backlog column is the outside view. Plan against the compressed figure, commit externally against the backlog one.

Calendar time does not scale with headcount inside a launch. Launch 0 is ~3 calendar weeks with four engineers and ~6 with one โ€” but it is also ~3 with eight, because the critical path is one frontend engineer running three serialised items. Launch 1 parallelises best: two clean streams for most of its length.

The designer is the hidden critical path. Items 16, 23, 26, 39/40 and 52 are design-gated. One designer feeding four engineers works only while the design queue leads by a full item. It does not survive Launch 2, where #23 alone is a multi-week design effort โ€” that is the point to either buy contract design or accept that engineering idles.


Explicitly not next

Named here so they stop occupying planning attention. Order unchanged.

# Item Why not yet
43 Recommendation & ranking (XXL) Needs a user base and engagement history that don't exist yet
45 Messaging (XL) Large, and DM abuse surface is real operational load
46 Notifications second pass (XL) Wait until the first pass has told you what's missing
34 Internationalisation (XL) See below โ€” decide, don't drift
32 Admin console (XL) Needed before funding or paywalls; not before them
24 Open Calls (XL) Depends on #32 and #16
47โ€“63 Token economy Start #48 when token work gets a real date, not before

Three standing decisions

i18n (#34). Its cost scales with shipped surface area, so every month it waits it gets more expensive. Either commit to it in the next twelve months or accept the retrofit consciously โ€” what is expensive is leaving it undecided while the surface grows. Concretely: the cheap mitigation is a string-extraction discipline from now on, which costs little and preserves the option.

Regulatory assessment (#48). A 4โ€“12 week external gate on ~85 eng-weeks of Phase 4 work. Irrelevant until token work has a date. Fatal if started at Phase 4 time rather than before it. The moment the token economy gets a quarter, this starts.

Tokenomics (#47). The published parameters let $OZN be minted below intended cost: tipping earns 10 PRG per US$1 while 100 PRG staked wins 1 $OZN for 50 PRG, so self-dealing between accounts mints $OZN for the transaction fee alone. This is a live problem in a public document, not a future build task โ€” the white paper is already published with these figures. Fixing the parameters is cheap now and expensive once contracts are audited.


Summary

Three constraints decide whether those numbers hold: the designer's queue must lead the build queue throughout; blocking (#39) must be enforced in one place rather than per-call; and versioning (#12) must land before reviews. Everything beyond that is a decision for a team that has users.