Redpoint Engine — Phase 10+ Roadmap (seat-business ordered)
Authored 2026-07-16 by the Fable orchestration session. Execute in a CLEAN session — this doc is the inheritance. Phases 1–9 are complete (erasure #56 being additively rebased at authoring time). Ordering is by seat-business leverage, not slice size.
Already shipped since this was scoped (do NOT re-plan)
job.cancelledwebhook event — built this session (a tier-3 lifecycle-parity gap). Removed from Phase 10.- Transcode-worker
theme.logo_urlSSRF guard — built this session. Removed from Phase 11. editor_applicationstable +/pro-editorsrecruitment stream — built this session (migration 0032).- Phase 10 — COMPLETE (2026-07-17, batch #60/#61/#66 + #65). See per-phase status below.
- Phase 11 — dry-run + arming-prep DONE (#68/#71, migrations 0035–0036); live arming awaits an operator ruling. See per-phase status below.
Delivered non-roadmap wave — the editor program (2026-07-17, #65–#79)
An operator-requested wave that sits outside the seat-business roadmap below,
delivered in full on main (a1cbd64), migrations 0034–0039 live:
- Client voice notes (0034, #65) + editor notification on append (#72).
- Editor performance reviews — client rating store + RPC + aggregate (0037, #74, packet 1A) and the client capture surface (#77, 1B).
- Specify-your-editor paid upsell (0038, #75) — a paid
package_extrasre-request on the continuity-hold machinery with cron-swept refund-on-miss; the 5★→upsell tie-in (#79, DX). LIVE £10 / 48h on wakecut, EUR hidden. - Editor supervision engine — pure composite-score policy engine (#76, 1C) + persistence/dispatch-hooks/audit/confirm-queue (0039, #78, 1D). DORMANT:
dispatch_config.supervisionships OFF (enabled/auto_actionsdefault false). - In a PR, not merged: packet 1E (ops supervisory roster/scorecard/confirm queue).
Plan of record:
docs/EDITOR-REVIEW-AND-SELECTION-PLAN.md.
Migration numbering
Superseded — live DB is at 0039 (2026-07-17). Actual assignments since this
was authored: Phase 10 preview↔draft link = 0033; voice-note kind = 0034;
Phase 11 commission = 0035 + arming-prep 0036; editor program = 0037
(ratings) / 0038 (specify-editor) / 0039 (supervision). Next free = 0040.
Always probe supabase/migrations/ + open PRs at build time (rule 8).
Phase 10 — Tier-3 Seat Completion (headless review + return-origin) — ✅ COMPLETE (2026-07-17)
Shipped: 10a-1 review-player API (#60), 10b per-tenant return origin (#61), 10a-2 review/delivery handle in webhook payloads (#66), preview↔draft link (0033). The expocut pure-API full-loop e2e (below) is green. data.review/data.delivery handles are documented in docs/PARTNER-API.md §04.
Goal: a fully-headless seat runs and renders the whole order→review→approve/cancel loop on its own front end from /api/v1 + webhook payloads alone.
No product decision needed — pure unblock. BUILD FIRST.
Scope (design these together — one cohesive "headless review" concern):
- Review-player API —
GET /api/v1/jobs/[jobId]/previews: ordered previews (reuseorderPreviews,src/lib/previews.ts) + short-lived signed GET URLs + thecurrent-cut flag. Approve/revise already exist via the transition endpoint. NON-GOAL: a custom scrubbing UI (partner uses native<video>/Frame.io). - Review URL in webhook payloads — add a review/preview handle to
draft.ready/job.status_changed→CLIENT_REVIEWand a download handle tojob.delivered, through the SAMEAPI_JOB_FIELDS/buildWebhookPayloadallowlist (no fare/editor leak). - Per-tenant checkout return origin — a domainless/pure-API tenant's Stripe success/cancel + redirects land back on the partner's site, not the wakecut pin. Per-order
return_urlon the 0025 orders API (or atenants.*jsonb slot). Anti-spoof: honor only a return_url whose origin the tenant pre-registered. (resolveRequestOrigininsrc/lib/public-origin.ts.) - Preview↔draft link (migration 0033) —
src/lib/previews.tsflags this blocked: client RLS can't readtranscode_jobs,fileshas no link column. Add the column so the review API/surface shows only the CURRENT submission's preview.
Gate: an expocut (pure-API) e2e drives NEW→CLIENT_REVIEW→(REVISION→CLIENT_REVIEW)→APPROVED→DELIVERED where the partner-front simulation renders the current-cut preview and returns to its OWN origin using ONLY API responses + webhook payloads (asserts a review URL on draft.ready, HMAC-verified; zero engine-hosted page hits).
Size L. Sub-items parallelize.
Phase 11 — Seat Revenue (platform_fee_bps wired) — 🟡 dry-run + arming-prep DONE; arming awaits operator ruling
Shipped: Option A partner-tenant commission, dry-run-first (#68, migration 0035 tenant_connect/partner_commissions, src/lib/partner-commission.ts, two-gate arming) + arming-prep (#71, migration 0036 — P&L ledger leg, EUR needs_fx_review holds, fee-unset surfacing). The code-side arming blockers are CLOSED. Live arming still needs the operator/accountant ruling (split + VAT topology, D1 below) before flipping the two gates. Option-B (white-label / merchant topology) build plan + decisions D1–D10 in docs/OPTION-B-BUILD-PLAN.md.
Goal: the engine formally earns its cut on every licensed-seat job.
⚠ NEEDS OPERATOR DECISION before live arming (money topology — see below).
Scope:
platform_fee_bpsinto the money flow — wire the tenant fee at capture/transfer (transitions.tspayout calc +payouts.tsledger): computed, recorded, reportable. Fares stay admin-only (p8-p9 §8); the fee is booked engine-side, never exposed to the tenant key.platform_fee_bps(0001) is currently referenced in ZERO code.- retention_days floor CHECK (migration 0034) — defense-in-depth. NOTE: the retention runner already maps 0/negative→default 45 (
retentionDaysFor), so this is belt-and-braces at the DB level, not a live foot-gun. AddCHECK (retention_days >= 1).
Gate: a licensed-tenant job runs order→APPROVED→DELIVERED; ledger shows platform fee = round(gross × platform_fee_bps/1e4), editor payout unchanged; a sub-floor retention_days is rejected by the DB.
Size M. Migration 0034.
Phase 12 — Show-Day Rapid Dispatch (surge variant of Phase 4)
Goal: the flagship expo/event seat survives a live show day — batch intake, rapid auto-assign, surge SLA — on one operator screen. ⚠ NEEDS OPERATOR DECISION: what "rapid" relaxes (QC skip/lighten? auto-assign vs manual? surge SLA numbers).
Scope:
- Surge dispatch mode: event-scoped queue/board variant of the ops console, batch assign, tightened SLA, live throughput counters (reuse quality/SLA helpers).
pushback_*notification emails (unruled) — the pool-pushback loop (0017/0018) releases a client prompt + repools with a boost but fires NO email (src/lib/emailhas no pushback template). Rule + wire the client "we need input to proceed" + boost/repool notifications throughnotifyJobEvent. Surge is when pushback spikes → they belong together.
Gate: a simulated show-day batch of N event orders is intaken + dispatched under surge SLA in one ops action, with the pushback prompt email firing exactly once (idempotent on retry). Size M. Should LEAD Phase 11 if an expo pilot is on the calendar — it's the demo that closes an expo partner.
Phase 13 — Adjacent-Vertical Launch Kit + Hosted-Seat Theming Maturity
Goal: stand up a new Tier-1 hosted+themed vertical seat from config + seed; make dark-branded hosted surfaces look finished.
Scope:
- Repeatable adjacent-vertical tenant launch: seed template + brief/package/theme/webhook checklist (the wakecut→edits→expocut path, productized) — rule-5 config, not code.
- Dark-theme surface fixes — status-chip light islands (
src/lib/job-status.ts/status-chip) + the review letterbox on the engine-hosted review page, so a dark-brand hosted seat is presentable.
Gate: a fresh dark-branded vertical tenant seeded from the kit runs order→delivery on engine-hosted pages with zero src/ changes and no light-island/letterbox defect.
Size M. Migration 0036 (seed only).
Phase 14 — Cross-Tenant Platform Analytics Console
Goal: one operator console for volume/SLA/margin/fee across all tenants + a partner-scoped slice.
Scope: cross-tenant KPIs (throughput, SLA-breach %, editor quality, and post-P11 platform-fee revenue) as admin-gated views (respect p8-p9 §8 fare confidentiality — a tenant-scoped read never sees other tenants or fares). Optional redacted per-tenant KPI feed via /api/v1.
Gate: the console reconciles per-tenant job counts + fee revenue against the ledger for a window; a tenant API key reads only its own redacted KPIs (cross-tenant + fare access 403/absent).
Size M/L. Migration 0037 (reporting views). Wants P11's fee data — last by leverage.
Defer further / drop
- Curated-pool self-serve onboarding + auto-match (schema ready): supply-side scaling, not a seat-sales lever. Defer until editor supply is the bottleneck.
- Custom timestamped review player UI: DROP (architecture non-goal). Phase 10's review API delivers the real requirement.
Operator product decisions that GATE build
platform_fee_bpsmodel + money topology (P11): flat % vs per-package; AND does buyer money keep landing in Redpoint's Stripe (fee booked engine-side) or move to Connect destination/application-fee (buyer pays the partner, Redpoint takes an application_fee)? The latter re-plumbs checkout + webhooks. Decide before 0034.pushback_*email ruling (P12): does the client get an email when ops releases a pushback prompt / on boost-repool? Content + recipients.- Surge rules (P12): what rapid-dispatch relaxes — QC, auto-assign, surge SLA figures.
Critical files
src/lib/webhooks/dispatch.ts(event vocab + payload allowlist — review URL)src/lib/api-response.ts(API_JOB_FIELDSallowlist)src/lib/transitions.ts(+src/lib/payouts.ts) — platform_fee_bps capture/payoutsrc/lib/public-origin.ts(resolveRequestOrigin— per-tenant checkout return origin)src/lib/previews.ts(preview↔draft link, review API)ingest-service/transcode-worker.js(surge/preview plumbing; SSRF guard already landed)