Companion to PLAN.md. PLAN.md captures architecture and engineering decisions; PRD.md captures product requirements from the user's perspective. Every functional and non-functional requirement here gets a stable ID (
FR-N,NFR-N) so ROADMAP.md and TESTING.md can reference them without drift.
Status: Draft v3 — checkbox-tracked. M0–M7 shipped; M8 (Agent Design Studio v1) + M9 (engine completeness + Agents Marketplace v1) in progress. Product: OffsideStudio — Agent Marketplace (default selling proposition). Underlying record/pipeline data lives in the Offside CRM data layer; the user-facing surfaces are the Agents Marketplace (browse + install pre-built agents) and the Agent Design Studio (visually design, customize, observe). Owner: Offside Labs. Last revised: 2026-05.
[✅]— implemented and onmain[🏗️]— partially implemented / in progress[☑️]— pending (not implemented yet)
Each FR / NFR / POST has a rollup status; user stories and acceptance criteria each get their own checkbox so partial deliveries stay honest. The "Roadmap mapping" line on each FR points at the ROADMAP milestone(s) that ship the work.
OffsideStudio — Agent Marketplace is the first product in the Offside Studio Suite, positioned for SMB sales teams (2–20 reps). The product's hero proposition is "install an agent, customize it, run it against your CRM." Two surfaces lead the experience:
- Agents Marketplace (FR-26): a curated, workspace-agnostic catalog of pre-built workflow agents that an admin can install with one click. Installation creates an immediately editable, immediately runnable workflow in the workspace.
- Agent Design Studio (FR-12): the visual canvas + run-inspector + describe-in-English surface where admins design, customize, and observe their agents.
Underneath these two surfaces sits a polished CRM data layer — contacts, companies, deals, pipelines, tasks, notes, activities — that gives the agents something real to act on. The CRM core (HubSpot/Attio lineage) and durable workflow runtime (Zapier/n8n lineage with M7's idempotent Celery-backed engine) are the foundations; the Marketplace + Studio are the headline.
The wedge is "agents you can ship by Tuesday." Pre-built agents for the obvious sales workflows, a no-code design studio for the bespoke ones, an AI authoring layer that translates English into a runnable graph, and a record/activity layer that makes the whole thing demoable on real data from day one.
"OffsideStudio — Agent Marketplace. Install an agent, customize it in the Design Studio, watch it run against your CRM."
Selling proposition (use this exact phrasing throughout the product, marketing, and demo materials): "OffsideStudio — Agent Marketplace."
Operating principles:
- Marketplace-first onboarding. A new admin's first 30 seconds in the product should be browsing the Agents Marketplace. The empty state for
/automationsinvites the user to "install your first agent." The CRM record views surface "agents that work on this record." - Design Studio is the second-most-prominent surface. Every installed agent opens directly in the Studio. Describe-in-English (FR-12 / M8.S3) is treated as a first-class authoring path alongside drag-from-palette.
- AI-native, not AI-adjacent. Every record view, every agent, every automation step is AI-aware. Cost + latency telemetry is visible to the user.
- Agents are a peer to records. Workflows + CRM records share one mental model and one event bus.
- Web-first with native iOS as a peer surface for read/edit + agent approvals on the go.
- Opinionated UX. Keyboard-first, command-palette-everywhere, dense-but-calm. Marketplace + Studio sit in the primary nav above Contacts / Companies / Deals.
Suite positioning: every Offside product (Studio, Crunch, Design, Director) shares voice, brand, and shared infrastructure. Offside is engineer-to-engineer — confident, technical, never breathless.
This is the most common objection in demos and sales calls. The canonical answer:
n8n / Zapier are workflow tools that point at your CRM. OffsideStudio is your CRM, with agents as a first-class peer.
You wouldn't pick n8n to be your system of record, and you wouldn't pick HubSpot to be your workflow runtime. OffsideStudio is the deliberate merger of the two. Use this section as the source of truth for demo talking points, sales enablement, and any future platform.offside.ai/vs comparison page.
- Records and agents share one data model + one event bus. A record trigger fires synchronously inside the same transaction that created the record (
apps/activities/signals.py→transaction.on_commit→triggers.fire). No webhook hop, no JSON shuttling across an API boundary, no eventual-consistency lag. With n8n + an external CRM, every workflow is a pipe across a boundary. - Pre-built agents for the ecommerce funnel, not generic templates. The Agents Marketplace (FR-26) ships opinionated agents that understand sales primitives — Lead qualification knows what a lead is, Abandoned cart recovery knows what a cart is. n8n's 1000+ templates are generic "connect X to Y" plumbing. Marketplace agents are pre-assembled playbooks.
- AI is the authoring layer, not a node type. Describe-in-English (FR-12 / M8.S3) turns natural language into a runnable graph via Claude tool-use. n8n's AI Agent node is an execution step you still wire by hand; ours is in the authoring loop.
- One bill, one auth, one workspace, one team. The honest TCO comparison is "n8n + a CRM (HubSpot/Salesforce) + a run-history dashboard + a Stripe-webhook handler + glue code" vs one product. Stitched-together SaaS isn't free — the cost is diffused across invoices and engineering hours.
- Per-step cost telemetry + immutable versioning. The Run Inspector surfaces
cost_cents+latency_mson every step including AI calls (NFR-6 — "no silent LLM bills"). Publishing creates an immutableAutomationVersion; in-flight runs finish on their original version (M8.S2). n8n shows execution logs but not first-class AI cost, and live edits can break running executions.
| Objection | Response |
|---|---|
| "n8n has 500+ integrations." | We have HTTP-request + webhook triggers covering any REST API today; named integrations (Gmail, GCal, Slack, Stripe) land M10–M11. We ship deep integrations, not shallow breadth. |
| "n8n is open-source / self-hostable." | Different game — n8n is horizontal (IT/DevOps/data/marketing); OffsideStudio is opinionated SaaS for sales teams. Hard self-hosting requirement → not our fit. |
| "n8n Community tier is free." | Compare apples to apples: free n8n + a paid CRM + maintained glue ≠ free. |
| "What if we outgrow you?" | Agents are open data — a JSON graph + a Postgres schema you own. Export is a short script; we don't lock the data layer. |
| "We already run n8n." | Keep it for IT/data-pipeline work. Use OffsideStudio for the sales motion; the two coexist via the webhook trigger (n8n posts to us to mutate a CRM record). |
Don't open with the competitive compare — it reads defensive. Lead with what the product does; deploy this when asked. The strongest single line: "n8n connects to your CRM; OffsideStudio is your CRM, with agents as a first-class peer." The strongest visual proof is the Run Inspector's per-step cost_cents column — most "AI workflow" tools have no answer to that.
- Context: Founder, head of sales, or sales manager at a 2–20 person company.
- Goals: Pipeline visibility; team accountability; less time configuring tools, more time selling.
- Pain points with current CRMs: Setup is heavy; automations live in a separate tool; AI features are bolt-on.
- Daily surfaces: Workspace home / pipeline view, automation builder, agent inbox, reports.
- Context: Account executive or SDR doing outbound + working assigned deals.
- Goals: Spend the day on relationships, not data entry; instant follow-ups; never miss a hot deal.
- Daily surfaces: Contact + deal records, inbox, command palette, iOS for on-the-go.
- Context: Configures pipelines, custom fields, integrations, agent policies. Often the manager wearing this hat in early-stage SMBs.
- Goals: Sane defaults that customize without breaking; safe rollout of agent autonomy.
- Daily surfaces: Settings, automation library, agent policy table, audit logs.
- Context: Executive, investor, or cross-functional partner who needs to see the pipeline without editing.
- Goals: Glance at the funnel; drill into specific deals.
- Daily surfaces: Dashboards, saved views.
Every FR has: Status · ID · Priority (P0 = MVP, P1 = post-MVP) · Roadmap mapping · Personas affected · Description · User stories · Acceptance criteria.
- Priority: P0 · Personas: P-1, P-3 · Roadmap: M2 (✅)
- Description: Every account creates or joins a workspace. All data is workspace-scoped. Roles:
owner,admin,manager,rep,read-only. - User stories:
[✅]As a manager, I can create a new workspace and invite up to 19 teammates. (M2.S1, M2.S2)[✅]As an admin, I can change a teammate's role. (implemented in M3 settings page; TC-6)[✅]As a rep, I can switch between workspaces I belong to without logging out. (M2.S3)
- Acceptance criteria:
[✅]Workspace switcher reachable in ≤2 keystrokes from anywhere in the app.[✅]Backend rejects any cross-workspace data access with 403.[✅]Invite flow uses Resend magic-link; invitee lands on signup → workspace auto-joined.
- Priority: P0 · Personas: P-1, P-2, P-3, P-4 · Roadmap: M1 (✅)
- Description: Email-based signup/login with JWT (access 1d / refresh 14d). allauth + dj-rest-auth + SimpleJWT on the backend. Password reset, email verification, JWT refresh-on-401.
- User stories:
[✅]As a new user, I can sign up with email + password. (M1.S1)[✅]As a returning user, I can log in on web and iOS with the same credentials and stay logged in. (M2 web, M6 iOS)[✅]As a user, I can reset a forgotten password via email link.
- Acceptance criteria:
[✅]Signup → workspace creation flow ≤30 seconds.[✅]Refresh token rotation; access token revoked on logout.[✅]iOS Keychain stores tokens; web stores refresh in HTTP-only cookie.
- Priority: P0 · Personas: P-2, P-3 · Roadmap: M4 (✅) web; M6 (✅) iOS read-only
- Description: First/last name, primary email, phone(s), title, company FK, owner FK, lifecycle stage, source, custom fields.
- User stories:
[✅]As a rep, I can create, view, edit, and archive a contact. (M4.S1)[✅]As a rep, I can search contacts by name, email, or any custom field. (M4.S4 via filter DSL; full FTS in M12)[✅]As an admin, I can define custom fields per workspace. (M4.S3, FR-8)
- Acceptance criteria:
[🏗️]List view paginates 1k contacts smoothly (≤200ms after filter change). (Pagination works; perf budget verified in M15.)[✅]Detail view shows the full activity timeline. (M5 ActivityFeed)[✅]Soft-delete via archive (recoverable for 90 days).
- Priority: P0 · Personas: P-2, P-3 · Roadmap: M4 (✅) web; M6 (✅) iOS read-only
- Description: Name, domain, size band, industry, owner FK, custom fields. Many-to-one with contacts.
- User stories:
[✅]As a rep, I can view all contacts associated with a company.[✅]As a rep, I can navigate to a deal directly from a company page. (TC-13 via M5 link)
- Acceptance criteria:
[✅]Domain auto-uniqueness check on create. (per-workspace unique constraint on non-empty domain)[☑️]Company merge flagged in P1 (POST-MVP).
- Priority: P0 · Personas: P-1, P-2 · Roadmap: M5 (✅) web; M6 (✅) iOS read-only
- Description: Deal name, value, currency, stage, pipeline, owner, expected close, contact + company FKs, custom fields. Workspace-defined pipelines with ordered stages.
- User stories:
[✅]As a manager, I can create a pipeline and order its stages. (M5.S1)[✅]As a rep, I can drag a deal across stages on a kanban view. (M5.S2 — DnD-kit)[☑️]As a manager, I can switch a pipeline view to a list view. (Kanban-only today; list view post-M14.)
- Acceptance criteria:
[✅]Stage change emits anactivityrow + arecord_field_changedautomation event. (M5 signal handler)[✅]Currency stored in cents; display localized. (value_cents Int + Intl formatter)
- Priority: P0 · Personas: P-1, P-2 · Roadmap: M5 (✅) web; M13 (☑️) iOS tasks tab
- Description: Title, due, owner, polymorphic relation (contact/company/deal), status, priority, custom fields.
- User stories:
[✅]As a rep, I can create a task on any record from its detail view. (M5 TasksTab)[☑️]As a rep, I see today's tasks in a "today" smart view. (Per-record view today; global today list lands at M14.)
- Acceptance criteria:
[✅]Overdue tasks highlight in tan-text accent. (M5 TasksTab CSS)[✅]Tasks scoped per workspace. (WorkspaceScopedManager)
- Priority: P0 · Personas: P-2 · Roadmap: M5 (✅)
- Description: Notes are Markdown bodies attached to records. Activities are append-only event rows: emails, calls, meetings, AI actions, automation runs, field changes.
- User stories:
[✅]As a rep, I can add a note to a contact and edit it within 24 hours. (M5 NotesTab + 24h edit window)[✅]As a rep, I see a chronological activity feed on every record. (M5 ActivityFeed)
- Acceptance criteria:
[🏗️]Activity feed paginates infinite scroll. (Server pagination ready; UI uses default page size today, scroll wired in M14.)[✅]Note edits beyond 24h create an audit trail. (edit_logJSONB + view-level enforcement)
- Priority: P0 · Personas: P-3 · Roadmap: M4 (✅)
- Description: Per-workspace, per-entity custom field definitions. Types:
text,long_text,number,select,multi_select,date,datetime,boolean,url,email,phone,relation. - User stories:
[✅]As an admin, I can add a custom field "Lead Score" of typenumberto contacts.[✅]As a rep, I can filter and sort by custom fields. (filter DSL withcustom.<key>paths)
- Acceptance criteria:
[✅]Adding a field doesn't require a schema migration (JSONB-backed).[☑️]Hot fields can be promoted to indexed expression columns by an admin. (Post-MVP shortcut: a singleindex_nowflag.)
- Priority: P0 · Personas: P-2 · Roadmap: M10 (☑️)
- Description: OAuth-connect a Gmail account. Sync threads + messages to/from contacts. Send mail from inside Offside as the connected user.
- User stories:
[☑️]As a rep, I can connect my Gmail and see threads with each contact.[☑️]As a rep, I can send an email to a contact from inside the contact view.[☑️]As a rep, I receive in-app activity when a contact replies.
- Acceptance criteria:
[☑️]Initial sync ingests last 90 days; ongoing sync is real-time via Pub/Sub push.[☑️]Disconnect revokes tokens server-side.
- Priority: P0 · Personas: P-1, P-2 · Roadmap: M10 (☑️)
- Description: OAuth-connect Google Calendar. Sync events to record activity timelines and trigger automations.
- User stories:
[☑️]As a rep, I see my upcoming meetings on each contact/deal record.[☑️]As a rep, I can create a calendar event from a contact (auto-invite the contact).
- Acceptance criteria:
[☑️]Past meeting summaries (FR-13) appear within 30s of the meeting ending.
- Priority: P0 · Personas: P-1, P-3 · Roadmap: M7 (✅) foundation; M8 (☑️) editor; M9 (☑️) full triggers/actions
- Description: Durable, idempotent workflow runtime built on Celery + Postgres + custom Django layer. Triggers (record events, time, webhook, form, email-received, AI-condition), actions (CRM mutations, comms, logic, AI, HTTP), HITL approval, retries, run inspection.
- User stories:
[🏗️]As an admin, I can build a workflow that triggers on "deal moved to Negotiation" and waits 1 day before drafting an AI follow-up email. (Runtime can execute; visual authoring + AI step handler land in M8 + M11.)[☑️]As a rep, I see workflow runs in a per-record activity feed. (Activity log exists; automation_run signal hook lands with the editor in M8.)[☑️]As an admin, I can replay or cancel a stuck run. (Django admin shows runs; UI controls in M8.)
- Acceptance criteria:
[✅]Worker restart mid-run does not lose state (idempotency + persisted state_snapshot). (M7 chaos test)[✅]HITL approval token signed and single-use; expires in 7 days. (M7 hitl.py)[✅]Run inspector shows step-by-step input/output/cost/latency. (M7 Django admin)
- Priority: P0 (hero) · Personas: P-1, P-3 · Roadmap: M8 (🏗️) canvas + run inspector + versions + describe-in-English shipped; HITL HTTP decide endpoint + undo/redo + type-mismatch validator pending
- Description: The Agent Design Studio is the second of OffsideStudio's two hero surfaces (the first is FR-26 Agents Marketplace). It is the visual authoring + observation environment for every agent in the workspace — whether the agent was installed from the Marketplace, authored from scratch on the canvas, or generated by describing it in English to Claude. The Studio combines: a React-Flow node-graph canvas with a draggable node palette and a per-node config drawer; a Versions panel listing every published
AutomationVersion; a per-run Inspector surfacing step inputs / outputs / cost / latency / idempotency keys; and the Describe-in-English Claude prompt (automations.author_from_nl.v1) that proposes a graph from natural language with a review-before-save gate. - Naming note: formerly referred to as "Workflow node-graph editor" in the v1/v2 PRD. Renamed to Agent Design Studio in PRD v3 to reflect its promoted status as a hero surface in the OffsideStudio — Agent Marketplace positioning.
- User stories:
[✅]As an admin, I can drag nodes onto the canvas and connect them with edges. (M8.S1)[✅]As an admin, I can save a draft and publish it as a new immutable version. (M8.S2)[✅]As an admin, I can describe a workflow in English and let Claude generate the node graph. (M8.S3)[✅]As an admin, I can inspect every step of a run with input / output / cost / latency / idempotency_key visible. (M8.S2 inspector)[✅]As an admin, I can install an agent from the Marketplace and the Studio opens with that agent already published and ready to edit. (FR-26 / M9.S4)[☑️]As an admin, I can undo/redo canvas edits. (M8 punch-list)
- Acceptance criteria:
[🏗️]Canvas renders 100-node workflows without jank.[☑️]Undo/redo for canvas edits.[🏗️]Schema validation prevents publishing a malformed graph. (Client-side validator covers reachability + missing edges + missing per-type config; type-mismatch checks between adjacent nodes pending.)[✅]Marketplace installs land in the Studio with v1 already published.
- Priority: P0 · Personas: P-2 · Roadmap: M11 (☑️)
- Description: Streaming AI drafts, reply suggestions, thread summaries, meeting summaries. Surfaced in every contact + deal view.
- User stories:
[☑️]As a rep, I can ask AI to draft a follow-up email for this contact based on our last 3 messages + deal stage.[☑️]As a rep, I can read a 3-bullet summary of a long Gmail thread.[☑️]As a rep, after a Google Calendar meeting, I can paste the transcript and get a 5-bullet summary written to the deal's activity log.
- Acceptance criteria:
[☑️]First token of a draft arrives ≤1.5s P95.[☑️]Drafts are editable in-place before send.[☑️]Cost shown per generation in admin telemetry.
- Priority: P0 · Personas: P-1, P-2 · Roadmap: M12 (☑️)
- Description: Natural-language queries → structured filter DSL → server-side query → results + AI summary.
- User stories:
[☑️]As a manager, I can type "deals over $10k that went quiet last week" into cmd-K and see a filtered list.[☑️]As a rep, I can save the resulting filter as a saved view.
- Acceptance criteria:
[☑️]NL → filter DSL conversion ≤2s P95.[☑️]Hybrid search (FTS + pgvector rerank) for fuzzy queries.[☑️]Schema-aware prompting: includes custom fields.
- Priority: P0 · Personas: P-2, P-3 · Roadmap: M11 (☑️)
- Description: Background workers populate lead score + company enrichment fields on new contacts/companies.
- User stories:
[☑️]As a rep, when I add a contact with emailjohn@stripe.com, I see Stripe's company size and industry auto-fill within 60s.[☑️]As an admin, I can disable enrichment per workspace.
- Acceptance criteria:
[☑️]Per-workspace daily token budget enforced; over-budget → enqueue + notify owner.[☑️]Manual "re-score" button on each contact.
- Priority: P0 · Personas: P-2 · Roadmap: M11 (☑️)
- Description: Per-record AI suggestion strip. Calm, non-chatbot UX.
- User stories:
[☑️]As a rep, on a quiet deal I see "This deal hasn't moved in 5 days — draft a re-engage email?".[☑️]As a rep, I can dismiss a suggestion or convert it into a task or workflow.
- Acceptance criteria:
[☑️]Max 3 suggestions visible at once; rest in an overflow.[☑️]Dismissed suggestions do not reappear for 7 days.
- Priority: P0 · Personas: P-1, P-3 · Roadmap: M7 (✅) HITL primitive; M13 (☑️) agent loop + UI
- Description: Per-workspace action-mode policy table (
suggest|approve|autonomous). HITL via in-app inbox + email magic-link + iOS push. - User stories:
[🏗️]As an admin, I can set "send email to lead" to require approval but "post Slack notification" to be autonomous. (AgentPolicymodel + enums in M7; policy UI in M13.)[☑️]As a rep, I can toggle "Agent assist" on a specific deal. (M13)[☑️]As a rep, I receive an iOS push when an agent action needs my approval; I can approve/reject without opening the app fully. (M13)
- Acceptance criteria:
[☑️]Reversible actions (notes, drafts) get a 60-second undo affordance after autonomous execution.[☑️]Irreversible actions (sent emails, charged payments — post-MVP) always require approval.[🏗️]Audit log records prompt, model, cost, output, decision, decider. (AutomationStepRuncolumns ✅; agent-action audit row in M13.)
- Priority: P0 (light) · Personas: P-1, P-4 · Roadmap: M14 (☑️)
- Description: Saved-view counters + simple deal funnel + activity-over-time chart.
- User stories:
[☑️]As a manager, on workspace home I see this week's pipeline + the team's activity.[☑️]As a viewer, I can drill from a counter into the underlying records.
- Acceptance criteria:
[☑️]Workspace home loads ≤500ms P95 with cached aggregates.[☑️]Charts respect WCAG 2.2 AA (color is not the sole signal).
- Priority: P0 · Personas: P-2 · Roadmap: M3 (✅) cmd-K skeleton; M4 (✅) filter DSL; M12 (☑️) FTS + vector
- Description: Global cmd-K with FTS + AI-summarized results. Hybrid keyword + vector for fuzzy queries.
- User stories:
[🏗️]As a rep, I can search across contacts, companies, deals, notes, emails from one input. (Cmd-K palette navigates today; record search lands in M12.)[☑️]As a rep, my recent searches are remembered. (M12)
- Acceptance criteria:
[✅]Cmd-K opens in ≤80ms.[☑️]First results render ≤200ms after 3 chars. (Real search results land in M12.)
- Priority: P0 (CSV) / P1 (HubSpot, Pipedrive) · Personas: P-3 · Roadmap: M4 (✅) CSV; M11 (☑️) Claude column mapping; POST-2 (☑️) HubSpot/Pipedrive
- Description: Switching-cost killer: bring your data in 5 minutes.
- User stories:
[☑️]As an admin, I can paste a HubSpot export URL and have contacts/companies/deals mapped automatically. (POST-2)[✅]As an admin, I can review and adjust the mapping before committing. (M4 ImportWizard)[✅]As an admin, I can import a CSV with up to 50k rows. (supported via Celery streaming task; load tested in M15)
- Acceptance criteria:
[🏗️]Mapping suggestions powered by AI; user-correctable. (Heuristic mapper ✅ in M4; Claude promptimports.suggest_column_mapping.v1upgrades it in M11.)[✅]Import runs as a workflow with progress + error report. (ImportRunmodel + 1.5s-poll wizard)
- Priority: P0 · Personas: P-1, P-3 · Roadmap: M9 (☑️)
- Description: OAuth-connect a Slack workspace. Workflow action: post to channel/DM. In-app notifications also routable to Slack.
- User stories:
[☑️]As an admin, I connect Slack and choose channels for different notification types.[☑️]As a rep, I see workflow output in #sales when configured.
- Acceptance criteria:
[☑️]Disconnect revokes tokens; existing workflow steps that point at Slack pause until reconnected.
- Priority: P0 · Personas: P-3 · Roadmap: M9 (☑️)
- Description: Inbound webhook endpoints (per-workspace HMAC) and outbound HTTP step for workflows.
- User stories:
[☑️]As an admin, I can copy a unique webhook URL and POST data to it from any system.[☑️]As an admin, I can add an HTTP request step in a workflow with custom headers + auth.
- Acceptance criteria:
[☑️]Webhook payloads logged for 7 days for debugging.[☑️]HTTP step supports basic + bearer + custom-header auth presets.
- Priority: P0 · Personas: P-1, P-2 · Roadmap: M6 (✅) read-only shell; M13 (☑️) full edit + push
- Description: SwiftUI app with full read+edit on contacts/deals, push notifications, HITL approval surface.
- User stories:
[🏗️]As a rep, I can sign in on iPhone, browse my pipeline, and edit a deal. (Sign-in + browse ✅ in M6; edit lands in M13.)[☑️]As a manager, I receive an APNs push when an agent action needs approval; I can approve/reject from the lock screen action. (M13)
- Acceptance criteria:
[✅]App launches to "today" view ≤2s on a 3-year-old iPhone. (M6 cold start)[☑️]Offline read for last 50 visited records; edits queue and sync on reconnect. (M13 + M15 polish)[☑️]App Store review checklist locally green. (M15 + TestFlight)
- Priority: P0 · Personas: P-1, P-2, P-3 · Roadmap: M2 (✅) Resend invites; M13 (☑️) in-app + iOS push
- Description: In-app inbox + email (Resend) + iOS push (APNs). User-controlled per-channel preferences.
- User stories:
[☑️]As a rep, I can disable email fortask_due_soonwhile keeping push on. (M13)[☑️]As an admin, I can see which notifications were sent in the last 7 days. (M13)
- Acceptance criteria:
[☑️]Quiet hours per user (no push between 9pm–7am local by default).[☑️]HITL approval pushes always bypass quiet hours.
- Priority: P0 · Personas: P-3 · Roadmap: M5 (✅) Activity model + signals; M14 (☑️) admin UI + CSV export
- Description: Append-only
activityrows already cover most actions; admin UI surfaces a filterable log. - User stories:
[🏗️]As an admin, I can see who changed which deal stage in the last 30 days. (Data exists inActivitytable from M5; filter UI lands in M14.)[☑️]As an admin, I can export an audit slice as CSV. (M14)
- Acceptance criteria:
[✅]90-day retention in MVP; longer retention is post-MVP enterprise (POST-5).
- Priority: P0 (the headline of the product) · Personas: P-1, P-3 · Roadmap: M9.S4 (✅) backend + frontend + 15-agent catalog + demo seed + presenter script (
DEMO.md) shipped. 9 categories covering the full ecommerce lifecycle (Lead management · Cart recovery · Communications · Fulfillment · Payments · Customer service · Deal hygiene · Integrations · Operations). - Demo headline: 🚀 Ecommerce Conversion Funnel Optimizer — the catalog's hero agent. A 10-node manual-triggered workflow that orchestrates the full funnel in one click: marketing campaign launch → AEO content seed → ad-platform sync → landing-page generation → CRM company record → email welcome task → cart-recovery task → payment-confirmation task → deployment-summary note. Every step is inspectable (input / output / cost / latency / idempotency_key). The stage-demo narrative leads with this agent — install it, run it live, switch to Companies to see the records the agent just created.
- Description: The Agents Marketplace is the headline surface of OffsideStudio. It is the first place a new admin lands; it is the answer to "what is this product?"; it is the demo opener. The Marketplace is a curated, workspace-agnostic catalog of pre-built workflow agents spanning the full ecommerce lifecycle — Lead from form, Welcome series — day 0, Abandoned cart recovery, Order received, Shipping dispatched, Payment success, Failed payment retry, Refund request handler, Post-purchase review request, Repeat-purchase nudge, plus the foundational Lead qualification, Welcome new contact, Deal pulse, and Outbound HTTP ping. An admin browses the catalog (
/marketplace/), filters by lifecycle category, previews an agent's node graph in a read-only canvas, and installs it into their workspace with one click. Installation creates a brand-newAutomationrow, snapshots the marketplace agent's graph + trigger into an immutable publishedAutomationVersion, sets the workflow toACTIVE, resolves any__INSTALLER__sentinel fields to the installer's user pk, and routes the user directly into the Agent Design Studio (FR-12) so the workflow is editable from second one. The Marketplace is the "blank-canvas → running workflow in 10 seconds" surface; the Design Studio is the "now customize it to your team" surface. The two pair tightly and lead the product's UX hierarchy. - Selling proposition usage: "OffsideStudio — Agent Marketplace" is the default product selling proposition. The Marketplace surface is what the phrase points at. Use the phrase in the empty state for
/automations, in the welcome onboarding, in the marketing site copy, and in the demo opening line. - Distinct from POST-15 (third-party developer marketplace + extensions, out-of-MVP): FR-26 is a curated, internal-only catalog of workflow templates. POST-15 expands this with developer onboarding, monetization, and signed extensions.
- User stories:
[✅]F26.S1 — As an admin, I can browse the marketplace catalog of pre-built agents with category filter + preview of the node graph. Grid at/[workspace]/marketplace/ships; detail page renders the agent's graph in a read-onlyWorkflowCanvas.[✅]F26.S2 — As an admin, I can install an agent into my workspace with one click and the new workflow opens in the canvas as a published version I can edit. Install API +useInstallMarketplaceAgenthook + post-install redirect into the editor all shipped.[✅]F26.S3 — As an admin, I can see which marketplace agents are already installed in my workspace (install_count + per-workspaceWorkspaceAgentInstallrows). Catalog grid shows install_count badge; per-workspace install rows live in Django admin.[☑️]F26.S4 — (v2 placeholder) As an internal curator, I can submit + version-publish agents to the catalog via Django admin or a dedicated tool. v1 seeds viatools/seeds/marketplace.py(14 agents).
- Acceptance criteria:
[☑️]Public catalog endpointGET /api/marketplace/agents/returns curated agents with metadata (name, slug, description, category, icon_emoji, install_count) — workspace-agnostic, no auth required so the marketplace is shareable.[☑️]Install endpointPOST /api/marketplace/agents/{slug}/install/(workspace-scoped, manager-gated) creates anAutomationin the requesting workspace, snapshots the agent's graph + trigger into a newAutomationVersion, pointsautomation.published_versionat it, and setsautomation.status = ACTIVE. Records aWorkspaceAgentInstallaudit row.[☑️]Installed agents are immediately editable + republishable from the M8 canvas — no "managed/installed" lock-down. The agent is a starting point.[☑️]4–6 seeded agents span variety: record trigger + log/Slack notify, schedule + email-summary, webhook + CRM mutate, branch + approval HITL, loop over a list. Each seed agent uses only the currently-shipped action types.[☑️]Workspace isolation: install rows scope per workspace; the catalog itself is global.[☑️]TC-92..TC-94 cover catalog list (anon-readable), install round-trip (manager-only + published version created), edit-after-install (changes don't propagate back to the catalog).
NFRs are quality bars rather than discrete deliverables. Most are partially in place from day one and tighten as the project matures; M15 polish formalizes the CI gates.
Roadmap: M3 (✅) cmd-K open ≤80ms; M15 (☑️) full P95 budget enforcement
[✅]Cmd-K open ≤80ms.[☑️]First results ≤200ms after 3 chars. (M12)[🏗️]Page-to-page nav P95 ≤300ms (RSC + cached data). (Working today; CI budget in M15.)[☑️]AI streaming: first token P95 ≤1.5s. (M11)[✅]iOS app cold start P95 ≤2s on 3-year-old hardware.[✅]Workflow advancer step latency P95 ≤500ms (excluding intentional waits/AI). (M7)
Roadmap: M3 (✅) keyboard + skip link + reduced motion; M15 (☑️) axe CI + screen reader pass
[✅]Keyboard navigation across every flow (cmd-K, j/k, slash, esc). (j/krow nav lands with M4 list views and is in place.)[✅]prefers-reduced-motioncollapses all animations.[✅]Focus-visible ring on every interactive element (tan, 2px, 2px offset).[✅]Color is never the sole signal (status pills include label text + tone).[✅]Skip link on every page.[☑️]Axe-clean on all top-level routes; manual screen-reader pass before each release. (M15)
Roadmap: M1 (✅) auth + HMAC plumbing; M2 (✅) tenant isolation
[✅]All endpoints require JWT except/auth/*and/health.[✅]Tenant isolation enforced at the ORM layer (WorkspaceScopedManager) + verified by tests.[✅]Secrets never logged; Sentry scrubs PII.[☑️]All OAuth tokens encrypted at rest with a workspace-scoped key. (Lands with M9 Slack + M10 Gmail.)[✅]HMAC on inbound webhooks; signed approval tokens for HITL (single-use, 7-day TTL). (HITL ✅ in M7; webhook HMAC in M9.)[☑️]Rate limiting on auth + AI endpoints. (allauth has rate-limits; AI endpoints rate-limited at M11.)
Roadmap: M0 (✅) Sentry config; M11 (☑️) AI telemetry
[✅]Sentry on web + iOS + Django + Celery worker. (SDKs wired; DSN env var.)[🏗️]Structured logs with correlation IDs (request id, workspace id, user id). (workspace_id in JWT auth; full correlation in M9.)[☑️]Per-AI-call telemetry: prompt name, model, tokens, cost, latency. (M11)[✅]Run inspector for every workflow run with full step trace. (M7 Django admin)
Roadmap: M0 (✅) tokens + components shipped; enforced in every subsequent milestone
[✅]All UI surfaces consumepackages/uitokens. No bespoke colors or fonts.[✅]Saturated blue/purple/cyan never appears. Tan is emphasis, never fill.[✅]Light-first; dark surfaces are scoped per section, never global.[✅]Voice is engineer-to-engineer; no breathless adjective stacking.
Roadmap: M11 (☑️)
[☑️]Per-workspace daily AI token budget; over-budget → enqueue + admin notification.[☑️]Provider fallback (Claude → OpenAI/Gemini) on outage or cost spike.[☑️]Anthropic prompt caching for system prompts and large reference docs.[☑️]Embeddings written async, batched, deduped by content hash.
Roadmap: M7 (✅) idempotency + advancer guarantees; M15 backups
[✅]Worker restart preserves all in-flight workflow runs. (M7 chaos test)[✅]Idempotency keys on every workflow side effect.[☑️]Backups: managed Postgres point-in-time recovery; nightly logical dump to object storage. (Configured at first deploy, M15.)[✅]Beat wake-up sweep tolerates 60s jitter for delays/waits in MVP.
Roadmap: M2 (✅) workspace isolation; M15 (☑️) right-to-delete
[✅]All data is workspace-scoped. No cross-workspace leakage.[☑️]AI prompts never leak data from one workspace into another's context. (Cache keys workspace-scoped at M11.)[☑️]Right-to-delete: workspace owner can request a hard delete that cascades within 30 days. (M15 polish + POST-5 retention controls.)
- Stack: Next.js 15 (Vercel) + Django 4.2 + DRF + Celery 5 + Redis + Postgres 16 + pgvector + SwiftUI iOS 17+.
- Hosting: Vercel (web) + Digital Ocean App Platform (Django web/worker/beat) + DO Managed Postgres + DO Managed Redis.
- AI: Anthropic Claude as default; OpenAI/Gemini fallback. No other providers in MVP.
- Brand: OffsideAI Design System v1.0 is authoritative; production CSS at
OffsideLabs-AI/offsidelabs-ai-web/assets/css/tailwind.css. - Compliance: No GDPR/HIPAA/SOC2 for MVP. Right-to-delete (NFR-8) only.
- Browser support: Last 2 stable versions of Chrome, Safari, Firefox, Edge. No IE.
- iOS: iOS 17+, iPhone only in MVP (iPad post-MVP).
| Metric | Target (3 months post-launch) |
|---|---|
| Time-to-first-workflow-published | ≤15 minutes from signup |
| Daily active reps per workspace | ≥60% of provisioned seats |
| AI feature adoption (any AI surface used in last 7 days) | ≥80% of active reps |
| Workflow runs per workspace per week | ≥50 |
| HITL approval rate (approve / total) | ≥90% (proxies "agent suggestions are good") |
| iOS WAU as % of total WAU | ≥35% |
| Workspace 30-day retention | ≥70% |
| Switch-from-other-CRM share (qualitative interviews) | ≥30% mention HubSpot/Pipedrive/Attio as prior tool |
Placeholders deliberately enumerated so we do not redebate in MVP scope reviews. Real prioritization happens after launch + first cohort of users.
- Subscription plans, seat-based pricing, per-workspace metering for AI tokens, free trial, usage caps, dunning.
- HubSpot full bidirectional sync, Pipedrive sync, Salesforce, Linear, Notion, Microsoft 365 (Outlook + Teams + OneDrive), Zoom, Twilio (SMS/calls), DocuSign, Stripe (as a CRM data source). Pattern: each is its own connector + workflow trigger/action set.
- Localization framework, translation pipeline, RTL support evaluation.
- Kotlin Multiplatform vs native Android Compose decision deferred.
- WorkOS or built-in SAML/OIDC, SCIM provisioning, 7-year audit retention, custom role builder, per-workspace sandbox environments.
- Separate product. Shares
packages/ui+packages/ai+packages/auth-utils. Distinct backend.
- Separate product. Same shared-package philosophy.
- Separate product. Same shared-package philosophy.
- Multi-step planning across many records, agent-to-agent handoff, autonomous prospecting from public data, voice-call agents.
- Sub-workflows (call workflow A from workflow B), parallel fan-out + join, durable workflow versioning beyond MVP "publish new version" semantics, conditional rollout (10% of records first), workflow templates marketplace.
- Custom dashboards builder, scheduled report email, BI-quality drill-downs, exportable CSV/Excel, formula fields, lookup fields.
- iPad layout, Apple Watch complications, Mac Catalyst, offline-first edits with conflict resolution, full-text search on-device.
- SOC2 Type 2, ISO 27001, GDPR DPA, regional data residency (EU, APAC), HIPAA where vertical-relevant.
- Rate-limited per-workspace API tokens, public OpenAPI spec, sample SDKs, developer docs site.
- Successor to FR-26's curated catalog: third-party developer onboarding, monetization, signed extensions (custom workflow nodes contributed by partners, workspace-installable AI prompts, branded automation templates from agencies). FR-26 ships the v1 curated catalog; POST-15 opens it up.
- Pricing model. Per-seat? Per-workflow-run? Per-AI-token? Hybrid? Default hypothesis: per-seat with AI-token soft caps.
- Free tier shape. Time-limited trial vs forever-free with limits?
- Target wedge customer. SMB sales (locked) but which sub-segment first? B2B SaaS sales is the most likely beachhead given AI-native fit; agencies are second.
- Onboarding sequence. Empty workspace → guided import → guided first workflow? Or "magic" pre-built starter workspaces per industry?
- Public marketing site. Reuse
OffsideLabs-AI/offsidelabs-ai-webcontent? Net-new copy? Decision affects launch timing.
- FR-N / NFR-N / POST-N are stable identifiers. Renumber only by appending; never reuse a retired ID.
- All linked artifacts: PLAN.md, TESTING.md, ROADMAP.md.
- This PRD lives at HEAD on
main. Substantive changes get a "v2 / v3 …" header bump. - Status checkboxes:
[✅]implemented,[🏗️]partial,[☑️]pending — must stay in sync with ROADMAP.md.
- v1 — 2026-05 — initial PRD shipped alongside PLAN.md / TESTING.md / ROADMAP.md.
- v2 — 2026-05 — added
[✅]/[🏗️]/[☑️]status checkboxes on every FR / NFR / user story / acceptance criterion. Added "Roadmap mapping" lines so each requirement points at the milestone(s) that ship it. Aligned with ROADMAP.md Revision 2 (M0–M7 complete). - v3 — 2026-05 — added FR-26 — Agents Marketplace v1 (P0, demo-critical) covering a workspace-agnostic curated catalog + one-click install + 4–6 seeded agents, mapped to ROADMAP M9.S4. Clarified POST-15 as the third-party developer marketplace successor to distinguish it from FR-26.
- v3.1 — 2026-05 — Repositioned the entire product around "OffsideStudio — Agent Marketplace" as the default selling proposition. Executive summary + vision rewritten to lead with the Marketplace + Design Studio hero pairing. FR-12 renamed from "Workflow node-graph editor" to "Agent Design Studio" (★ hero surface). FR-26 promoted to ★★ hero surface with explicit "the headline of the product" framing. CRM record/pipeline experience repositioned as the underlying data layer that the agents act on, rather than as the primary surface. Companion edits to PLAN.md, ROADMAP.md, CLAUDE.md, MEMORY.md, TESTING.md.
- v3.2 — 2026-05 — FR-26 marked
[✅]. M9.S4 fully shipped: backend + frontend (/marketplacegrid + detail with read-only canvas preview + one-click install + sidebar repositioning) + 15-agent catalog spanning the full ecommerce lifecycle across 9 categories + demo workspace seed (tools/seeds/demo_workspace.pywith sample contacts / companies / deals / tasks / notes) + presenter script (DEMO.md). Demo headline is now the Ecommerce Conversion Funnel Optimizer hero agent — a 10-node manual-triggered workflow that choreographs marketing campaign launch → AEO seed → ad sync → landing pages → email welcome → cart recovery → payments → deployment-summary note in one click. - v3.3 — 2026-05 — added §2.1 Competitive positioning ("why not n8n / Zapier?") — the canonical answer to the most common demo objection. Five differentiators (shared data model + event bus, opinionated marketplace agents, AI as authoring layer, single-product TCO, per-step cost telemetry + immutable versioning), a counter-objections table, and demo guidance. Source of truth for sales enablement + any future
platform.offside.ai/vscomparison page.
PRD.md ends.