Projects — launch redesign

A total redesign of /projects for the day the first real user arrives, on the question Khoa set: what would a world-class small team have here if they were about to launch? Grounded in the real source on origin/develop, carrying the War Room language Adam has shipped, and organised around one conviction: a pre-launch cockpit's job is to answer "can this go in front of a user, and what needs me today?" — not to catalogue where files live.

Start here

The board

Needs-you queue first, then Products, Clients and Lab — every card wearing its launch gates and live-agent state.

Open →
The core page

Product detail

The product's admin: Today, Users, Issues lead; Ship, Assets, Setup behind them — under a persistent readiness verdict.

Open →
Same shape, different gates

Client detail

Pulse, Deliverables, Relationship, Setup. Scoped → Delivered → Accepted → Invoiced replaces the launch gates.

Open →

What is actually there today

Read from source, not from the running page — my identity cannot reach the live app, so this inventory comes from CockpitProjectsPage.tsx, CockpitProjectDetailPage.tsx and cockpitProjects.ts on origin/develop:

The diagnosis

The current page is organised by where data lives — one tab per storage system. Nobody's day works like that. The morning question is "what needs me?", the pre-launch question is "can this go in front of a user?", and neither has a home. The eleven tabs answer a question nobody asks: "where do we keep things?"

The redesign in five moves

1 · Needs-you leads every screen, oldest first

The pattern every operations tool converges on — Sentry, PagerDuty, Linear's triage: open with the queue of things that will not move without a human, sorted by how long they've waited, not how recently they arrived. Newest-first is how a four-day-old decision hides under fresh chatter. The OwnerMind Kill/Go sitting at the top of the mock, at 4d, is the honest example.

2 · Launch gates replace vibes

Borrowed from how serious teams pre-flight a release (Vercel's checks, Stripe's go-live checklist): five named gates per product — Auth, Golden path, Billing, Observability, Support — each ready / at-risk / failing / unknown. Unknown is deliberately distinct from failing: "never measured" and "known bad" are different facts, and a single "78% ready" number hides exactly the thing that bites. Each gate is one plain-English sentence — "a stuck user can reach a human" — with a named owner, because a gate nobody owns is a wish.

3 · Eleven tabs become six surfaces named after the operator's questions

New surfaceThe question it answersAbsorbs
TodayWho joined, what broke, how's money — this morningOverview, Sessions (activity)
UsersWho is on this, free or premium, who's slippingnet-new — lived in a separate admin before
IssuesWhat broke, for whom — with the replaynet-new — errors + session recordings
ShipCan this go in front of a user?Environments, gates, PRs, Team, Tasks
AssetsEverything the project producedGallery, Docs, Storage, Datasets
SetupWiring — touched rarely, on purposeConnections, Credentials, Settings

Assets is the strongest collapse: Gallery, Docs, Storage and Datasets were four places to look for "the thing this project made". Setup is the deliberate demotion — credentials and connections matter, but a launch team touches them monthly, not daily, so they don't deserve four of eleven top-level slots.

4 · The rail answers "do I need to look today?"

Khoa's requirement: every product one click away, checked daily. But a shortcut alone still costs seven clicks on a quiet day. So each product pin on the rail carries its state — amber dot: something needs you; teal: agents live, nothing needed; dimmed: quiet. The daily check becomes a glance at the rail, and clicking is only for the pins that ask. State is in the aria-label too, never colour alone.

5 · One product with the War Room, not a neighbour

Adam has shipped the Working Set, lanes and the live-browser runtime we designed together. This surface reuses them rather than paralleling them: the working set shown on a product's Pulse is the War Room working set — pin here, it's pinned there. "Open in War Room" is first-class on every project. The violet lane accent is carried over so held-by-you means the same thing on both surfaces. One vocabulary, one product.

The operator's page, not the developer's — rework, 30 Jul

Khoa's read of the first draft: it looked like a development section, when the daily questions are "did any users join today, any issues arise, can I watch the recording, free or premium?" He is right, and it aligns with the locked Cockpit IA decision that put owner-admin inside the unified cockpit — so the product page here is the product's admin. No separate per-product admin panels: for one operator, seven admins is seven more places to check.

Product-specific tables — the frame doesn't pretend products are identical

Khoa's example: Conversite has templates — names, prices, who bought what. That cannot be generic, and forcing it into shared "metrics" flattens exactly the data an operator cares about. So each product declares one domain surface the shared frame renders without understanding: Conversite → Templates (catalog + who-owns-what), Greenpen → Projects, Keystack → Tenants & work orders, OwnerMind → Assessments, CourseVenture → Courses & cohorts. This extends a seam that already exists on develop — productSurfaces.ts declares per-product deploy surfaces behind one function, with a comment saying the long-term home is a backend read-model. Domain tables are the same pattern, one level up. Cross-links keep it honest: today's +$29 MRR on the Today tab is r.singh's Storefront purchase in Templates — same number, same source, two views.

Build implication, stated early: these surfaces need products to emit a small event stream — signup (with plan and source), error groups with a session-replay id, plan state from billing, and one declared domain table (catalog + ownership) per product. That per-product telemetry contract is the real work behind this page; the design is the argument for paying it.

Patterns borrowed, and from where

Accessibility, concretely

Honest limits

Grounded in source, not the running app. My identity cannot reach /projects (every route redirects to /model-defaults), so this is built from the develop source plus the section/tab inventory above. Real data shapes — what a populated Gallery actually holds, what Sessions really lists — are designed, not captured. When my cockpit access lands (PR #102, pending activation), the first job is a fidelity pass against the live surface, exactly as OwnerMind Desk got. Roster, figures and timestamps in the mock are illustrative.

Sana · design · 30 Jul 2026 · clickable prototype, not a build spec · sections and current-state inventory from origin/develop