Skynet — Delivery Plan (sequence, gates, cards — no dates)
For: Agon, Sead, Sven (CTO), Vince. Companion to: the functional design (what), the workflow source map (how work flows), the architecture and deployment design (how it is built and run). The executable text of every S1 card is in skynet-task-specs.md; this plan is the order, the gates and the load.
1. Rules of this plan
- Delivered = 100 % complete. The project is done when every workflow in the source map runs natively in Skynet, the standalone apps are retired, ClickUp is replaced board by board, and the app is SaaS-ready. Nothing before that is "the delivery".
- No calendar dates. Work is a sequence of slices (S1–S5) and, inside a slice, waves. A wave starts only when the previous wave's gate is true. A gate that is not met is a stop, not a slip.
- Best implementation, no quick fixes. A card that would need a shortcut to close is split or re-planned, never closed short. Discovered work becomes a card before its code lands.
- Load: one card, one owner; sizes S ≤ ½ day, M ≈ 1 day, L ≈ 2 days; no person carries more than 2 days per wave (a wave ≈ two working days of effort per person, not a date). Loads below are computed from the card JSON.
- Three lanes: A = Agon (platform, deploy, boxes, later Intelligence), V = Vince (shell, Production, bindings, later Studio UI), S = Sead (core auth, contracts, creative code, read layer, readback, bridge, later Workspace).
2. Slice sequence and entry gates
| Slice | Content | Entry gate ("what must be true before it starts") |
|---|---|---|
| S1 Unified app + closed loop | One app on server.ecomprofits.io; Production native at parity; creative-code loop proven; bindings + spend guard + admin; export package on the ClickUp Launch card via the bridge; links to the standalones; staging, CI/CD, backups, rollback, monitoring | S0a scrub proven; box prep done (A0); contracts drafted |
| S2 Intelligence merge | Scraper engine + transcriber as services in the stack; meta_ads data in unified Postgres (A4 spike → gate G1); native Intelligence pages (brands, browse, families, intel, research, teardowns, market intel); Reddit VOC (A18); PubMed evidence adapter + MCP + evidence packet (A18b, A18c); Telegram/Discord channels as VOC sources (A23); "send to brief / Expand"; static-ads' own scraper retired; standalone scraper retired | S1 exit gate (§3) true in production; §9 limits re-issued for scraper workloads |
| S3 Studio merge + strategy layer | Agent runtime on Postgres (studio schema), night-shift on the stack, subscription runner internal-only; Script Studio native; hook session + gates; coverage map, gap finder, allocation, brief queue; validated memory; instinct loop; KPIs from readback; winner rules with human gate; standalone console retired | S2 data contracts stable; Bian's coexistence agreement explicit; workos naming/launch APIs reliable |
| S4 Workspace cutover | Launch board native (pilot: discovery S0b → G2 → build → G3), then boards in the order discovery names; ClickUp mirror as rollback; workos moves into the stack; credentials discontinued; Railway off | S3 loop in daily use; D1–D4 settled; one board accepted |
| S5 SaaS hardening | RLS per schema, per-workspace keys/quotas, audit log, billing, onboarding, security review, retention/deletion rules | Native workspace is the default path; per-workspace boundaries proven in practice |
2b. Bridge track B — standalone work for Mathew while S1 runs
Agon's decision: the standalone scraper and RescaleOS may be changed now for Mathew's needs, in parallel with S1; no freeze between the projects. Track B is temporary: it lives in the standalone repos, it does not redefine Skynet's ownership or end state, and every bridge path is retired by A19 / A20 / B0 once the native flows exist. Cards are in the task specs, section "Bridge track B"; ordered by what unblocks Mathew first.
| Order | Key | Card | Owner | Size | Depends on |
|---|---|---|---|---|---|
| 1 | R1 | PubMed doctrine file (evidence-contract.md: evidence classes, claims policy, citation format, transport order WebFetch → MCP → paste) | Bian-side / Vince | S | — |
| 2 | R2 | RescaleOS /evidence-layer skill (six lenses, WebFetch first, outputs M0–M9) | Bian-side / Vince | M | R1 |
| 3 | R6 | Prove /evidence-layer on one product; retro edits into R1/R2 | Bian-side / Vince | S | R2 |
| 4 | R3, R4, R5 | Consumers: BPT Phase 2.5, offer-brief/belief-doc, scriptwrite feed | Bian-side / Vince | S each | R2, R6 |
| 5 | R8 | RescaleOS maps + memory: PubMed live, named as evidence not VoC | Bian-side / Vince | S | R2, R6 |
| 6 | I1 | Scraper LFS bridge: Ads-Library-link ingest, long-copy detection, lander filter, Grok extraction tier, ranked HTML package | Agon | L | — |
| 7 | MC1 | RescaleOS model-configuration boundary (Claude models via setModel in sessions; non-Claude models only through scraper/OpenRouter tiers or an MCP) | Bian-side / Vince | S | — |
| 8 | I3 | RescaleOS /lfs <ad-library-url> skill (submit → poll → fetch → file → optional draft) | Bian-side / Vince | M | I1, MC1 |
| 9 | I2 | Primal Queen continuous job + export/drop into his folders | Agon | M | I1 |
| 10 | I4 | Miguel's feedback → rules.md | Vince | S | Miguel's notes |
| — | R7a | PubMed scraper adapter + MCP (lib/market-intel/pubmed-*, /mcp/pubmed) — optional accelerator after R6 | Agon | M | R6 |
Impact on Skynet cards (features, not dates): A18b becomes a port of the proven PubMed adapter, not a build; A18c consumes the proven evidence-packet contract; A12a takes the Grok extraction schema as its prompt asset seed; A13a takes the lander/destination filter as lens semantics; V14 takes the extraction schema, the "write one for me" contract and rules.md as layer inputs; V17 takes the reaction-banking rule as instinct-loop source; V15's evidence/teardown views follow the package shape the bridge proved. A19 and A20 gain explicit sunset duties; new card B0 · Bridge sunset checklist (A, S, after A19 + A20).
3. S1 exit gate
app.rescale.mediaserves the unified app fromserver.ecomprofits.io; one login for Skynet itself.- Production fully native at parity.
- Creative-code loop proven with one real ad.
- Bindings + spend guard + minimal admin.
- Export package attached to the existing ClickUp Launch card via the workos bridge.
- Intelligence and Studio entries link to the standalones.
- Staging + CI/CD + backups + rollback drill + monitoring.
4. Card delta from the previous card set (48 → S1 set)
| Card | Was | Now | Why |
|---|---|---|---|
| A2b, A5-lite, V6b, A8 | sidecar aliases, console SSO, scraper SSO, scraper soak | dropped | no mounting, no cross-host proxy; standalone changes are limited to bridge track B while S1 runs |
| A4 (+ gate G1) | PostgREST spike in S1 | S2 — "scraper data → unified PG for the merge" | not part of the S1 topology |
| S0b, S6, S8, V9, S11 (+ G2, G3) | launch-board pilot in S1 | S4 (pilot is the first Workspace board) | not in the S1 exit gate; loop proven via the bridge instead |
| S8 | launch-board API + mirror | split: S8a (S1: narrow workos bridge only — POST /naming/ad-name + POST /launches/:id/package on the already-existing Launch card; no launch list/read/create/update API) and S8b (S4: full launch API + native board) | S1 needs only the package on the existing Launch card |
| A3 | proxy + SSO for mounted routes | rewritten: Caddy for the unified app only | no /scraper, /studio |
| A6 | staging with isolated sidecars | rewritten: unified-app staging on server.rescale.media | Agon's choice |
| V6 | shell routes + legacy mounts | rewritten: shell with links to the standalones | link-out |
| X2, X3, X4, X5, X7, M4, M6, X1, S10, S13, V13, M5 | proofs/drills for the old topology | rewritten for two boxes, the ecomprofits box limits and the bridge | new host |
| A0 | — | added: box prep on both boxes (paths, vhosts, GHCR login, backup folders + permissions, disk baseline) | new host |
| A2c | — | added: compose resource limits + Postgres tuning + concurrency caps (architecture §9) | Supabase protection |
| A3b | — | added: deploy.yml on the ecomprofits pattern — two SSH targets, digest pinning, .env.release, smoke gate, Telegram | CI/CD decision |
| X3b | — | added: Supabase-protection smoke (load test Skynet under its caps; Supabase latency unchanged) | shared box |
| X4b | — | added: backup path + sweep validation on the production box (folder, permissions, Storage Box sync, freshness check) | separate backup path |
| M3 (email) | Sead | moved to Agon (W6) | Sead's load |
| Unchanged | A1a, A1b, A2, S0a, S1a, S1b, S3, S4, S4b, S5a, S7, S12, V1, V2a, V3, V4, V5, V7, V8, V10, M1, M2 | — | build the app, the loop, the contracts |
S1 card set = 43 cards (plus A4 in S2 and S0b/S6/S8b/V9/S11 in S4 kept in the same JSON). Specs for rewritten/added cards are updated in skynet-task-specs.md in the same review pass as this plan (marked "S1-rev" there).
5. S1 waves, gates and load
| Wave | A — Agon | V — Vince | S — Sead | Gate at the end of the wave |
|---|---|---|---|---|
| W0 prep | A0 box prep, both boxes (S) | — | S0a workos scrub + scan gate (S) | Scan gate proven on the scrubbed tree; both boxes ready (paths, vhosts, GHCR, backup folders) |
| W1 foundation | A1a repo + imports (M) · A1b CI + governance (M) | V1 SSO in Production (S) · V2a shell skeleton (S) · V3 Production on unified PG (M) | S1a core auth + contract (M) · S1b invite/reset + user import (M) | CI green on main; core issues tokens; Production runs on unified PG locally with /api/healthz + /api/version |
| W2 contracts + core | A2 compose files, dev stack (M) · A2c limits + tuning (S) · A3 Caddy for the unified app (S) | V4 bindings + usage + spend guard (L) | S3 creative-code service (M) · S4 lineage + outbox (S) · S4b bindings contract (S) | Contract day: auth, creative code, lineage, bindings, launch-package schemas merged in packages/contracts with consumer tests |
| W3 deploy + staging | A3b deploy.yml (M) · A6 staging on server.rescale.media (M) | V6 shell with links (S) · M1 settings migration (S) · V7 code on export + lineage writes (M) | S5a ecomprofits read layer (M) · S8a narrow workos bridge only: POST /naming/ad-name + POST /launches/:id/package on the already-existing Launch card (M) | Staging live; smoke gate green; export carries a code; read layer matches the dashboard for 3 known ads |
| W4 closed loop | X5 rollback drill + cutover matrix (M) · X7 production stack prepared on the ecomprofits box (M) | V8 gateway client in Production (M) · V10 Production parity + winners show code/lineage (M) | S7 readback job (M) · S10 loop E2E with one real ad (M) | Loop proven on staging (documented run); production stack prepared and healthy on server.ecomprofits.io; rollback under 15 min |
| W5 drills + hardening | X3 synthetic checks + backup freshness (S) · X3b Supabase-protection smoke (S) · X4 restore drill (S) · X4b backup path validation (S) | V5 minimal admin (S) · V13 contract tests + module docs (S) · X2 upload/download/SSE through the proxy (S) · M2 R2 prefix ADR (S) | S12 production-PG migration dry run + rollback scripts (M) · S13 cross-tenant isolation tests (S) · M5 retention plan (S) | All drills passed and written up; parity checklist green; isolation tests in CI |
| W6 QA + go-live | X1 auth policy tests (S) · M3 email delivery (S) · M4 legacy-host monitoring (S) · M6 comms + training (S) | QA/freeze (all) | QA/freeze (all) | S1 exit gate (§3) true in production → S2 may start |
Load (S=½, M=1, L=2): W0 A 0.5 · S 0.5 — W1 A 2 · V 2 · S 2 — W2 A 2 · V 2 · S 2 — W3 A 2 · V 2 · S 2 — W4 A 2 · V 2 · S 2 — W5 A 2 · V 2 · S 2 — W6 A 2 · V/S QA. No cell above 2.
Hard dependency chains: S0a → A1a → A1b → A2 → A3 → A3b → A6 → X7 (deploy spine, Agon) · S1a → contract day → S3/S4 → V7 → S5a → S8a → S7 → S10 (loop spine) · V3 → M1 → V10 → S12 (Production data). Everything else floats inside its wave.
Within-wave order where a same-wave dependency exists:
- W4:
S7lands first;S10runs on the readback output fromS7plus the stamped export fromV7;V10does parity/regression work in parallel, but its winners/code/lineage acceptance closes only afterS7is green. - W5:
S12closes before the production migration checklist is signed.
6. S1 cards — one line each (full spec in skynet-task-specs.md)
Agon: A0 box prep · A1a repo + imports + CODEOWNERS · A1b CI + governance · A2 compose (prod / staging / dev) · A2c limits + Postgres tuning + concurrency caps · A3 Caddyfile (SPA + /api/*, request ids, limits, rate limit) · A3b deploy pipeline (build → staging → smoke → prod, digests, .env.release, Telegram) · A6 staging stack · X5 rollback drill + cutover matrix · X7 production stack prepared · X3 synthetic + backup freshness · X3b Supabase-protection smoke · X4 restore drill · X4b backup path validation · X1 auth policy tests · M3 email · M4 legacy-host monitoring · M6 comms.
Vince: V1 SSO in Production · V2a shell skeleton · V3 Production on unified PG + ops endpoints · V4 bindings/usage/spend guard · V6 shell with links · M1 settings migration · V7 creative code on export + lineage · V8 gateway client · V10 parity + winners with code/lineage · V5 minimal admin · V13 contract tests + docs · X2 proxy I/O tests · M2 R2 prefix ADR.
Sead: S0a workos scrub · S1a core auth + contract · S1b invites + user import · S3 creative-code service · S4 lineage + outbox · S4b bindings contract · S5a read layer · S8a narrow bridge endpoints (POST /naming/ad-name, POST /launches/:id/package) in the old workos repo · S7 readback · S10 loop E2E · S12 migration dry run · S13 isolation tests · M5 retention plan.
7. Slices S2–S5 — full card sets (scoped to the same standard as S1)
Agon's decisions that shape these slices: S2 — scraper engine + transcriber run on server.ecomprofits.io as Skynet services with their own limits; real port of the meta_ads schema + RPC functions into Skynet's Postgres and the engine rewired to direct pg (no PostgREST shim); Intelligence UI rebuilt natively; scraping behaviour per the functional design (competitor entities ↔ products, lenses, schedules, alerts, auto-recreate rules, the scrape → classify → family → teardown → script chain). S3 — everything on the stack, skills/prompts as versioned in-app assets, subscription runner as an internal binding; needs Bian's agreement. S4 — only the 13 creative-workflow ClickUp lists are replaced; company-ops lists stay in ClickUp. S5 — multi-tenant, invite-only, manual invoicing from metered usage; Stripe self-serve out of scope. Executable specs for every card below are in skynet-task-specs.md (sections S2–S5); the JSON carries them.
S2 · Intelligence merge
| Wave | Cards | Gate at the end of the wave |
|---|---|---|
| W0 | D21, D22, D23, D23b | Operator rules, product-card fields, VOC seed groups and evidence lens terms are written and accepted — no build on guessed workflow semantics |
| W1 | A4 | Direct-pg path proven against real meta_ads semantics and load; the PostgREST option is formally dead (ADR-003) |
| W2 | A9 | meta_ads schema + RPCs run inside Skynet Postgres; scraper workers use direct pg; staging gives the same browse/intel/research answers as the old stack |
| W3 | A2d, A13a, V22 | Engine + transcriber run in the stack under their own limits; competitors/products/lenses are workspace entities; native browse/intel pages usable |
| W4 | A14, A13b | Native research backend live; alerts + auto-recreate rules + competitor APIs live |
| W5 | A15, A12a | Promote to product live; teardown jobs + artefacts native |
| W6 | A18, A12b | Reddit VOC live; Create script / Recreate actions live |
| W7 | V15, A23, A18b | Native pages group 2: research, teardowns, market intel/VOC + evidence, tracked-ad actions, promotion; Telegram/Discord channels as VOC sources; PubMed evidence adapter + MCP live |
| W8 | A19, A18c | Standalone scraper retired; static-ads' duplicate scraper disabled; Intelligence runs only from Skynet; evidence packet in briefs |
S2 exit gate: Appendix A.1 at 100 % parity inside Skynet (settings, tools, research, teardowns, market intel, admin surfaces); standalone scraper off; static-ads' internal scraper retired.
| Key | Card | Owner | Size | Wave | Depends on |
|---|---|---|---|---|---|
| D21 | Research operator workflow confirmation (W1–W3 rules) | A | S | W0 | slice entry gate |
| D22 | Product bridge field confirmation (Sven + Cyrus) | S | S | W0 | slice entry gate |
| D23 | Reddit VOC seed confirmation (Mathew) | A | S | W0 | slice entry gate |
| D23b | Evidence lens seed confirmation (Mathew) | A | S | W0 | slice entry gate |
| A4 | Intelligence data-path proof + pressure test → ADR-003 | A | L | W1 | D21, D22, D23 |
| A9 | meta_ads migration + scraper direct-pg cutover | A | L | W2 | A4 |
| A13a | Competitors, lenses, schedules — model + migration | A | M | W3 | A9, D21 |
| A2d | Scraper engine + transcriber as stack services with hard limits | A | M | W3 | A9 |
| V22 | Intelligence native pages, group 1 (brands, browse, families, transcripts, intel, gold, settings, tools) | V | L | W3 | A9, A13a |
| A13b | Traction alerts + auto-recreate rules + competitor APIs | A | M | W4 | A13a, D21 |
| A14 | Research native backend + ranked opportunities | A | M | W4 | A9, D21 |
| A12a | Teardown native jobs + artefact pages | A | M | W5 | A9, A13a |
| A15 | Promote to product (+ ClickUp Product card via bridge) | A | M | W5 | A14, D22 |
| A12b | Create script / Recreate actions + brief stub / Expand hand-off | A | M | W6 | A12a |
| A18 | Reddit VOC pipeline (groups, continuous, retained, export) | A | M | W6 | A9, D23 |
| A23 | Chat source adapters: Telegram + Discord channel ingestion | A | M | W7 | A18, A9 |
| A18b | PubMed evidence adapter + six-lens scopes + MCP + export | A | M | W7 | A9, A18, D23b |
| V15 | Intelligence native pages, group 2 (research, teardowns, market intel/VOC, tracked-ad Expand / Create script / Recreate, promotion) | V | L | W7 | V22, A12b, A14, A15, A18, A18b |
| A19 | Scraper retirement + duplicate-scraper shutdown + archive (incl. the bridge export surfaces) | A | M | W8 | A2d, V15 |
| A18c | Evidence packet in briefs | A | S | W8 | A12b, A18b |
Load (S=½, M=1, L=2): W0 A 1.5 · S 0.5 — W1 A 2 — W2 A 2 — W3 A 2 · V 2 — W4 A 2 — W5 A 2 — W6 A 2 — W7 A 2 · V 2 — W8 A 1.5. No cell above 2.
Risks → cards: RPC/browse edge cases hidden by Supabase → A4; scraper load on the shared box → A4, A2d; promotion semantics drift → D21, D22, A15; wrong VOC groups/export → D23, A18; wrong evidence classes / unsafe claims → D23b, A18b, A18c; UI parity gaps → V22, V15, A19; alert/auto-recreate rules misfire → D21, A13b.
S3 · Studio merge + strategy layer
| Wave | Cards | Gate at the end of the wave |
|---|---|---|
| W0 | D31, D32, D33 | Bian's coexistence + migration window, hook/gate semantics, script-bridge behaviour are explicit |
| W1 | A10 | Agent runtime on Postgres studio; engine API parity green |
| W2 | A11 | Skills, doctrine, workspaces, scheduled loops, subscription binding run on the stack under one runtime contract |
| W3 | A21, V14, S16 | Studio parity APIs, prompt assets/overlays, script bridge stable for daily authoring |
| W4 | V23, S14 | Native Studio pages + inbox/dispatch live; the old console not needed for normal work |
| W5 | V16, S15 | Hook session + gates; lineage producers for scraper/studio/workos + coverage store v0 |
| W6 | V18, S5b, S9 | Coverage map, gap finder, allocation, brief queue; winner rules with human gate |
| W7 | V17, V19, S27 | Instinct loop for hooks and scripts, judge, hypothesis ledger; the notification platform (outbox, dispatcher, destinations, quick actions) live |
| W8 | V20, A24 | Assistants, template sync, video recipes; agents in chat — bot proposals with quick actions, @skynet tag-and-ask |
| W9 | A20 | Standalone console retired |
S3 exit gate: Appendix A.3 at 100 % parity inside Skynet; Bian's loops run on the stack; KPIs come from readback; the script entity bridges to ClickUp until S4; every notification goes through the platform with quick actions; the team can tag and ask the agent in Telegram/Discord; the standalone console is off.
| Key | Card | Owner | Size | Wave | Depends on |
|---|---|---|---|---|---|
| D31 | Bian coexistence + migration-window agreement | A | S | W0 | slice entry gate |
| D32 | Hook + strategy expectations (Mathew + Cyrus) | V | S | W0 | slice entry gate |
| D33 | Script-card bridge + demand semantics (Sven + ops owner) | S | S | W0 | slice entry gate |
| A10 | Agent runtime on Postgres studio + engine API parity | A | L | W1 | D31 |
| A11 | Runtime assets, night-shift on the stack, workspaces, subscription binding + rotation | A | L | W2 | A10, D31 |
| A21 | Studio parity APIs (scripts, revisions, sessions, gates, scoreboard, opportunities, backlog, notifications, playbook, research ingest, KPI reminder, feedback pollers) | A | L | W3 | A10, A11 |
| S16 | Script-entity bridge to ClickUp Script cards + demand-line hand-off | S | L | W3 | A10, D33 |
| V14 | Prompt layers + per-user overlays + Mathew-editable prompt assets | V | L | W3 | A11, D32 |
| S14 | Inbox + dispatch | S | M | W4 | A21, S16 |
| V23 | Script Studio native pages | V | L | W4 | A21, V14 |
| S15 | Lineage producers (scraper, studio, workos) + coverage store v0 | S | M | W5 | S14, S16 |
| V16 | Hook session + approval gates | V | L | W5 | V14, D32 |
| S5b | Winner/loser rule evaluation (workos classify knobs) | S | M | W6 | S15 |
| S9 | Winner/loser human gate + winner lineage | S | M | W6 | S5b, S15 |
| V18 | Coverage map + gap finder + allocation + brief queue | V | L | W6 | S15, D32 |
| S27 | Notification platform port (registry, outbox, dispatcher, destinations, mutes, digests) | S | L | W7 | A21, S16 |
| V17 | Instinct loop for hooks | V | M | W7 | V16, S9 |
| V19 | Instinct loop for scripts + judge + hypothesis ledger | V | M | W7 | V23, S9 |
| A24 | Agents in chat: bot proposals with quick actions, @skynet tag-and-ask | A | L | W8 | S27, S14, A11 |
| V20 | Layer-authoring assistants, template sync, video recipes | V | M | W8 | V14, V23 |
| A20 | Standalone console retirement + archive | A | M | W9 | A24, D31, V20, V23 |
Load (S=½, M=1, L=2): W0 A 0.5 · S 0.5 · V 0.5 — W1 A 2 — W2 A 2 — W3 A 2 · S 2 · V 2 — W4 S 1 · V 2 — W5 S 1 · V 2 — W6 S 2 · V 2 — W7 S 2 · V 2 — W8 A 2 · V 1 — W9 A 1. No cell above 2.
Risks → cards: Bian rejects the model mid-build → D31; Postgres migration changes loop semantics → A10, A11; decorative coverage map → D32, V18; script bridge double truth → D33, S16; taste captured as shared truth → V17, V19, S9.
S4 · Workspace cutover
| Wave | Cards | Gate at the end of the wave |
|---|---|---|
| W0 | S0b, D41, D42 | Launch discovery + board authority complete; G2 inputs are real |
| W1 | S6 | G2 decided; the order of the remaining 12 boards named |
| W2 | S8b, V9 | Native launch board + mirror live on staging, reconciliation both ways |
| W3 | S11 | Pilot accepted for production dual run; G3 decided |
| W4 | S26, V24 | Board batch 2 (creativeDemand, scripts, creatives) native with mirror rollback |
| W5 | S18, V25 | Board batch 3 (products, competitors, researchIntake, ripSources) native |
| W6 | S17 | workos runs in the Skynet stack with new credentials; Railway = rollback only |
| W7 | S19, V26 | Final batch (funnelsLanders, ugcCreators, emailFlows, campaigns, adsets) native; ClickUp read-only for the 13 lists; Railway off after the rollback window |
S4 exit gate: the 13 creative-workflow lists replaced by native boards; ClickUp read-only for them; workos in the stack; Railway off; company-ops lists untouched in ClickUp.
| Key | Card | Owner | Size | Wave | Depends on |
|---|---|---|---|---|---|
| D41 | Launch pilot confirmation (Cyrus + media buyer) | S | S | W0 | slice entry gate |
| D42 | Board authority + mirror-failure confirmation (Sven + ops owner) | S | S | W0 | slice entry gate |
| S0b | Pre-pilot discovery (launch process, per brand) | S | M | W0 | slice entry gate |
| S6 | Discovery write-up → G2 (launch board first; board order) | S | S | W1 | S0b, D41, D42 |
| S8b | Launch board API + ClickUp mirror | S | L | W2 | S6 |
| V9 | Launch board native UI | V | L | W2 | S8b |
| S11 | Pilot SOP + walkthrough → G3 | S | S | W3 | S8b, V9 |
| S26 | Board batch 2 API + mirrors: creativeDemand, scripts, creatives | S | M | W4 | S11, D42 |
| V24 | Board batch 2 native UI | V | M | W4 | S26 |
| S18 | Board batch 3 API + mirrors: products, competitors, researchIntake, ripSources | S | L | W5 | S26, D42 |
| V25 | Board batch 3 native UI | V | L | W5 | S18 |
| S17 | workos host move into the stack + credential discontinuation | S | L | W6 | S11, S26, S18 |
| S19 | Final batch API + ClickUp read-only cutoff: funnelsLanders, ugcCreators, emailFlows, campaigns, adsets | S | L | W7 | S17, D42 |
| V26 | Final batch native UI + Workspace as the default path | V | L | W7 | S19 |
Load (S=½, M=1, L=2): W0 S 2 — W1 S 0.5 — W2 S 2 · V 2 — W3 S 0.5 — W4 S 1 · V 1 — W5 S 2 · V 2 — W6 S 2 — W7 S 2 · V 2. No cell above 2.
A.4 folds: naming (M3) stays in S1/S3 (S3, S8a, S16); classify knobs (M2) in S3 (S5b, S9), only hosted by S17; the presentation deck is archived inside S17.
Risks → cards: launch board built on guessed buyer behaviour → S0b, D41, S11; wrong board order → D42, S6; mirror drift on cascade paths → S8b, S26, S18, S19; hidden Railway-only secrets/crons → S17; company-ops lists touched by accident → S19, V26.
S5 · SaaS hardening
| Wave | Cards | Gate at the end of the wave |
|---|---|---|
| W0 | D51, D52, D53 | Billing/retention, roles/onboarding, security-review scope written down |
| W1 | S21 | RLS implemented; tenancy tests prove isolation schema by schema |
| W2 | S22, A22 | Per-workspace credentials, keys, quotas enforced across the stack |
| W3 | S23, V21 | Audit trail, invite-only onboarding, full users/roles/admin parity live |
| W4 | S24, A17 | Usage metering + invoice export; security/load hardening complete |
| W5 | S25a | Export + retention live |
| W6 | S25b, S20 | Deletion/purge live; SaaS readiness review passes |
S5 exit gate (= 100 %): multi-tenant invite-only operation live; RLS enforced; per-workspace credentials/keys/quotas enforced; audit log + usage metering live; manual invoicing from metered usage; retention/deletion complete; admin/users/roles parity across Production, Intelligence, Studio, Workspace. Stripe self-serve out of scope.
| Key | Card | Owner | Size | Wave | Depends on |
|---|---|---|---|---|---|
| D51 | Billing + retention confirmation (ops owner) | S | S | W0 | slice entry gate |
| D52 | Roles + onboarding confirmation (Sven + Mathew) | V | S | W0 | slice entry gate |
| D53 | Security review scope confirmation | A | S | W0 | slice entry gate |
| S21 | RLS rollout + tenancy CI for core, production, meta_ads, studio | S | L | W1 | D51, D52 |
| A22 | Sidecar + runtime quota enforcement (scraper, transcriber, runtime, workos, production callers) | A | M | W2 | S22 |
| S22 | Per-workspace credentials, keys, quotas + admin APIs | S | L | W2 | S21 |
| S23 | Audit log + admin provenance | S | M | W3 | S21, D52 |
| V21 | Admin / users / roles parity + invite-only onboarding + workspace creation | V | L | W3 | S21, S22, D52 |
| A17 | Hardening: load tests, abuse cases, security-review remediation | A | L | W4 | D53, S21, S22, S23, S24 |
| S24 | Usage metering ledger + invoice export (manual invoicing) | S | L | W4 | S22, A22, D51 |
| S25a | Workspace export + retention jobs | S | M | W5 | S21, S23, D51 |
| S20 | SaaS readiness review → 100 % | S | S | W6 | V21, A17, S24, S25b |
| S25b | Deletion queue, dry-run, purge across Postgres / R2 / lineage | S | M | W6 | S25a |
Load (S=½, M=1, L=2): W0 A 0.5 · S 0.5 · V 0.5 — W1 S 2 — W2 A 1 · S 2 — W3 S 1 · V 2 — W4 A 2 · S 2 — W5 S 1 — W6 S 1.5. No cell above 2.
Risks → cards: late RLS breaks real workflows → S21; services still read global credentials → S22, A22; admin parity gaps → D52, V21; billing drifts into Stripe → D51, S24; deletion misses R2/lineage/sidecar data → S25b, A17.
8. Discovery and interviews (run during S1, feed S2–S4)
| Workflow | Who | Feeds |
|---|---|---|
| W1–W3 competitor tracking, research, teardown/VOC | Agon + the weekly research operator | S2 cards |
| W4 strategy expectations | Mathew + Cyrus | S3 |
| W5, W6 script practice, hook approvals | Bian (+ Mathew) | S3; coexistence agreement |
| W7–W9, W13 production hand-offs, learnings | Vince | S1 parity checklist, S3 |
| W11 launch package (S0b) | Cyrus + one media buyer | S4 |
| W14 boards, mirror failures, statuses | Sven + ops owner | S4 |
9. Confirmations still open (do not gate S1)
Bian — Studio stays standalone through S3; coexistence for A11. Leadership — D1–D4 (gate S4). Sven — bridge scope (S8a endpoints in the old repo, deployed on Railway). Cyrus — launch-pack minimum. R2 bucket versioning/lifecycle — infra input for the architecture doc §10.