Files
DBAdmin/labs_os_review_full_document.md
T
Paweł Domański ae2bae964c Jun 2, 2026, 1:29 PM
2026-06-02 11:29:19 +00:00

146 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Labs-OS Review — What's Strong, What's Hollow, and the Plan
## TL;DR
Labs-OS has a strong skeleton and a strong thesis, but the body is mostly mannequin. The Compass strategy doc (`docs/labs-os-in-arr-playbook.md`) is the most valuable artifact in the repo — it's a real product. The shell you love is real. The Convex schema is real. Most everything in between is decorative placeholder text. Out of ~30 tab pages across six modules, only one mutation actually persists user data (Compass → diagnosis → `updateCompass`). Every other “workbench” is a form with no submit handler and a literal `<unused: agentSpecs.userByProject…>` string rendered as a TODO.
That mismatch — undeniable strategy, undeniable shell, hollow middle — is the single biggest fix. The good news: it's also the most demoable fix on a livestream.
## What's already working (don't disturb)
- Strategy spine is excellent. $1M ARR math, six-module decomposition, seven-stage roadmap, gate-before-tool discipline, Compass-as-command-layer thesis. This is the actual moat.
- Shell is taste-forward. Matrix-canvas + grid + perspective + side-brand feel + floating shell + accent rings = a recognizable Clearmud silhouette. Light/dark theme toggles are good.
- Schema is professional. Convex `schema.ts` has proper types/indexes for `projects`, `projectMemberships`, `compassDecisions`, `stageGates`, `evidenceSignals`, `revenueGoals`, `experiments`. This is much further along than the UI suggests.
- Navigation invariants are written down. README + Architecture / navigation principles + the three docs in `/docs` are clearly product-canon. Future passes should respect them.
- Project-first context model. `App.tsx:140-169` (`compassFor`, `dashboardFor`, `compassNudges`) wires the active project into every module's text — that's the right pattern. Just under-realized.
## The honest gaps
I'll group these so the plan in the next section maps cleanly.
### Gap 1: hollow workspaces (the biggest one)
`tabWorkspaces` in `App.tsx:264-563` defines 24 workbenches (Offer, Prototype, Onboarding, Feedback, Builder, Ops, Governance, Memory, Canvas, Channels, Campaigns, Commerce, Channels, Product/Model, Pricing, Pipeline, Conversion, Retention, Metrics, Experiments, Signals, Reviews, Proof Vault). Each renders a form + checklist + outputs + a `mutationNeed` TODO string. None of them save anything. The payload of “what this tab should do” lives in text, not code. That gap reads worse on stream than just having fewer modules.
### Gap 2: no "vibe coding" surface
The brand is "vibe coding to $1M ARR." But there's no AI surface in the app:
- No prompt scratchpad / agent console.
- No "ship this next" generator that takes the current stage + missing gate and outputs a brief Claude/Codex/Cursor can run.
- No record of what was vibe-coded today (which is exactly the kind of artifact that becomes Distribution content for tomorrow).
- The Agents module is about agents conceptually, not a place where agents do work.
This is the unique angle that separates Labs-OS from "yet another founder dashboard." It's currently invisible.
### Gap 3: nothing exits the OS
Founders pay for artifacts they can take to a customer call, an investor, an outbound message, a stream. Labs-OS has zero exports: no PDF pitch packet, no copy-to-clipboard pricing card, no "weekly review" markdown, no shareable read-only project page, no proof-vault download. Every workbench should end in an artifact.
### Gap 4: structurally monolithic code
- `src/App.tsx` is 838 lines, one file = types, data tables (`modules`, `moduleTabs`, `roadmap`, `dashboardData`, `compassNudges`, `tabWorkspaces`, `stageLabels`), all components (`MatrixBackground`, `ThemeToggle`, `CompassNudge`, `CompassWorkspace`, `CompassCore`, `CompassTabWorkspace`, `ModuleDashboard`, `ModuleDashboardOverview`, `ModuleCard`, five module workbenches, `AuthButton`, `ProjectLauncher`, `ProjectContextRail`, `SystemLoad`), `App()`.
- `src/index.css` is 198 lines, one file, no Tailwind utilities used despite the import (`@import "tailwindcss"` is the only Tailwind reference).
- Stage-key enum is duplicated across `schema.ts`, `projects.ts`, `evidence.ts`, and `App.tsx` — four sources of truth for the same union.
- A leftover top-level `compassState` constant at `App.tsx:116125` is shadowed by `compassFor(project)` inside `CompassWorkspace` and is effectively dead.
The shell pattern is clean, but as features land, this single-file architecture will fight back. Refactor before ramping content, not during.
### Gap 5: auth is ship-blocking
`@convex-dev/auth` is wired (`convex/auth.ts`, `convex/http.ts`, `convex/auth.config.ts`), and the React client correctly falls back to demo mode when `VITE_CONVEX_URL` is missing (`src/lib/convex.ts:5`). But Google OAuth client ID/secret aren't configured in any Convex env. Until OAuth lands, every viewer who creates a project on stream is creating a public template, not their own private project. That's both a privacy bug and a retention bug — viewers can't take their work out with them.
### Gap 6: distribution loops aren't built into the product
You're branding "Labs in Public." The product offers no:
- Public read-only project share URL (schema only has `private | template`, not `public`).
- "Stream replay" view of decisions/signals that landed during a session.
- Embeddable ARR meter / progress chart that streamers (you, eventually viewers) can drop into stream overlays.
- Templates seeded for stream viewers to fork from ("Day 12 starter project").
These would compound the livestream into the product, which compounds the product into more livestream content.
### Gap 7: small but real polish issues
- Top-bar window-controls dots (`App.tsx:835``.window-btn-close/.minimize/.maximize`) are decorative — viewers will click them. Either wire them up (close → launcher / minimize → fullscreen workspace / maximize → toggle right rail) or remove them.
- `SystemModal` search (`App.tsx:774`) only searches static module/tab labels. Once entities exist, it should search projects, signals, experiments, decisions.
- `module` is used both for variable name and shadows nothing problematic but reads poorly; e.g. `App.tsx:670, 698, 770` most `module = modules.find(...)` — minor but worth a rename to `currentModule` or `mod`.
- No cmd-K palette. For an "OS" framing, this is the single most expected affordance.
- Window resize / theme toggle / right rail toggle don't have keyboard shortcuts.
- `MatrixBackground` recreates the canvas on every component remount. Fine for now, but moving it to a stable layout root prevents the reflow and state flicker across page transitions.
## What I'd actually do (prioritized plan)
I split this into four phases keyed to the livestream cadence: next stream, next two streams, month-one, post-launch. The structural-integrity rules (matrix bg, shell, left rail, top tabs, right rail) are preserved across all phases — every change happens inside the workspace area or as a separate route.
### Phase 0 — code hygiene (1 stream, low-glory but unlocks everything)
Demoable as: "Day N refactor session — Claude restructures Labs-OS so each module is its own file, then we commit live."
1. Split `App.tsx` into `src/shell/`, `src/modules/{compass,experience,agents,distribution,revenue,evidence}/`, `src/data/`, `src/types.ts`. Each module gets a `dashboard.tsx` and one file per tab. Static tables (`tabWorkspaces`, `compassNudges`, `dashboardData`) move into `src/data/`.
2. Split `index.css` into `shell.css`, `tokens.css`, and per-module CSS files. Don't migrate to Tailwind utilities — your hand-tuned tokens are a feature, just modularize.
3. Single source of truth for `stageKey` enum. Export from `convex/schema.ts` (or a shared `convex/types.ts`) and import in the React side via `convex/generated` (or `convex_generated`, depending on generator naming in the project).
4. Delete `compassState` const at `App.tsx:116`. Rename shadowing module variables.
5. Add `CLAUDE.md` documenting the navigation invariants and structural-integrity rules so future Claude/Codex passes don't break them. (You can have me draft this — it's short, ~80 lines.)
### Phase 1 — make ONE module fully real (23 streams)
Pick Evidence as the first fully-real module. Reasoning: it has the cleanest schema (`evidenceSignals`, `experiments` already exist), the best on-stream optics ("watch us turn a customer quote into a stage gate"), and it's the module the rest of the product depends on (gates can't move without Evidence).
For the first vertical slice:
1. Wire Evidence → Signals to Convex. Replace the placeholder `EvidenceLabWorkbench` form with the real `evidence.addSignal` mutation already in `convex/evidence.ts:37`. Show signals listed below the form in real time via `useQuery(api.evidence.listSignals)`.
2. Wire Compass → Milestones to `stageGates`. Currently a static checklist (`App.tsx:653`); the schema already has `stageGates`. Add `convex/stageGates.ts` with `listByProject`, `setStatus`, and a one-time seeder per project. When a gate flips to `complete`, update `evidenceCount` and `missingGate` on the project.
3. Wire Compass → Decision Log to `compassDecisions`. Add `compassDecisions.create` / `listByProject` mutations.
4. First export. Compass → Today → "Generate brief" button produces a Claude/Codex-ready prompt that bakes in stage, ICP, pain thesis, missing gate, today's action, recent signals. Click → copy. This is the vibe coding bridge — Labs-OS becomes the prompt source-of-truth for the actual coding tool.
After this phase, one whole module is undeniably real. That's worth more than 5 modules with placeholder forms.
### Phase 2 — configure Google OAuth
Unblock real user accounts first so any work after this saves to private projects, not demo templates. Required eventually; could go before or after refactor.
### Phase 3 — build the vibe-coding surface
Skip ahead and design the workbench module that owns the brand promise. Highest narrative payoff but builds on top of the hollow foundation.
### Phase 4 — polish & livestream amplifiers
I'd lean Option A (because Agents is already crowded and "Workbench" is a recognizable second-rail concept), but it's a real call.
- Wire window-controls dots OR remove them.
- Embed `current ARR` project widget for stream overlays.
- "Day X" stamp baked into Compass → Today (auto-counts from stream-1 date).
- Lightweight viewer telemetry (PostHog or Convex analytics) + "Live now" panel showing how many viewer-projects are at each stage.
- Per-stage starter templates (Stage 0 starter, Stage 1 starter…) so a viewer can fork into the right starting point on the first stream they watch.
## What I'd ship first (if you only do one thing this week)
Phase 0 + Phase 1 step 1. Split the monolith, wire Evidence → Signals to Convex, and watch a real signal save during a stream. That single, small thing — a customer quote landing in the proof vault and showing up in real time on the right rail — proves the whole "Compass before tools, evidence beats vibes" thesis on camera. Everything after that is easier to sell.
## A few questions before I start coding
- [ ] First move
- [ ] Workbench shape
- [ ] Context depth
- [x] Submit →
Where should we start? I'd lean Phase 0 + Phase 1 step 1 first (refactor + wire Evidence → Signals live).
1. **Phase 0: refactor first (recommended)**
Split `App.tsx` and `index.css` into modules, single-source the `stageKey` enum, add `CLAUDE.md`. One stream of unglamorous but essential restructuring before any features.
2. **Phase 1: wire Evidence to Convex**
Skip the refactor and go straight to making one module real. Higher demo payoff today, but the monolith will fight back as we add modules.
3. **Phase 2: configure Google OAuth**
Unblock real user accounts first so any work after this saves to private projects, not demo templates. Required eventually; could go before or after refactor.
4. **Phase 3: build the vibe-coding surface**
Skip ahead and design the workbench module that owns the brand promise. Highest narrative payoff but builds on top of the hollow foundation.
5. Type something.
6. Chat about this.