Quorum — Moments That Matter

living document; trim to v1 when we pick winners
Last updated: 2026-05-18 5:39 PM (2w ago)

Change log

Version Date Change Author
0.7 2026-05-18 Added #61 The team room becomes a real product surface and #62 Design briefs become versioned artifacts in Build and implementation. #61 captures the moment when /w/<id> crosses from a placeholder ("Team room lands in Story 2.1") to a functioning floating-panels shell — the full 19-step methodology rail, named agent roster with role hues + streaming reticles, stage card with disabled-until-typing AI assist, live Idea statement artifact in the right rail, working light + dark themes with Kinsley's morning-studio rebuild, theme switcher with localStorage persistence, sign-out at the bottom of the nav, and the digital-planet backdrop reused from /sign-in for visual continuity. The screen is static — no real AI yet — but the grammar of the conductor model is now legible at first glance. #62 captures the moment when design briefs stop being chat scrollback and become a git'd library at design-briefs/ — a token preamble that locks the visual system, a queue prioritized by interview impact, a shipped-reference brief that anchors Claude Design to what's actually live, plus a live-snapshot pipeline that captures the team-room as a self-contained HTML file before each Claude Design session. Both are builder / team moments. Kinsley + Quentin
0.6 2026-04-29 Added #59 The team becomes visible and #60 The design system stops being a screenshot in Build and implementation. Both surfaced by the 2026-04-29 portfolio centerpiece push. #59 captures the moment when the agent roster crosses from a list in the PRD to a navigable, designed surface — three pillar cards with 22 agents organized by lens, each with named methods and artifacts. #60 captures the moment when the design-system page in the planning exports stops being a static reference and becomes a live React app embedded in the portfolio surface — visitors can click the modal triggers, fire toasts, drive the Select listbox, and see the slide-swap animation, all from inside Quorum's chrome. Both are builder / team moments rather than user-facing. Quentin
0.5 2026-04-28 Added #58 First automated WCAG AA gate goes green in Build and implementation. Surfaced by the 2026-04-27/28 wider a11y audit in quorum-app: 12 distinct page-states (design-system at rest + with modal open, /sign-up, /sign-in, /workspaces picker, /w/<id>, /w/<id>/members in both team and solo_free variants, /new-workspace landing + plan-change, modal-open on the picker, /sign-up/pay) all clear axe-core's critical+serious filter at WCAG 2.1 AA. The first axe pass on /design-system caught two real production contrast bugs on shared chrome (.app-modal__btn-danger, .app-ws-card__updated-abs) — the live-reference page worked exactly as designed. This entry isn't about a public-facing user moment; it's the team / builder peak when "a11y as floor, not ceiling" stops being a phrase and starts being a CI gate. Quentin
0.4 2026-04-23 Added 3 new moments in Organize and filter to cover the three-pillar checkpoint-gate framework landed in the PRD on the same day (FR25b, FR25c, FR25d, Story 4.7): #55 First pillar gate verdict (pass / fail / needs revisit), #56 "Needs revisit" blocks advancement, #57 "Why this verdict?" drill-down. Partners-with list unchanged. Quentin
0.3 2026-04-23 Added 4 new moments surfaced by the 2026-04-23 content-strategy work: #54 Accessibility statement discovered (Team and enterprise), #51 First release notes read (Post-ship), #52 Page not found (404) and #53 Server error mid-work (Valleys and endings). Added 3 new partner docs to the "partners with" list (release-notes-format, accessibility-statement, error-pages). Moment IDs past 50 are stable identifiers, not strict sequence — new moments are placed in their logical group regardless of ID order. Quentin
0.2 2026-04-22 Added per-moment Screens to capture and How to reach fields across all 50 moments. Added "Screenshot capture conventions" section with naming, storage, resolution, and distinction from portfolio-capture screenshots. Added screenshot-discipline commitment. Added screenshot-capture ownership row. Updated copy-hook version tags from v0.1 to v0.2. Quentin
0.1 2026-04-22 First generous inventory. 50 moments across 11 groups. Mapped to PRD FRs, epics, and existing quorum-app artifacts. Quentin

What this is

The voice and tone guide says how Quorum sounds. This document says where it matters most. It inventories the peaks, valleys, and transitions across the full user lifecycle where copy, design, and product logic decide whether Quorum earns trust or loses it.

v0.2 is intentionally generous. The goal is to surface every moment worth thinking about, including the valleys that don't appear in happy-path FRs. v1 will trim to the ones we treat as first-class product surfaces with dedicated design, copy, motion, and screenshot work.

This document partners with:

Screenshot capture conventions

Every moment below specifies Screens to capture (the specific UI states worth documenting) and How to reach (the navigation or trigger condition that gets you there).

Storage: _bmad-output/planning-artifacts/moments-screenshots/

Naming: moment-NN-description.png where NN is the moment number zero-padded (01 through 54). Description is kebab-case, short, specific. Examples: moment-01-landing-popover-open.png, moment-04-payment-declined.png, moment-33-release-blocked.png, moment-52-page-not-found.png.

Mobile variants: append -mobile to the description. Example: moment-01-landing-popover-open-mobile.png.

Format: PNG. Desktop resolution 1440×900. Mobile resolution 375×812 (iPhone 14 Pro standard).

Capture moment: each screenshot should represent the moment at its truest state. For peaks, capture the best-case on-voice rendering. For valleys, capture the failure mode (decline error, stall nudge, quota hit, hallucination caught). Both are valuable for the portfolio doc (FR47) and for future UX audits.

Who captures: primarily Jaymes during in-context passes; Kinsley during design review; James ad-hoc during his builder journey. Quentin flags what is worth capturing during release skims; James decides per the portfolio-capture workflow.

Distinction from portfolio capture: _bmad-output/portfolio-capture/screenshots/ holds personal-journey screenshots (first localhost, first stack decision, etc). The moments folder holds product-surface screenshots illustrating the user's journey at each documented moment. Both feed the Portfolio Document per FR47.

How to read each moment

Every moment has this shape:


Lifecycle map

Eleven groups. Fifty-four moments. Numbered for reference in sprint planning and screenshot naming. IDs past 50 are stable identifiers placed in their logical group regardless of strict numerical sequence (so a group's moments aren't always contiguously numbered — that's fine).

Pre-account (1–6): anonymous visitor through payment confirmation. Account and entry (7–9): first authenticated load through pipeline orientation. Discovery and ideation (10–12): Kitchen Sink framework through concept sync. Organize and filter (13–16): themed groupings through release allocation. Artifact production (17–22): PRD through pitch. Team and enterprise (23–28, 54): invites through admin; accessibility statement discovery. Build and implementation (29–34): story export through ship. Post-ship (35–37, 51): metrics through portfolio document share; release notes read. Recovery and continuity (38–41): return, stall, resume, support. Valleys and endings (42–47, 52, 53): declined payment through canceled subscription; 404; server error. Cross-cutting (48–50): save points, agent turns, notifications.


Pre-account

1. First landing on quorum.app

Type: Transition (anonymous visitor first impression). What happens: Visitor arrives cold. Sees the hero, the value prop, and the team popover that reveals the 21-agent roster. Why it matters: First seven seconds decide whether they stay or bounce. Quorum's claim (named agents are the team, not a chat sidebar) has to land in a scannable way. Failure mode: Hero that reads like every other AI-SaaS landing page. Generic CTA. Team-popover feature hidden or unclear. Visitor bounces. Ownership: Voice and marketing copy = Quentin. Hero layout and visual hierarchy = Kinsley. Team popover component and motion = Jaymes + Luca. Positioning = Sophia + John. Maps to: - Existing quorum-app: src/app/sign-up/LandingAndGrid.tsx, src/app/sign-up/TeamPopover.tsx, src/app/sign-up/sign-up-scene.css. - Roster data: src/features/team/roster.ts (21 agents). Screens to capture: Landing cold on /. Landing with team popover open. Landing on mobile. Landing with prefers-reduced-motion enabled. How to reach: visit quorum.app in incognito or a private window. Popover opens by clicking the "Twenty-one agents" trigger. Mobile = responsive mode at 375×812. Reduced-motion = system accessibility setting on. Copy hooks (v0.2): - Team popover trigger label: "Twenty-one agents" (clear, confident, specific). - Popover title: "Your Quorum team" (possessive matters: theirs from moment one). - Hero headline candidate: "Agents that argue with you, not agree with you."

2. Plan selection pre-auth

Type: Transition (browse to commit). What happens: Visitor sees the 4 plans (2 categories, 2 tiers each) and picks one before creating an account. FR48 and FR49. Why it matters: Plan-first flow is the key differentiator from free-trial SaaS. Commitment happens early. Copy has to make tier differences honest and navigable. Failure mode: Dense feature-comparison tables. Hidden limits that surface post-payment. User picks wrong tier and churns when they feel trapped. Ownership: Tier copy and comparison labels = Quentin. Pricing layout and hierarchy = Kinsley. Plan data model = Damien. PM framing = John. Maps to: - FR48, FR49, Epic 1.3.2. - Claude Design v2 output: Pay page exists in _bmad-output/planning-artifacts/claude-design-outputs/. Screens to capture: Plan grid (all four plans, no selection). Plan selected (one card active). Plan grid on mobile. Individual tier detail expansion (if any). How to reach: from landing, click primary CTA that routes to the plan-selection step. Usually /sign-up/plan or similar. Copy hooks (v0.2): - Tier names: plain. "Solo," "Solo Plus," "Team," "Team Plus." No "Enterprise." - Limits language: state the limit, name the upgrade path. "Three workspaces. More on Solo Plus." - CTA: "Start on Solo" (verb that matches the commitment).

3. Account creation with plan selected

Type: Transition (anonymous to authenticated). What happens: User provides credentials. Workspace is created and bound to the chosen plan. Why it matters: Classic form-filling valley. Form errors here kill roughly 30% of signups. Copy has to guide without nagging. Failure mode: Generic validation. Required fields without clear labels. Account created but workspace confused. Ownership: Form microcopy = Quentin. Form layout and input types = Kinsley. Auth implementation = Damien. Post-creation routing = Jaymes. Maps to: FR2a, FR1, FR49. Story files 1-3-sign-in-and-workspace-membership.md, 1-3-2-self-signup-with-plan-type.md. Screens to capture: Empty form. Filled form before submit. Per-field validation errors (email invalid, password too short, etc.). Submission loading state. Success confirmation. How to reach: complete plan selection, arrive at credentials form. Trigger validation by submitting invalid inputs deliberately. Copy hooks (v0.2): - Validation formula: "Password needs 8+ characters and one number." - Success: "Workspace created. Let's bring in the team."

4. Payment / billing first touch

Type: Valley (peak anxiety in the pre-account flow). What happens: User enters card details. Stripe handles tokenization. Payment succeeds or fails. Why it matters: Money is where users get nervous. Trust signals, clarity, and honest decline messaging decide whether they complete or bail. Failure mode: Generic "an error occurred." Empty loading states that imply double-charge. Decline messaging that blames the user. Ownership: Billing copy = Quentin + Damien. Stripe integration = Damien. Trust signals and flow = Kinsley. Maps to: Story file 1-3-2-design-notes.md (has payment flow + dev test-data button spec). FR42, NFR-S2. Claude Design v2 Pay page. Screens to capture: Empty pay form. Pay form filled (test data). Processing state. Decline error (specific reason shown). Success confirmation. Receipt email render (separate capture). How to reach: after account creation, arrive at /sign-up/pay. Use the dev-only "Fill test data" button (dev-environment only) to prefill test-card values. Stripe test cards for specific states: 4242 4242 4242 4242 (success), 4000 0000 0000 0002 (generic decline), 4000 0000 0000 9995 (insufficient funds). Copy hooks (v0.2): - Pre-submit reassurance: "Cancel anytime. No questions." - Declined: "Your card was declined. Try another, or update your details in Settings." - Success: "Payment confirmed. Workspace is yours."

5. Returning sign-in

Type: Transition (lower intensity than 3, but has its own valleys). What happens: Existing user signs in on known or new device. Why it matters: Frequent event. Small friction compounds. 2FA, password reset, new-device flows are valleys inside a minor peak. Failure mode: Password-reset email that takes 20 minutes. Generic "Invalid credentials." Forgot-password flow that dead-ends. Ownership: Sign-in copy and error handling = Quentin. Auth UX = Kinsley. Auth backend = Damien. Cross-context session per Epic 10 = Damien + Jaymes. Maps to: FR2. Epic 1 Stories 1.3. Epic 10 Story 1.P2 (session portability). Screens to capture: Sign-in form empty. Sign-in filled. Wrong-password error. Forgot-password flow (request email, check-email state, reset form). New-device prompt. 2FA prompt if applicable. How to reach: visit /sign-in as returning user. Trigger errors with wrong credentials. Trigger forgot-password from the link. Trigger new-device by signing in from a different browser or user-agent. Copy hooks (v0.2): - Forgot-password CTA: "Reset password." - Wrong-device messaging: "New device detected. We sent a code to your email."

6. Email verification

Type: Transition (bureaucratic necessity). What happens: User clicks the verification link in email. Account activates. Why it matters: Small moment, high drop-off. Bad spam filtering or unclear expectations loses users entirely. Failure mode: Email hits spam. User confused about whether verification is required. Link expires before click. Ownership: Email copy = Quentin. Email template design = Kinsley. Email deliverability and send = Damien. Maps to: FR2 (auth), standard auth hygiene. Screens to capture: Verification email rendered in inbox (Gmail desktop, Apple Mail, mobile Gmail). Verification-success landing page. Expired-link state. Resend-verification flow. How to reach: sign up with a real inbox. Capture email from inbox client. Click link. Separately hit an expired-link URL by waiting past the token TTL (or construct a stale URL). Copy hooks (v0.2): - Subject line: "Verify your Quorum email." - Body opening: "Click the button below to confirm this email is yours." - CTA: "Verify email."


Account and entry

7. First landing post-signup

Type: Peak (the threshold moment). What happens: User enters an empty workspace for the first time. The product has to orient without overwhelming. Why it matters: The "now what?" moment. Too many tooltips feels like work. Blank page feels abandoned. Failure mode: Tutorial carousel that blocks the UI. Or blank state with no next step. Ownership: First-run copy = Quentin. First-run flow and visual orientation = Kinsley. Onboarding motion = Luca. Activation logic = Jaymes + Damien. Maps to: FR7 (team room), Journey 1 opening for Maya, Journey 6 opening for recovery. Screens to capture: Empty workspace on first load. Primary CTA prominent. Welcome-line visible. Alternative first-run states (if invited vs self-signup). How to reach: complete signup with a fresh email. Land on the post-signup route (typically /workspace/[slug] or similar). Copy hooks (v0.2): - First-line: "Welcome. Let's get your vision on paper." - CTA: "Start with an idea."

8. First agent encounter

Type: Peak (sets the tone for the whole relationship). What happens: User meets their first agent, almost always John or Mary. Agent introduces themselves and asks the first real question. Why it matters: Quorum's claim about structural differentiation lives or dies here. Generic AI voice kills the product's promise. Failure mode: "Hi! I'm your AI product manager. Let's get started!" Hollow and tool-shaped. Ownership: Agent voice and intro copy = Quentin. Agent visual presence = Kinsley. Agent entrance motion = Luca. Agent routing = Jaymes. Maps to: FR7, FR8, PRD §quorumAgentRoster. quorum-app/src/features/team/roster.ts. Screens to capture: Team room on first load (before any message). John's intro message. Agent avatar + name + title visible. Close-up of the first question agent asks. Same for Mary if discovery path chosen. Agent switch indicator (who is active now). How to reach: new workspace, trigger the first pipeline step. Path depends on chosen entry flow (idea-driven → John; discovery-driven → Mary). Copy hooks (v0.2): - John's opening: "I'm John. I'll help you turn your idea into a PRD. First question: what problem are you actually trying to solve?" - Mary's opening: "I'm Mary. I'll dig into what's already out there before we design anything new. Tell me about the people who'll use this."

9. Pipeline orientation

Type: Transition (just-in-time learning). What happens: User sees how the pipeline works for the first time. The 13-step map from idea to portfolio. Why it matters: Methodology-as-product claim. Understanding the rails builds trust; not understanding means they get lost. Failure mode: 13-step progress bar that looks exhausting. Or no orientation and they wander. Ownership: Orientation copy = Quentin. Pipeline visualization = Kinsley. Step transitions = Luca. Pipeline state logic = Jaymes. Maps to: FR7 through FR13 cluster, Epic 2. Screens to capture: Pipeline map at first reveal. Current step highlighted, done checked, upcoming ghosted. Hover state revealing step details. Collapsed minimap. Full-screen map view if it exists. How to reach: after first agent encounter, when pipeline map first surfaces. Typically triggered by a "see the whole journey" button or on step 2 entry. Copy hooks (v0.2): - Not-a-tutorial: "Twelve steps. You drive. Stop, save, come back at any step."


Discovery and ideation

10. First full Kitchen Sink ideation session

Type: Peak (deep engagement high). What happens: User runs the 8-category framework end-to-end, producing the four structured deliverables. Why it matters: Quorum's most novel work. Rigid categories → shallow output. Conversational categories → real thinking. Failure mode: Eight rigid forms in sequence. Agents that don't challenge. Template-shaped output. Ownership: Category prompts = Quentin. Session pacing and agent handoffs = Bob. Agent voices = each agent. Overall flow = Kinsley. Maps to: FR14, Epic 2. Screens to capture: Category 1 intro. Category in-progress with user response. Handoff between categories. Final summary with four deliverables. Individual deliverable view (Problem/Solution Framing, Features, Master Prompt, per-Screen Prompts). How to reach: start Kitchen Sink from pipeline step 1. Walk through all 8 categories to completion. Copy hooks (v0.2): - Category intros: one sentence context, one concrete example, one open question. - Inter-category transitions: "Good. That gave us X. Next up: Y."

11. First agent pushback

Type: Peak (the structural-differentiation promise made real). What happens: User gives an answer and an agent pushes back. Why it matters: Core promise. No pushback = chat sidebar. Hostile pushback = users quit. The line is opinionated without combative. Failure mode: Too soft ("I noticed you might want to consider..."). Too hard ("That's wrong."). No pushback at all. Ownership: Pushback copy patterns = Quentin (craft-heavy). Agent persona = PRD/manifest. Tone calibration by agent = Quentin + John. Maps to: FR10, FR25. Screens to capture: User's ambiguous message. Agent pushback bubble clearly differentiated visually. Branching response options (accept challenge, clarify, push back on the pushback). Resolution state. How to reach: during any pipeline step, give an ambiguous answer (e.g., "users" without specifics, "make it better" without criteria). Or direct-prompt the agent with something clearly handwavy. Copy hooks (v0.2): - Pushback formula: "I hear X. Before we lock it in, try this: [specific challenge that opens a door, not a trap]."

12. First live concept sync from Kinsley

Type: Peak (design-as-product moment). What happens: Kinsley updates concept visuals live during the three-pillar filter. Why it matters: Kinsley is the evidence that Quorum's agents are not stock. Live design response to filter decisions is tactile proof. Failure mode: Static mockups. Or updates that feel random. Ownership: Update messaging = Quentin + Kinsley. Live-sync UX = Kinsley. Motion of update = Luca. Technical sync = Jaymes + Damien. Maps to: FR17, FR18, FR24. Screens to capture: Concept board before filter decision. Update notification appearing. Concept board after update with diff callout. Motion sequence (if recorded as animated PNG / video). How to reach: run the three-pillar filter with concept visuals attached. Pick a filter outcome that would change concept scope; watch Kinsley refresh. Copy hooks (v0.2): - Update notification: "Kinsley updated the dashboard concept after your last call. Take a look." - Inline caption: "Why this changed: [one line about the filter decision that drove it]."


Organize and filter

13. First themed feature grouping

Type: Peak (recognition moment). What happens: System proposes sitemap and themed groupings. User sees sprawl organized. Why it matters: The "oh, it's a product now" moment. Failure mode: Groupings that don't match user's mental model. Or abstractions that don't help. Ownership: Grouping labels = Quentin. Proposal UX = Kinsley. Logic = PM + agents. Maps to: FR19, FR20. Screens to capture: Raw feature list. Proposed grouping reveal. Theme-level detail view. Edit state (dragging a feature between themes). How to reach: after ideation + full feature list, trigger the organize step in the pipeline. Copy hooks (v0.2): - Grouping intro: "We organized your 47 features into 6 themes. Review, edit, or approve."

14. First aha from the three-pillar filter

Type: Peak (Maya's signature moment in J1). What happens: Filter runs across Desirability, Feasibility, Viability. Ranked results + release allocation surface. Why it matters: If Quorum doesn't produce at least one "I didn't see that" insight per session, it's a fancy spreadsheet. Failure mode: Boilerplate reasoning. Rankings that match user's gut. Ownership: Filter result copy and evidence display = Quentin. Ranked-list UX = Kinsley. Logic and evidence = John + agents. Maps to: FR21, FR22, FR25a. Screens to capture: Filter input panel. Filter running state (per-pillar progress). Combined ranking result. Per-feature evidence tooltip / expansion. Unexpected-insight callout (the aha). How to reach: complete ideation + organize; trigger three-pillar filter. Requires real features and agent analysis time (async job per NFR-P3). Copy hooks (v0.2): - Result headline: "Top ranked: [feature]. Reasoning below." - Evidence section: "Because: [specific citation], [specific data], [specific user quote]." - Unexpected-insight callout: "Unexpected: [the surprising result], [one-line why]."

15. First override of filter

Type: Peak (trust moment, user asserts judgment). What happens: User disagrees with filter recommendation and overrides. System records rationale. Why it matters: No override = dictatorial. Sulky override = petty. Calm and respectful is the line. Failure mode: "Are you sure?" repeated pestering. Silent override without audit record. Ownership: Override copy = Quentin. Override UX = Kinsley. Audit recording = Damien. Maps to: FR23, FR25, FR45. Screens to capture: Filter recommendation panel. Override button/CTA. Rationale input modal. Confirmation post-override. Audit log entry for the override. How to reach: in filter results view, click override on any recommendation. Fill the rationale field. Confirm. Copy hooks (v0.2): - Override prompt: "Overriding the filter's recommendation. What's your reasoning?" - Confirmation: "Recorded. You can revisit this decision in the audit log."

16. First release allocation

Type: Peak (scope-clarifying moment). What happens: System recommends MVP, V2, V3, deferred buckets with per-allocation reasoning. Why it matters: "What do I build first?" is the question every founder has. Clean answer matters more than any single artifact. Failure mode: Arbitrary bucketing. Or buckets user can't edit. Ownership: Allocation copy and rationale = Quentin + John. Bucket UX = Kinsley. Logic = filter. Maps to: FR25a. Screens to capture: Allocation overview (MVP / V2 / V3 / deferred, with counts). Per-bucket feature list. Individual feature rationale expansion. Edit affordance (move to V2). How to reach: after three-pillar filter completes. Allocation view appears automatically or via explicit CTA. Copy hooks (v0.2): - Allocation header: "MVP: 12 features. Here's why each is in or out." - Per-feature rationale: one sentence per feature.

55. First pillar gate verdict

Type: Peak (the gate renders a judgment, not just a score). What happens: A feature finishes evaluation on a single pillar and receives a terminal verdict — pass, fail, or needs revisit — paired with a confidence level and the evidence that supported it. The verdict badge appears on the pillar's card. Why it matters: The three pillars are checkpoint gates, not just analysis lenses. A ranked list says "this is best." A verdict says "this clears." Features have to earn their way out of the filter, one pillar at a time. This is the moment users see the methodology working — not just producing a score, but taking a position. Failure mode: Verdict that reads as a vague score ("76% desirable"). Badge copy that muddles pass vs needs-revisit. Evidence that doesn't tie back to the pass criteria the user was promised. Ownership: Verdict badge copy + color = Quentin. Verdict UX = Kinsley. Gate pass criteria + confidence rubric = PM + agents (Mary / Winston / John per pillar). Maps to: FR25b (terminal verdicts), Story 4.7 (pillar gate verdicts and exit criteria). Screens to capture: Pillar card with verdict badge rendered. Hover/focus state revealing pass criteria + this feature's score against them. Confidence indicator. Evidence expansion (ties to #14's evidence card). How to reach: run the three-pillar filter on a feature group; wait for a pillar evaluation to complete (Collaborate mode shows per-step progress; Let-AI mode completes the whole set). Copy hooks (v0.3): - Pass badge: "Clears Desirability" (not "passed" — avoid test-exam framing). - Fail badge: "Does not clear Feasibility" (direct, not harsh). - Needs-revisit badge: "Needs revisit — Viability". - Confidence line: "Confidence: moderate. Three of four pass criteria are met; the pricing signal is thin." (concrete, not generic) - Pass-criteria peek: "Tested against: user-need evidence, behavior-change signal, persona fit, willingness-to-pay signal."

56. "Needs revisit" blocks advancement

Type: Valley (a friction point — but a disciplined one). What happens: User attempts to finalize step 3 and move to release allocation, but at least one feature-gate pair is still in needs revisit. The system blocks advancement and lists the unresolved gates, offering three paths: run a dispute for deeper analysis (#17a / Story 4.3), accept as-is (forces pass with rationale), or override with audit (connects to #15). Why it matters: The single most important constraint in the checkpoint-gate framework. Without this block, "filter" collapses back to "ranking" — features can exit without actually clearing. This valley is where Quorum's discipline lives. If we soften it, the whole methodology bends. Failure mode: "You have 3 unresolved items" with no indication of which pillars. Pestering "Are you sure?" prompts. A "Skip for now" shortcut that skips the methodology (there is no such shortcut). Copy that scolds the user for not resolving. Ownership: Block copy = Quentin. Block UX (modal vs inline vs rail treatment) = Kinsley. Logic enforcement = backend (Damien). Maps to: FR25c (gate-cleared required for allocation), Story 4.6 "Given any feature still sits in needs revisit" AC, Story 4.7 "Given a feature in needs revisit" AC. Screens to capture: Finalize-step-3 action with needs-revisit features listed. Per-feature unresolved-gate summary. Three-path resolver (dispute / accept / override). Rail or banner callout of the block state. How to reach: run the filter with at least one feature left in needs-revisit on any pillar; click the primary "Finalize and see allocation" CTA; the block screen surfaces. Copy hooks (v0.3): - Block headline: "Four features haven't cleared every gate yet. Resolve them before we allocate." - Per-feature line: "Feature X — Feasibility needs revisit. Winston is still researching the S3-versioning question." - Three-path label: "Resolve by: running a dispute, accepting as-is, or overriding with reason." - No skip-shortcut. If the user insists on skipping, that's a literal override event (#15), logged and marked, not a hidden bypass.

57. "Why this verdict?" drill-down

Type: Transition (trust-building surface that pays back the transparency promise). What happens: From a pillar verdict badge, the user opens a "Why this verdict?" affordance. A panel reveals the pass criteria that pillar tests for, the evidence collected by the agents, and how this specific feature scored against each criterion. Not just "here's the score" — here's the rubric and the marks. Why it matters: The whole three-pillar framework is marketed as a transparent filter. If users can only see verdicts, they have to trust blindly. If they can see the rubric and the evidence, they can challenge with precision — which is what enables the productive dispute loop (FR23) rather than just rage-overrides. Failure mode: A drill-down that restates the verdict without showing the criteria. A "view more" that opens an unreadable JSON blob. Pass-criteria copy that's so abstract it doesn't help the user argue back. Ownership: Pass-criteria copy = Quentin + PM. Drill-down UX = Kinsley. Criteria definitions = per-pillar agent (Mary / Winston / John). Maps to: FR22 (evidence and rationale), FR25b (verdict with documented pass criteria), Story 4.7 "Why this verdict?" AC. Screens to capture: Pillar card in default state. "Why this verdict?" link / icon. Expanded panel with four sections: pass criteria, evidence snippets, this feature's mark against each criterion, confidence rationale. Dispute trigger inline. How to reach: from any pillar verdict on the three-column board, click "Why this verdict?" (or the ⓘ adjacent to the badge). Copy hooks (v0.3): - Panel header: "Why Desirability passed." - Criteria list format: "✓ User-need evidence — strong (3 citations). ✓ Behavior-change signal — clear (Maya switches tools). ⚠︎ Willingness-to-pay — moderate (one data point, not longitudinal)." - Dispute hint at bottom: "Disagree with the mark on any criterion? Dispute it."


Artifact production

17. First PRD complete

Type: Peak (first shippable artifact). What happens: PRD produced as HTML and DOCX. User can download. Why it matters: First time the user holds something product-document-shaped. Validates the pipeline. Failure mode: Template-shaped PRD. Or PRD that doesn't reflect filter decisions (silent drift). Ownership: PRD content voice = Quentin + Paige. PRD structure and design = Kinsley. Export pipeline = Damien. Maps to: FR26. Screens to capture: PRD preview in-app (table of contents + sections). Export dropdown. Download in progress. Generated HTML opened in browser. Generated DOCX opened in Word. Excerpt showing FR section with proper formatting. How to reach: after filter + allocation, trigger PRD generation (step 4 in pipeline). Copy hooks (v0.2): - Generation confirmation: "PRD ready. Download HTML or DOCX." - Download complete: "Saved to your downloads. Open it."

18. First journey map

Type: Transition (widening perspective). What happens: Journey maps reflecting agreed flows are produced. Why it matters: Makes abstract decisions concrete. Failure mode: Swim-lane diagrams that need a key. Journeys without clear personas. Ownership: Journey narrative copy = Quentin + Mary. Journey visualization = Kinsley. Maps to: FR27. Screens to capture: Journey map overview (all personas). Single-persona journey full view. Step-level detail. Annotations at friction points. Mobile view (if exists). How to reach: pipeline step 4b (journey mapping), after PRD. Copy hooks (v0.2): - Journey titles: character-led. "Maya: from spark to pitch." - Step labels: verbs from the user's perspective.

19. First design refinement (5.25)

Type: Peak (fidelity jump). What happens: Design tokens and high-fidelity comps arrive. Concept visuals mature. Why it matters: Product starts to feel like a product instead of a plan. Failure mode: Tokens invented without user's brand. Refined designs that drift from concept. Ownership: Refinement messaging = Quentin. Token generation and hi-fi = Kinsley. Brand alignment = Kinsley + Mary. Maps to: FR28. Screens to capture: Before / after for one hero screen (concept vs refined). Token sheet (colors, typography, spacing). Design system index page. Change log annotations on changed screens. How to reach: pipeline step 5.25. Copy hooks (v0.2): - Refinement intro: "Tokens locked. Screens refined. Here's what changed from concept."

20. First motion spec

Type: Transition (temporal layer added). What happens: Luca produces motion specs for refined designs. Why it matters: Motion is where the product feels alive. Specs make it buildable. Failure mode: Specs that devs can't read. Motion ignoring prefers-reduced-motion. Ownership: Motion copy and summary = Luca + Quentin. Spec format = Luca. Accessibility check = Quentin. Maps to: FR29, NFR-A2. Screens to capture: Motion spec overview. Per-animation detail (timing, easing, duration). Reduced-motion fallback spec. Annotated sequence diagram. How to reach: pipeline step 5.5, after design refinement. Copy hooks (v0.2): - Motion summary line: "Modal entry: 300ms spring. Reduced-motion: instant."

21. First roadmap and cost

Type: Transition (planning to budgeting). What happens: Roadmap and cost estimates produced. Why it matters: First numbers. Reality check. Failure mode: Cost ranges too wide to be useful. Or precision that implies false confidence. Ownership: Cost copy and confidence framing = Quentin + Winston. Cost data = Winston + Damien. Maps to: FR30. Screens to capture: Roadmap timeline view. Cost panel with range + confidence. Assumptions list expanded. Per-phase breakdown. How to reach: pipeline step 6. Copy hooks (v0.2): - Cost presentation: "$8K to $14K. Confidence: medium. Assumptions: [list]." - Roadmap: phases, not dates unless asked.

22. First pitch deck

Type: Peak (Maya's pitch-ready finale in J1). What happens: Audience-appropriate pitch produced as PDF, DOC, HTML. Why it matters: "Ready to pitch on Monday" moment. Output has to be pitch-ready, not deck-shaped. Failure mode: Generic templates. Pitches that don't reflect user's positioning. Ownership: Pitch copy and narrative = Sophia + Quentin. Pitch design = Kinsley + Caravaggio. Export = Damien. Maps to: FR31. Screens to capture: Pitch preview in-app. Slides 1, 5, final. Generated PDF opened. Generated DOCX opened. HTML deck in browser. How to reach: pipeline step 8 (pitch). Triggered after roadmap + cost. Copy hooks (v0.2): - Generation confirmation: "Pitch ready. Three formats exported." - Pitch voice: opinionated, specific, short sentences.


Team and enterprise

23. First invitation sent

Type: Transition (solo to team). What happens: Workspace owner invites a member. Plan may auto-promote per FR50. Why it matters: Growth moment. Copy should make the invitation feel like an offer, not a burden. Failure mode: Invitation emails that look like spam. Auto-promotion that surprises the owner with a bill. Ownership: Invite email + in-app copy = Quentin. Invite UX = Kinsley. Plan upgrade logic = Damien. Maps to: FR3, FR50. Screens to capture: Invite-form modal. Sent confirmation. Plan-upgrade warning (when Solo auto-promotes to Team). Invite email (recipient inbox view). Member list with pending status. How to reach: settings → members → invite. Use a secondary email to send to. Copy hooks (v0.2): - Invite CTA: "Send invitation." - Email subject: "[Owner name] invited you to [Workspace]." - Plan warning (before send): "Adding a member moves this workspace to Team ($X/mo). Confirm?"

24. First collaborator joins

Type: Peak (enterprise-trio J3 starts here). What happens: Invited teammate accepts and lands in the workspace. Why it matters: Second person's first impression. They missed prior context. Failure mode: Teammate lands in populated workspace with no orientation. Or gets a full tutorial they don't need. Ownership: Welcome-to-existing-workspace copy = Quentin. Catch-up UX = Kinsley. Maps to: FR3, FR9. Screens to capture: Invite-accept landing (before entering workspace). Welcome-to-existing-workspace first view. Where-they-left-off summary card. Catch-up offer. How to reach: from secondary email, click invite link. Accept. Land in workspace. Copy hooks (v0.2): - Welcome: "You're in. [Owner] started this workspace. Here's where they left off: [summary]."

25. First shared vision session

Type: Peak (J3 signature). What happens: Sam, Jordan, Chris run Kitchen Sink together. Real-time presence, turn-taking, conflicts. Why it matters: Enterprise defining moment. Clunky = enterprise adoption dies. Failure mode: Merge conflicts on ideation. One person dominating while others disengage. Ownership: Multi-user session copy = Quentin + Mary. Presence UX = Kinsley. Real-time sync = Damien + Jaymes. Maps to: FR14, NFR-R2. Screens to capture: Session room with 3 cursors visible. Turn indicator active. Real-time presence chips. Synced artifact updating. Conflict-surface state. How to reach: invite 2 members to a fresh workspace. Start Kitchen Sink session with all 3 logged in concurrently. Copy hooks (v0.2): - Session opener: "Three of you are here. Start?" - Turn-taking prompt: "Jordan, your turn. One minute or skip."

26. First cross-agent conflict surfaced

Type: Peak (structural-differentiation evidence). What happens: Two agents disagree; conflict shown to user for resolution. Why it matters: Core promise again. Never surfacing = agents pretending to differ. Too often = user overwhelmed. Failure mode: "Here are two perspectives..." (focus-group tone). Burying real disagreement in consensus-flavored copy. Ownership: Conflict-presentation copy = Quentin. Resolution UX = Kinsley. Conflict logic = John + PM. Maps to: FR10, FR11, FR12. Screens to capture: Conflict banner at top of affected artifact. Two positions side by side. Trade-off panel. Resolution CTAs (pick one, ask for more). Resolved state. How to reach: during filter or planning step where two agents evaluate differently (e.g., Kinsley favors feasibility of X, Damien flags risk). Trigger by picking a scope that creates honest tension. Copy hooks (v0.2): - Conflict header: "Kinsley and Damien disagree. Here's the trade-off." - Each position: one sentence. - CTA: "Pick one" or "Ask for more."

27. First decision recorded

Type: Transition (ephemeral to auditable). What happens: User's choice on a contested recommendation recorded with rationale. Why it matters: Audit trail. Six months later, "why did we decide X?" has an answer. Failure mode: Decisions without context. Rationale prompted every click. Ownership: Decision prompt copy = Quentin. Audit log UX = Kinsley. Recording = Damien. Maps to: FR12, FR45. Screens to capture: Decision prompt modal. Rationale input state. Recorded confirmation. Audit log entry view. Retroactive rationale lookup (months later). How to reach: override any agent recommendation. Fill rationale. Visit audit log. Copy hooks (v0.2): - Rationale prompt: "One line on why?" (optional). - Confirmation: "Recorded."

28. First admin action

Type: Valley (config work, low fun). What happens: Workspace admin configures tiers, seats, integrations (FR42-44). Why it matters: Rarely joyful, frequently needed. Good copy keeps admins from escalating to support. Failure mode: Settings pages with unexplained fields. Destructive actions without guardrails. Ownership: Settings labels and helper text = Quentin. Settings UX = Kinsley. Admin logic = Damien. Maps to: FR42, FR43, FR44. Screens to capture: Admin settings index. Tier configuration panel. Seat configuration. Integration connect flow (Jira/Notion). Destructive-action confirmation. How to reach: as workspace owner, settings → admin. Copy hooks (v0.2): - Field labels: plain English. "Seats" not "licenses." - Destructive guardrails: "Type DELETE to confirm."

54. Accessibility statement discovered

Type: Peak (small; trust signal, especially for enterprise buyers and users with disabilities). What happens: User or prospect visits quorum.app/accessibility. Often from an enterprise procurement process asking about VPAT, a user who hit a barrier and wants to report it, or a curious visitor checking whether we take a11y seriously. Why it matters: The accessibility statement is a credibility moment. Enterprise buyers read it before signing. Users with disabilities read it to know what to expect. Detailed, honest, with a feedback channel builds trust in seconds. Boilerplate or missing looks checkbox-compliant or worse. Failure mode: Copy-pasted boilerplate. Claims of "fully WCAG-compliant" with no specifics. No feedback mechanism. No acknowledgment of known limitations. No VPAT offer for enterprise buyers. Ownership: Statement content = Quentin. Page design = Kinsley. Feedback form + mailto wiring = Jaymes + Damien. VPAT document = Quentin + compliance advisor (TBD). Maps to: accessibility-statement.md (source content). NFR-A1 (WCAG 2.2 AA). NFR-A6 (VPAT readiness). Implicit: FR covering public a11y page routing. Screens to capture: Public quorum.app/accessibility page. Section-level anchors (commitment, what's built in, known limitations, third-party posture, feedback channel, VPAT). Feedback-form entry (when wired). VPAT request email draft. How to reach: visit quorum.app/accessibility directly. Or click "Accessibility" in the site footer (when wired). Or click "Report an accessibility issue" in the in-product help menu. Copy hooks (v0.3): - Page intro: "We build Quorum Plus so every teammate, founder, and contributor can use it." - Full copy: accessibility-statement.md.


Build and implementation

29. First story exported

Type: Transition (planning to build). What happens: User exports the epic/story pack to Cursor, Codex, Claude Code (FR35). Why it matters: Quorum hands off the baton. Clean export = dev loop works. Garbled = pipeline output wasted. Failure mode: Stories missing context. Formats external tools can't parse. Ownership: Export format and in-doc voice = Quentin + Bob. Export pipeline = Damien. Format spec = Winston. Maps to: FR33, FR34, FR35. Screens to capture: Export modal with format picker. In-progress export. Downloaded artifact (JSON + MD previewed). Confirmation state. How to reach: after PRD → stories break-down, trigger sprint-pack export. Copy hooks (v0.2): - Export confirmation: "Sprint pack exported. Drop it into your coding tool." - Per-format caption: "JSON for Cursor and Claude Code. Markdown for humans."

30. First build progress back to board

Type: Peak (loop-closure moment). What happens: External dev tool signals progress; Quorum updates its view. Why it matters: Round-trip is what makes Quorum a conductor. Without signals, it's a one-way planner. Failure mode: Silent builds. Status lag. Ownership: Status copy = Quentin + Bob. Status UX = Kinsley. Webhook handling = Damien. Maps to: FR36. Screens to capture: Board view pre-update. Status-change animation mid-update. Board view post-update. Per-story detail with activity log. Webhook-received notification (if surfaced). How to reach: configure webhook from Cursor / Claude Code integration; trigger an external commit or task-completion event. Copy hooks (v0.2): - Status badges: "In progress," "Blocked," "In review," "Done." - Status notification: "Story 2.3 moved to In review. Two hours of work logged."

31. First QA run

Type: Transition (trust check). What happens: Quinn runs tests or Murat designs the pack. Results surface. Why it matters: First evidence the build is real. Failure mode: Jargon-heavy reports. Reports that don't tell users what to do. Ownership: QA report copy = Quentin + Quinn. Report UX = Kinsley. Test logic = Quinn + Murat. Maps to: FR38. Screens to capture: QA summary view. Per-test result (pass and fail). Failure detail with suggested fix. Coverage visualization. How to reach: after implementation phase, trigger QA step. Quinn for fast coverage; Murat for architecture. Copy hooks (v0.2): - QA summary: "18 of 20 tests passed. Two failures below with suggested fixes." - Failure format: test name, what failed, suggested next step.

32. First security review

Type: Peak (Cipher's entry). What happens: Cipher runs audit. Findings surface with severity. Why it matters: Security is a gate. Findings have to be actionable. Failure mode: Vague criticals without specifics or remediation. Ownership: Security report copy = Cipher + Quentin. Report UX = Kinsley. Audit logic = Cipher. Maps to: FR39, NFR-S1 through S6. Screens to capture: Cipher audit run progress. Findings summary (severity counts). Per-finding detail. Remediation steps. Re-run after fix verification. How to reach: after implementation, trigger security audit. Findings seed from Cipher's scan tooling. Copy hooks (v0.2): - Findings header: "[N] critical, [N] high, [N] medium, [N] low." - Per-finding: one-line title, one-line evidence, one-line remediation.

33. First release declared blocked

Type: Valley (good valley; safety gate holding). What happens: User or agent marks release blocked. Why it matters: Blocking is a feature. Copy should make the block feel safe, not punitive. Failure mode: Blocks without reasons. Blocks user can't override via waiver. Ownership: Block reason copy + waiver flow = Quentin + Cipher + Quinn. Block UX = Kinsley. Block logic = PM. Maps to: FR41, NFR-S4. Screens to capture: Block banner on release view. Block-reason detail panel. Waiver-request form. Waiver-approved state. How to reach: on a release candidate that has active QA or security findings at high severity, mark release blocked. Copy hooks (v0.2): - Block banner: "Release blocked. Reason: [specific]. Required: [specific]." - Waiver: "Request waiver" button with rationale field.

34. First release shipped

Type: Peak (the big one; J1 and J3 end here for v1). What happens: Gates clear. User declares release shipped. Why it matters: Full-loop close. Earned understatement beats manufactured celebration. Failure mode: "WOOHOO YOU SHIPPED!" (oversold). Silent status change (undersold). Ownership: Ship-confirmation copy and motion = Quentin + Luca. Ship UX = Kinsley. Release mechanism = Damien. Maps to: FR40, FR41. Screens to capture: Pre-ship state (all gates green). Ship confirmation modal. Post-ship summary (stats). Optional subtle celebration animation (first frame + last frame). How to reach: clear QA, security, UAT gates. Hit "declare shipped." Copy hooks (v0.2): - Ship confirmation: "Shipped. Your users have it." - Optional stat: "42 stories, 8 weeks, 3 team members."

58. First automated WCAG AA gate goes green

Type: Peak (builder / team moment, not user-facing). What happens: Every covered page-state — design system at rest and with a modal open, both auth surfaces, the post-auth core (picker, room, members in team and solo_free variants, new-workspace landing + plan-change), one modal-open interactive state, and the public payment step — clears axe-core's critical+serious filter at WCAG 2.1 AA. The check runs in CI on every push. The team can no longer ship a regression on label association, focus management, color contrast, or ARIA semantics on these surfaces without the build going red. Why it matters: A11y stops being aspirational and becomes infrastructure. The promise in the public accessibility statement (NFR-A1, WCAG 2.2 AA) earns a teeth-bearing partner: an automated gate that says no on behalf of every user with a disability before any of them have to. It also closes the loop on the live design-system page's reason for existing — its first axe pass caught two real production contrast bugs (.app-modal__btn-danger 4.05:1, .app-ws-card__updated-abs 3.19:1) on shared chrome that would have propagated to every route that used them. The doc the developer reads turns out to be the doc that protects the user. Failure mode: WCAG cited as a one-time audit checklist instead of a continuous gate. Coverage limited to the marketing surfaces while the post-auth product (where users live) drifts. Critical-only filter that lets serious violations through. The "axe is too strict, let's exclude rule X" reflex when a real bug fires. Ownership: Test architecture and helper (expectNoA11yViolations) = Damien. Coverage scope (which routes, which states, which interactive moments) = Kinsley + Cipher (a11y-as-pen-test posture). Voice on a11y commitments and any user-facing copy = Quentin. Visual fixes when violations fire = Kinsley + Jaymes. Maps to: NFR-A1 (WCAG 2.2 AA), NFR-A6 (VPAT readiness). accessibility-statement.md (the public commitment this gate enforces). FR47 (portfolio document — automated gates are part of the case study). quorum-app/tests/e2e/design-system.spec.mts and quorum-app/tests/e2e/a11y-coverage.spec.mts (the gate itself). Screens to capture: CI output showing the green a11y test count (12 page-states / N tests passing). The first-pass diff that fixed the two contrast bugs (commit 9d34857). The design-system reference page next to the workspace card it surfaced the bug on, side-by-side. The expectNoA11yViolations helper. The a11y-coverage spec listing. How to reach: in quorum-app, run npx playwright test tests/e2e/design-system.spec.mts tests/e2e/a11y-coverage.spec.mts. Or wait for CI on a push to main. Or extend coverage by adding a test to a11y-coverage.spec.mts for a route or interactive state not yet listed. Copy hooks (v0.2): - For the portfolio doc (FR47): "WCAG 2.1 AA isn't a launch checklist here — it's a CI gate. Twelve page-states, including modal-open and post-auth surfaces, fail the build if a contrast or ARIA regression lands." - For the public accessibility statement: "We don't claim full WCAG 2.2 AA. We do automate WCAG 2.1 AA against twelve page-states on every push, and we widen the net as we ship new surfaces." (Honest. No "fully compliant" claim.) - For internal hand-off: "If a11y-coverage.spec.mts is red, fix the violation, don't exclude the rule. If you genuinely think axe is wrong, write the case in the PR — false-positive whitelisting only with a note."

59. The team becomes visible

Type: Peak (builder / portfolio moment, not user-facing). What happens: The agent roster crosses from a list buried in the PRD to a designed, navigable surface. The team page at exports/team/index.html ships with three pillar cards (Desirability, Feasibility, Viability), 22 agents organized by their primary lens, each with their methods, artifacts, and trigger phrase laid out in a card. Cross-pillar contributions surface as colored chips on the agents who span lenses (Mary, Sophia, Saga, Dr. Quinn, Kinsley, Atticus, Paige). The framework stops being abstract and becomes characters with named ownership. Why it matters: Quorum's thesis — "agents are the team, not a chat sidebar" — needs a surface where that's literally true. Until today, the team was implied (in the PRD, in vision notes, in the workflow). Now it's a page. A portfolio visitor can read who Mary is, what she runs, what she produces, and the trigger phrase to bring her into a session, in under a minute. A current user can browse the roster and learn which agent owns the question they're stuck on. The team is no longer a claim. It's a visible architecture. Failure mode: Agent cards that read like LinkedIn profiles ("specialist in X, passionate about Y"). Methods sections that paraphrase the agent's skill description instead of naming concrete workflows. Artifact lists that promise files no project ever produces. Color systems that decorate but don't encode meaning. Stagger animations that feel performative across 11 cards. Ownership: Information architecture and pillar mapping = Mary + John (analysts of analysts). Visual design and liquid-glass system = Kinsley. Color system mapping pillar to identity = Kinsley. Motion specification = Luca. Voice and copy across 22 cards = Quentin. Maps to: PRD § The Three-Pillar Framework (the cards literalize the framework's agent-ownership claims). FR47 (portfolio document — the team page is portfolio infrastructure). The implicit promise in "Agents are the team" — this page is where that promise gets receipts. Screens to capture: Hero + three collapsed pillar cards (the at-rest state). One pillar card expanded showing the agent grid. One agent card expanded showing both What they run and What they produce. The cross-pillar chips on Atticus's card (V solid + D and F outlined). The chevron mid-rotation on a pillar card. How to reach: Open quorum.jayfrank.info/team/ (after deploy) or localhost:8000/exports/team/index.html (local). Click any pillar to expand. Click any agent's collapsible sections to see methods and artifacts. Copy hooks (v0.6): - For the team page hero: "Eighteen agents, three lenses, one product. Quorum operationalizes the Desirability / Feasibility / Viability framework by distributing the argument across named agents, each with their own methods and artifacts. The framework is the spine; the agents are the practice." - For the philosophy callout: "Most AI tools collapse a product team into one assistant with five voices. Quorum keeps the roles structurally separate: Mary argues for the user; Winston argues for the build path; John argues for the business; Cipher argues for the attacker. Their disagreements are the product." - For an agent's invitation hover: "Bring Mary into the session. She owns desirability, runs the user research, frames the personas, signs off on the gate."

60. The design system stops being a screenshot

Type: Peak (builder / portfolio moment, not user-facing). What happens: The design-system page in the planning exports stops being a static reference and becomes a live React app inside Quorum's chrome. Visitors land on exports/design-system/index.html (with Quorum's nav, hero, and footer wrapping), and inside the iframe, the actual /design-system route from quorum-app renders fully. Click "Open medium" — a real Modal portals to body and slides in. Click the Select trigger — the listbox opens with keyboard navigation. Click "Fire success" — a real Toast slides down from the top with the green tone. Click "Open slide-swap demo" — the modal's two-pane slide animation runs. Click the Pill — the counter increments from "Click me" to "Click me (1)". The design system is no longer a doc that describes the components; it's the component runtime, embedded. Why it matters: Portfolio sites that show design systems usually fall into two camps: docs that talk about components in prose, or screenshots that show the components frozen. Quorum's surface ships the third option — the actual app, sandboxed in an iframe, hydrated and interactive. A visitor doesn't read about how the modal animates; they trigger it. They feel the timing, the curve, the toast tone. The portfolio shows what it claims to make. The act of demonstrating is the demonstration. Failure mode: Iframes that show a 404 because asset paths weren't rewritten for the deploy URL. Components that visually render but have dead onClick handlers because the build snapshot stripped the React runtime. Production bugs that dev mode tolerated (like our useSearchParams() Suspense issue) breaking the build silently. Bundle paths baked with absolute URL prefixes that work in one hosting environment but not another. Framework version drift between the iframe and the parent that surfaces as console warnings. Ownership: Snapshot pipeline + path-rewrite logic = Damien (build orchestration) + Jaymes (frontend correctness). Iframe sizing and viewport semantics so position-fixed modals position correctly = Jaymes + Luca (motion timing within the iframe). Visual framing — the wrapper page, hero, and Source-of-truth callout — = Kinsley. Voice on the framing = Quentin. Maps to: PRD § Design system (live reference, not just docs). FR47 (portfolio document — the design system surface is the most direct evidence of "what we built"). The implicit promise in "the doc the developer reads is the doc that protects the user" (from #58) — this version doubles down: the doc the visitor explores is the doc the user lives in. Screens to capture: The wrapper page with iframe collapsed in resting state. The same page with the Modal mid-animation. The Select listbox open inside the iframe. The Toast firing. A side-by-side of the iframe view and the live app.quorum.jayfrank.info/design-system page (after deploy) showing they match. How to reach: Open quorum.jayfrank.info/design-system/ (after deploy) or localhost:8000/exports/design-system/index.html (local). Click any interactive component inside the iframe. Copy hooks (v0.6): - For the page hero: "Live, interactive showcase of the /design-system route in quorum-app. Click any trigger below — modals open, the Select listbox reveals, Toasts fire, the slide-swap animates. Real React inside, Quorum chrome around." - For the Source-of-truth callout: "Edit any of those files and the next python3 _gen_all_exports.py rebuilds the static bundle. The four interactive-state screenshots live alongside this page at screenshots/." - For internal hand-off when the design-system breaks: "The bundle is path-rewritten to work under any URL prefix. If something 404s, check the rewrite step in quorum-app/scripts/snapshot-design-system.mjs first."


Post-ship

35. First post-ship metric

Type: Transition (planning to reality). What happens: Real user data arrives. Agents surface insights. Why it matters: Closes planning-to-reality loop. Validates or invalidates filter decisions. Failure mode: Dashboard of raw numbers without interpretation. Ownership: Metric interpretation copy = Quentin + John. Dashboard UX = Kinsley. Metric pipeline = Damien. Maps to: Pipeline step 12 (feedback). Screens to capture: Metrics dashboard first-view. Per-metric interpretation panel. Signal-vs-noise callouts. Agent-highlighted unexpected pattern. How to reach: 30+ days post-ship with connected metric source. Copy hooks (v0.2): - Metric header: "First 30 days: [specific]." - Interpretation: "Signal: [X]. Noise: [Y]. What to do: [Z]."

36. First Portfolio Document generated

Type: Peak (the full-journey artifact; FR47). What happens: Portfolio Document produced in HTML, PDF, Doc. Why it matters: Quorum becomes a portfolio tool, not just a planning tool. Failure mode: Generic case-study template. Document missing the interesting decisions. Ownership: Portfolio copy and narrative = Quentin + Sophia. Portfolio design = Kinsley + Caravaggio. Generation = Damien. Maps to: FR47, Epic 9. Screens to capture: Portfolio preview in-app. Section list with coverage indicators. Export dropdown. Generated HTML page. Generated PDF. Generated DOCX. How to reach: after ship + any post-ship feedback, trigger Portfolio Document from pipeline step 13. Copy hooks (v0.2): - Generation confirmation: "Portfolio ready. Share it." - Document voice: first-person user perspective, third-person where facts require.

37. First portfolio share

Type: Transition (internal to external). What happens: User sends Portfolio Document outside the workspace. Why it matters: Product goes public. User stakes reputation on Quorum's output. Failure mode: Broken shared document (missing images, wrong links). Confusing share flow. Ownership: Share UX and copy = Quentin + Kinsley. Export integrity = Damien. Maps to: FR47. Screens to capture: Share sheet. Link-copied state. Shared-document recipient view. Download-PDF state. Download-DOCX state. How to reach: portfolio page → share button. Copy hooks (v0.2): - Share sheet title: "Share portfolio." - Options: "Copy link," "Download PDF," "Download DOCX." - Post-share: "Shared."

51. First release notes read

Type: Peak (small; trust signal). What happens: User opens the release notes page after seeing "New update available" in-product, or visits quorum.app/releases directly. Why it matters: Release notes signal that the product is alive, maintained, and honest about what ships. A good read builds confidence. A bad read (vague "various improvements," hype-heavy, dismissive) erodes it quietly. Failure mode: Release note says "We've improved performance" with no specifics. Marketing-toned ("thrilled to announce") instead of release-toned. Wall of text with no structure. Missing "Known issues" section when there are known issues, making us look like we don't know our own product. Ownership: Release-notes drafting = Paige. Voice pass = Quentin. Release-notes UX = Kinsley. Publish pipeline = Damien. (Model B ownership, decided 2026-04-23.) Maps to: release-notes-format.md (template + voice + workflow). Implicit FR covering release visibility once wired. Screens to capture: Public quorum.app/releases index. A specific release note at quorum.app/releases/v1.2.0. In-product release notes panel (when that ships). The "New update available" banner state. How to reach: visit quorum.app/releases after v1 ships. Or open the release-notes panel from the product's help menu once wired. Copy hooks (v0.3): - Page title: "What's new in Quorum Plus." - Per-release structure: see release-notes-format.md template. - Empty state when no releases yet: "Release notes land here when v1 ships."


Recovery and continuity

38. First return after absence

Type: Transition (re-engagement). What happens: User comes back days or weeks later. Must orient without redoing onboarding. Why it matters: Lapsed users are the plurality of SaaS. Smooth re-engagement = retention. Failure mode: Unfamiliar dashboard. "Welcome back!" without context. Ownership: Welcome-back copy = Quentin. Resume UX = Kinsley. State restoration = Damien + Jaymes. Maps to: FR13, Journey 6. Screens to capture: Welcome-back banner on first login after absence. Where-you-left-off card. Resume-or-start-fresh options. Loaded state after resume. How to reach: sign out, wait (or simulate in staging by advancing timestamps). Sign back in after threshold period. Copy hooks (v0.2): - Welcome-back header: "Back. You left off at step 5 (three-pillar filter). Resume or start fresh?"

39. First stall detected

Type: Valley (the friction point). What happens: User inactive in mid-pipeline or repeatedly backed out. System detects; offers help. Why it matters: Lapsed becomes churned here. Warm nudge saves them; tone-deaf nudge loses them. Failure mode: "Looks like you're stuck!" (condescending). No nudge (silent churn). Ownership: Nudge copy = Quentin + John. Trigger logic = Damien. Offer UX = Kinsley. Maps to: FR13, Journey 6. Screens to capture: Stall-nudge toast or modal. Offer options panel (walk-through / on my own / pause). Dismissed state. How to reach: sit inactive on a pipeline step past the detection threshold. Or back out of the same step multiple times in succession. Copy hooks (v0.2): - Nudge: "You've been on the filter step for an hour. Want a quick walk-through of what it's doing?" - Options: "Yes, walk me through," "No, I've got it," "Pause and come back."

40. First session resume from checkpoint

Type: Peak (small peak; quiet competence). What happens: User accepts resume offer. Lands exactly where they left off. Context loaded. Why it matters: "This product respects my time" moment. Rare and valuable. Failure mode: Resume drops user two steps back. Stale checkpoint loaded. Ownership: Resume confirmation copy = Quentin. Resume flow = Kinsley. Checkpoint system = Damien. Maps to: FR13. Screens to capture: Resume confirmation dialog. Loaded state with prior context restored. Optional recap toggle expanded. How to reach: accept resume offer after a return-after-absence. Verify state matches where user actually left off. Copy hooks (v0.2): - Resume header: "Picked up where you left off. Step 5, three-pillar filter, halfway through." - Recap toggle: "Want a quick recap?"

41. First support ticket referencing session ID

Type: Valley (external support touches the user's journey). What happens: User contacts support. Ticket includes session ID and artifact versions. Why it matters: Support can help without 20 discovery questions. Failure mode: Support blind to session state. Hard-to-find ticket IDs. Ownership: Ticket form copy = Quentin. Ticket UX = Kinsley. Session-ID exposure = Damien. Maps to: Journey 6. Screens to capture: Support-entry link in help menu. Ticket form with session-context auto-attached. Privacy-note visible. Submitted-confirmation state. How to reach: settings → help → contact support. Copy hooks (v0.2): - Ticket intro: "We'll include your workspace state automatically. You just describe what happened." - Privacy: "We never share workspace content. Only session metadata and what you write in this message."


Valleys and endings

42. Payment declined (post-signup)

Type: Valley (billing interruption mid-use). What happens: User's recurring payment fails. Access might degrade or pause. Why it matters: Users panic on decline. Tone decides update-the-card vs rage-cancel. Failure mode: "Your payment failed." Threatening countdown. Both lose customers. Ownership: Decline copy = Quentin + Damien. Access-degradation logic = Kinsley + Damien. Maps to: FR42, FR44. Screens to capture: In-app decline banner. Decline email (inbox view). Card-update flow. Payment-retry success. Degraded-access state (if applicable during grace period). How to reach: use Stripe test card 4000 0000 0000 0341 (attach succeeds, charge fails on renewal). In test env, fast-forward the billing cycle to trigger renewal. Copy hooks (v0.2): - Banner: "Quorum payment didn't go through." - Specific reason: "Your card was declined by the issuer. Try another, or update details." - Access note: "Full access continues through [date]. Update anytime."

43. Workspace deleted

Type: Valley (destructive; potentially irreversible). What happens: Owner deletes a workspace. Polls, votes, members, artifacts removed. Why it matters: Most dangerous action. Guardrails firm without paternalistic. Failure mode: Confirmation too easy. Counts wrong. No recovery path. Ownership: Deletion copy = Quentin. Deletion UX = Kinsley. Soft-delete + retention = Damien. Maps to: FR6, NFR-S5. Screens to capture: Danger-zone settings entry. Delete-confirmation modal (shows counts). Typed-DELETE state. Post-delete redirect. Recovery banner (if soft-delete enabled). Recovery-option view in settings. How to reach: settings → danger zone → delete workspace. Use a test workspace. Type DELETE to confirm. Copy hooks (v0.2): - Confirmation: "Deleting this workspace erases [N] polls, [N] members, [N] votes, and [N] artifacts. Type DELETE to confirm." - Post-delete: "Workspace deleted. You have 30 days to restore from Settings → Recovery."

44. Member removed

Type: Valley (relationship ending). What happens: Admin removes a member or member leaves. Why it matters: Departures awkward. Clean copy without making anyone feel worse than needed. Failure mode: "You have been removed from the workspace." (chilly). Or flowery apology that prolongs awkwardness. Ownership: Removal copy (both sides) = Quentin. Removal UX = Kinsley. Mechanics = Damien. Maps to: FR6. Screens to capture: Admin remove-member flow. Confirmation modal. Success state. Recipient (removed member) email notification. Removed-member next sign-in state (shown out of workspace). How to reach: admin → members → remove (use a test account). Copy hooks (v0.2): - To removed: "You were removed from [Workspace]. You keep any artifacts you created personally." - To admin: "Done. [Member] no longer has access."

45. Subscription canceled

Type: Valley ending (product churn). What happens: User cancels. Access ends at period's close. Why it matters: How we say goodbye shapes whether they come back. Failure mode: Five retention screens. Or cancel so easy the product feels replaceable. Ownership: Cancel-flow copy = Quentin. Cancel UX = Kinsley. Mechanics + retention offers = Damien + John. Maps to: FR42. Screens to capture: Cancel-flow entry in billing. Reason-for-cancel form. Confirmation screen. Access-continues-through banner. Goodbye email (inbox). How to reach: settings → billing → cancel subscription. Copy hooks (v0.2): - Confirmation: "Subscription canceled. Access continues through [date]." - Goodbye: "Thanks for building with Quorum." - Return offer: "Come back anytime. Your data stays for 90 days."

46. Rate limit hit or quota exceeded

Type: Valley (ceiling encounter). What happens: User hits a usage cap. Why it matters: How we handle limits decides fair vs predatory perception. Failure mode: Hard cutoff with no warning. Vague limit messaging. Ownership: Limit-reached copy = Quentin. Warning UX = Kinsley. Metering = Damien. Maps to: FR44, NFR-R3. Screens to capture: Approaching-limit banner (at 80%). At-limit banner (blocked). Upgrade-offer modal. Reset-date countdown. How to reach: test environment with low monthly caps; exercise feature that meters usage until banner appears. Copy hooks (v0.2): - Approaching: "You're at 80% of this month's sessions (16 of 20). Upgrade or wait until [date]." - At-limit: "Monthly session limit reached. Upgrade to continue, or resume on [date]."

47. Agent hallucination caught by user

Type: Valley (trust failure). What happens: Agent produces factually wrong output. User catches it. Why it matters: Critical trust moment. How we handle being caught wrong decides retention. Failure mode: Agent doubles down. Or generic apology with no specificity. Ownership: Recovery copy = Quentin + the relevant agent. Acknowledgment UX = Kinsley. Correction logic = PM + agents. Maps to: FR11, FR23. Screens to capture: Incorrect agent output with user's correction pointed out. Agent acknowledgment bubble. Corrected state with visible edit. Audit-log entry for the correction. How to reach: give an agent a question where hallucination is likely (e.g., "what did [specific person] say in [specific interview in 2021]" — agents often invent). Catch and correct. Copy hooks (v0.2): - Acknowledgment: "You're right. I had [specific thing] wrong. Thanks for catching it." - Correction: correct the record visibly. Do not silently rewrite history.

52. Page not found (404)

Type: Valley (lost-user moment). What happens: User follows a link to a page that doesn't exist. Could be a deleted workspace, a moved resource, a mistyped URL, or a stale link from email or Slack. Why it matters: The 404 is often the first page a lost user sees. Done well, it orients them back to useful ground in a sentence. Done poorly, it feels like hitting a wall and they bounce. Failure mode: Generic "404" with no context, no action, no voice. Worse: "Oops! Something went wrong!" which is vague and cheerful in the wrong direction. Worst: the 404 URL path hides the problem by silently redirecting to home without telling the user why. Ownership: 404 copy = Quentin. 404 UX and illustration = Kinsley. Routing = Damien + Jaymes. Maps to: error-pages.md (copy source). Implicit FR covering graceful error handling. Screens to capture: Signed-out 404 at a public URL. Signed-in in-app 404. Workspace-scoped 404 (e.g., /w/<id>/polls/<deleted-poll>). Mobile versions of each. How to reach: navigate to quorum.app/any-missing-url signed-out. Navigate to /w/<id>/polls/<deleted-poll-id> signed-in to trigger the workspace-scoped variant. Copy hooks (v0.3): - Signed-out headline: "Page not found." - Workspace-scoped headline names the resource: "That poll isn't here." - Full copy catalog: error-pages.md.

53. Server error mid-work

Type: Valley (trust-at-risk moment). What happens: User is mid-task. Request hits a 500-class server error. Work state may or may not be preserved. Why it matters: Mid-work errors are where users forgive or abandon. A calm, specific, action-oriented error keeps them. A panicked "Something went wrong, please try again later" loses them. Failure mode: Red flashing modal. Apologies without action. No incident ID to reference if they need support. Vague "try again" with no indication that their unsaved work is safe. Ownership: Error copy = Quentin. Error UX = Kinsley. Error envelopes and incident IDs = Damien. Observability = Damien + Cipher. Maps to: error-pages.md (500-series copy). Implicit FR covering graceful error handling. NFR-R (reliability). Screens to capture: Full-page 500 error. Inline action-level error banner (when only one action failed, not the whole page). 503 (service unavailable) variant. Error with incident ID shown. State of user's draft after error (ideally: preserved, with "Your draft is saved" callout). How to reach: in staging, kill the API process and attempt a save. Verify the 500 page renders, the user's draft is preserved, and the incident ID is visible. Copy hooks (v0.3): - Default headline: "Something broke on our end." - Subhead: "We're looking at it. Try again in a minute." - With incident ID: "Incident ID: . Reference this if you email support." - Full copy catalog: error-pages.md.


Cross-cutting (repeated moments across the lifecycle)

48. Every save point

Type: Transition (tiny, constant). What happens: System saves state in the background. User knows it's safe to close. Why it matters: High-frequency reassurance. Good save UX prevents anxiety. Failure mode: Lying "unsaved changes" warnings. Silent saves with no signal. Ownership: Save indicator copy = Quentin. Indicator motion = Luca. Save system = Damien. Maps to: FR13, NFR-P1. Screens to capture: Saving indicator (mid-save). Saved state (ambient). Save-error state. Unsaved-changes warning on navigation. How to reach: make any change that triggers autosave. Disconnect network briefly to force save failure. Copy hooks (v0.2): - Saving: "Saving..." (visible only during save). - Saved: "All saved." (subtle). - Failure: "Couldn't save. Retrying."

49. Every agent turn

Type: Transition (repeated; NFR-P2 territory). What happens: Agent working. Multi-step or streaming feedback surfaces. Why it matters: Long silences = anxiety. 10 seconds without feedback = users assume broken. Failure mode: "Please wait while the agent processes your request..." (generic). Ownership: Streaming indicator copy = Quentin. Indicator UX = Kinsley. Agent infra = Damien. Maps to: NFR-P2. Screens to capture: "Agent is thinking" initial state. Streaming partial output mid-turn. Complete output. Long-running turn with partial-summary callout. How to reach: any agent query. For long-running, trigger a filter or analysis job that takes tens of seconds. Copy hooks (v0.2): - Streaming: "John is thinking." - Partial summary: "Scanning 12 sources... 3 findings so far."

50. Every notification

Type: Transition (attention interruption). What happens: User gets a notification. Why it matters: Notifications that earn attention compound trust. Wasted attention trains users to ignore the product. Failure mode: Notification spam. Vague content that forces opening the app to investigate. Ownership: Notification copy = Quentin. Notification UX = Kinsley. Notification channel abstraction (web + Tauri, Epic 10 Story 1.P4) = Jaymes + Damien. Maps to: Epic 10 Story 1.P4. Screens to capture: In-app notification toast. System notification (macOS desktop banner). Permission-prompt first-ask. Notification-settings panel. Muted-per-session state. How to reach: trigger a notification-worthy event (member joined, release status changed, comment posted). For macOS system notifications, install the Tauri desktop app once Epic 10 ships; until then, capture browser Notification API behavior only. Copy hooks (v0.2): - System-notification title: "[Member name] joined [Workspace name]." - System-notification body: the single most useful next piece of info.


Cross-cutting commitments (apply to every moment above)

Ownership matrix

Area Primary owner
All user-facing copy Quentin
Flow, layout, visual hierarchy Kinsley
Motion specs Luca
Frontend implementation Jaymes
Backend implementation, APIs, auth Damien
Security review Cipher
Test coverage Quinn (generation), Murat (architecture)
Narrative + launch arc Sophia
Agent personas + PM framing John
Screenshot capture (primary) Jaymes during in-context passes; Kinsley during design review

How to use this doc

What this doc does not cover (yet)