Change Log

living document
Last updated: 2026-06-03 1:34 PM (3m ago)

A daily log of what's changed across the Quorum project. Entries are reverse-chronological (newest first). Each day's entry covers: planning artifacts updated, structural / system changes, sessions completed, decisions made.

This is distinct from version-control.md, which is the strategy doc for how Quorum (the product) versions user artifacts at runtime. This file is the audit trail of how the project itself evolves.


June 20263 entries
2026-06-03Inline waitlist CTA, overnight-PR verification sweep, planning-page refresh (app + planning)

Inline waitlist CTA, overnight-PR verification sweep, planning-page refresh (app + planning)

  • Waitlist CTA rebuilt (PR #57). The "Join the waitlist" button no longer opens a modal. It collapses in place and the design-system TextField slides in (ease-in-out, 300ms); on submit a success toast slides down from the top of the screen and the CTA slot becomes a small green check reading "You've been added." The toast is portaled to <body> with styles in globals.css, so it works on the public landing (which has no ToastProvider) as well as the app top nav and demo modal. Verified end-to-end with Playwright; typecheck, lint, and 169 unit tests pass.
  • Overnight-PR verification sweep. Gate-tested the full backlog of auto/*, story/*, and chore/* draft PRs (typecheck + lint + unit tests per branch) to sort them into ready / needs-fix / hold ahead of a merge pass.
  • Planning page refreshed (this). Change log brought current across the 2026-05-20 → 06-03 gap, time-log updated, stories/epic-status regenerated from sprint-status.yaml, and the case study rewritten around the autonomous build story.
2026-06-02Sixteen-PR overnight batch merged + second 24-routine batch opened (app)

Sixteen-PR overnight batch merged + second 24-routine batch opened (app)

The first overnight pipeline landed: sixteen remote routines each opened a draft PR, all verified locally and merged to main (each merge auto-deploys to production).

  • Surfaces built out: per-workspace demo project content (#17), navigable Home stat tiles (#18), shipped product analytics page (#20), deeper Customize "How your team talks" with presets + live preview + persistence (#28), Account surface (profile / plan / connected accounts / sessions) (#27), Settings split into five clear sections (#26), Community showcase with a typed mock dataset (#25), and a curated, filterable Templates catalog with preview + new-workspace hand-off (#24).
  • Quality + infra: SEO + social metadata for public pages (#22), branded error / 404 / loading states (#23), internal admin waitlist view + CSV export (#14), DB-free unit tests for auth/demo, home mocks, waitlist + contact (#21), a clutter-vs-value surface audit (#19), and a per-workspace personal-info feature spec (#15).
  • New app capability: global Cmd/Ctrl-K command palette (#29).
  • Onboarding: first-run flow polished into a warm 3-step welcome (#30).
  • Second batch armed: 24 collaborative-team routines (each a lead spawning specialist sub-agents) fired in the evening, opening a fresh wave of auto/* draft PRs (#31–#55) for polish, a11y, motion, toasts, error boundaries, CI, security headers, SEO, favicons/PWA, and more.
2026-06-01Ship-spree: waitlist capture, public pricing, launchpad tour, demo hardening + Epic 1 retrospective (app + planning)

Ship-spree: waitlist capture, public pricing, launchpad tour, demo hardening + Epic 1 retrospective (app + planning)

  • Waitlist (new): DB table + API + a reusable capture CTA wired into the hero, the demo work-in-progress modal, and the in-app nav.
  • Launchpad: rocket-ship launchpad icon top-right of the app nav; stat tiles drop their icons for a blue → amber gradient and order by most-left-to-do; a guided tour ("Try our demo" spotlights each section); the demo opens with a choice (walkthrough vs explore) rather than forcing a path.
  • Demo hardening: locked to read-only (visitors can't create workspaces), shows a persona name (Keith Haring) instead of the real account holder, and a work-in-progress modal on the project space.
  • Pricing: restored the public /pricing page (full plan grid + monthly/annual toggle) and footer.
  • Planning: Epic 1 retrospective run and marked done (#9); Story 1.7 closed; a deep-research competitive-UX report captured for the step walkthrough.
May 20265 entries
2026-05-31App build day two: tenant isolation, member flows, Customize tone, top-nav + Epic 2 specs (app + planning)

App build day two: tenant isolation, member flows, Customize tone, top-nav + Epic 2 specs (app + planning)

  • Stories: Story 1.6 tenant-isolation guarantees, closing read-path leaks (#2); Story 1.7 leave-or-remove-member flows (#3); both marked done.
  • Customize: "How your team talks" controls (expertise, reading level, tone) with Material/line icons instead of emoji.
  • Community: advanced /community page + a richer launchpad community tile (roomier Builder spotlight).
  • Shell: top-nav Launchpad (left) + gear settings icon; e2e/a11y regressions fixed.
  • Quality: adversarial code-review report of recent main work (#4), red-baseline e2e/a11y failures fixed (#5), and ready-for-dev specs drafted for Epic 2 stories 2.5–2.8 (#6).
2026-05-30App shell + Home + Epic 12 surfaces (app)

App shell + Home + Epic 12 surfaces (app)

  • Story 1.5 RBAC plus the Epic 12 application shell: Home, Customize, Account, Settings, Templates, and Community.
  • Top-nav shell; Home/workspaces rendered as standalone member cards; a "What's next" drawer.

2026-05-21 to 2026-05-22

Planning mobile nav + design-system rail polish (planning)

  • Mobile nav: a dedicated drawer with a fixed header that shrinks on scroll, solid drawer background, and CTAs cloned into the drawer via hamburger JS; inline epic-chart expand.
  • Design-system rail: favicon + hero CTAs; rail icons + animated toggle + collapse; ds-sidenav top offset to 32px; a marker chip + hover state + collapsed-icon centering.
2026-05-19Onboarding flow + composer v2 across every step + planning nav refactor + case study hero + pricing bump (planning +…

Onboarding flow + composer v2 across every step + planning nav refactor + case study hero + pricing bump (planning + app)

Three-and-a-half-hour late-night push immediately following the 2026-05-18 build. Layered on top of the morning's quorum-app merge.

Onboarding (new): - 4-step flow at /onboarding/{1-workspace, 2-idea, 3-team, 4-kickoff} in the dark .q-frame style with shared OnboardingShell component (DigitalWorldBackground, brand bar, progress dots, glass card). - Step 2 (idea) adds file-upload zone (PNG/MD/PDF) + platform-target picker (Web / iOS / Android / macOS / Windows / TV). - Kickoff page is a server-side router — auto-redirects to /w/<id> so the user never sees an interstitial. - /demo?go={signup|signin|onboarding} route handler: signs out for sign-in/sign-up demos (shows unauthenticated landing), auto-signs-in as DEMO_USER_EMAIL for onboarding so the prototype walkthrough never dead-ends at sign-in.

Composer v2 (every step page): - Stacked layout: target chip on top-left, Override link + outline-pill Lock CTA on top-right, input row with + attach / @ mention / send icon below. Single darker input. - Dynamic step loader rewrites bundle-HTML composer markup on the fly; regex tolerates both <a class href> orderings + q-composer modifier classes + Override buttons with inline SVG. Covers 23/24 step files (legacy team-room excluded).

Three-pillar Desirability redesigned: - Replaces the conversation-view with a curation-view per James's spec. - 6 mock findings, each a card with agent attribution + kind chip (Insight/Risk/Assumption/Direction) + state pill (Included/Flagged/Open) + title + Source row + Impact row + Include ✓ / Flag ◆ / Remove × buttons. - Stage card now shows counts: total / included / flagged / open. Feasibility + Viability ready to mirror the same pattern.

Case study hero (planning): - Injected above case-study.md body by new build_case_study_hero(). - Stat strip (21 agents · N stories · N designed-or-shipped · N in production · 9 weeks mock). - Status donut chart (real bucket counts from sprint-status, including new "mocked" bucket). - 19-step pipeline ribbon with color per status. - Image grid using real Step 1 LIVE screenshots (dark + light) from design-briefs/snapshots/; Step 3 + planning-index slots placeholder.

Planning nav refactored: - Top nav now a pill-shaped liquid-glass container (backdrop-filter: blur(18px) saturate(1.35), border-radius 999px). No per-link borders, no header divider, no hero divider. - TOP_NAV_LIMIT bumped 4 → 5 so all 5 default-visible items (Planning / Team / Case study / Design system / Prototype) fit in the pill. - Planning's Prototype link goes to a hub page (exports/prototype/index.html) with 3 cards: marketing landing (/sign-up), sign-in (/sign-in), demo (/onboarding/1-workspace). Original Quroum bundle overview preserved at prototype/_quroum-overview.html.

Sign-up page (marketing landing): - Price bump (final): Solo Pro $19 → $30/mo ($28/mo annual = $336/yr), Team Starter $39 → $50/mo ($46/mo annual = $552/yr per user), Team Business $79 → $100/mo ($92/mo annual = $1,104/yr per user). Solo Free stays $0. Round-number monthly across the board; annual savings dialed to ~1 month (was ~2) per James's call. - Monthly/annual toggle (PlansSection client component) restyled to match Quorum's design-system language — liquid-glass pill container (same as planning nav), Source Code Pro UPPERCASE labels, cyan-soft active state with inset border + outer glow, ~1 mo free badge in green-soft. Annual shows total/yr, monthly shows "Save with annual · from $X/mo" hint. - Team pricing flagged for review tomorrow — Solo Pro $30 vs Team Starter $50/user crossover math doesn't make sense for 2-3 person teams; feature density per tier needs re-evaluation. - App Store + Google Play badges in hero (12px gap, 4-color Google Play Symbol). - FAQ entry added: "Do you help with the setup work too — domains, hosting, databases?" plus existing export FAQ updated to mention the planning-site export. - Hero top padding reduced ~40px (40→0 narrow, 72→16 wide) to shift content above the fold.

Cross-link nav: - Every Quorum logo in the app (sign-in / sign-up / onboarding / /w/[id] / step pages) links to http://localhost:4567/ (planning home). Sign-in logo swapped from inline 3-dot SVG to the real branded /brand/quorum-plus-dark.svg.

Change-log presentation: - Month-level accordions (May open by default, April collapsed) wrapping day-level accordions (each day shows date + first-bold recap as summary; expand to read full entry).

Other: - Step-2c context tiles: q-ctx-foot { margin-top: auto } so "Open" links align vertically across all three cards. - Step-2b: redundant iterate-on-concept panel removed. - Step-5a journey: "Add stop" → "Add moment". - Initial concept visuals mockups switched to dark mode (oklch 10–14% backgrounds, light text, dark inner rows). - Sprint-status: 22 backlog stories promoted to "mocked" status (designed in prototype, not implemented). Epic-status card adds a Mocked bucket with purple-blue swatch. - /w/<id> workspace page allows anonymous viewing (demo robustness — auth gate stays on mutations, not the presentational shell).

2026-05-18Design briefs library + token preamble + live snapshot pipeline + sign-up hero rebuild (planning + quorum-app)

Design briefs library + token preamble + live snapshot pipeline + sign-up hero rebuild (planning + quorum-app)

Codified the Claude Design workflow as a versioned artifact set. Driven by the realization that every Claude Design session was starting from a blank brain — visual decisions made in one session weren't carrying to the next, the original handoff bundle's team-room had drifted from what we shipped, and revisions lived only in chat scrollback.

New folder _bmad-output/planning-artifacts/design-briefs/ with seven files:

  • README.md — the workflow (Kinsley writes brief → James pastes preamble + reference + brief into Claude Design → bundle returns → dev session implements).
  • _token-preamble.md — the locked visual system in 14 sections (palette, type, spacing, floating-panels grammar, methodology rail, agent roster, streaming patterns, composer, a11y floor, forbidden moves). Paste at the top of every Claude Design session.
  • _queue.md — every remaining V1 screen prioritized A→D for interview-week impact. Step routes (8 unbuilt pipeline steps), settings + admin (6 surfaces), error states, component-documentation framework, all enumerated with status.
  • step-1-describe-shipped-reference.md — the shipped Step 1 documented as a reference brief (~350 lines). Captures every iteration since the original bundle (full-bleed frame, theme switcher, Quorum+ wordmark, sign-out footer, AI assist, transparency tweaks, layout adjustments). Intended to be pasted alongside the preamble at the start of any new Claude Design session so generated screens match what's live, not what the bundle had.
  • Four brief-ready specs: step-2a-concept-alignment.md (150 lines), step-2b-generated-concepts.md (161), step-2c-organize-the-vision.md (184 — references the canonical "what is garbage" screen spec), step-3-three-pillar-analysis-desirability.md (245 — the portfolio-piece centerpiece). Each carries layout, exact copy strings, active roster, accept/reject criteria, ADA callouts.

Live snapshot pipeline (quorum-app/scripts/snapshot-team-room.mjs): captures /w/<id> as a self-contained 105KB HTML file with all stylesheets inlined + dark + light PNG references at 2× DPR. Output lands in design-briefs/snapshots/. Re-run after meaningful changes to the team room before each Claude Design session. Sign-in via the seeded e2e test user. ~30s per run.

Sign-up hero rebuild (quorum-app): replaced the schematic laptop + phone mockups on /sign-up with two tablets framing real screenshots of the live team-room — Step 1 (Describe your idea) in the back tablet, Step 3 (Three-pillar analysis from the bundle's team-room.html) in the front. Tablets are larger (76-78% width), rotated -4°/+4.5°, with three floating feature tooltips between them (Methodology rail / Named AI team / Live artifacts) connected by glowing line projections. Layout switched from float: right + shape-outside to a flex split — fixes the regression where the back tablet covered "studio" in the title at narrow widths; at <1080px the panel becomes column-stacked with tablets below bullets and above "Choose your plan."

Screenshot capture pipeline (quorum-app/scripts/capture-tablets.mjs): Playwright signs in, navigates to /w/<id> and /_demo/step-3.html (the bundle's team-room HTML served statically for capture), grabs both at 1600×1000 @ 2× DPR. Output to public/hero/.

Decisions logged this session: - Repo merge: quorum-app/ → quorum/app/. Reversed earlier "don't merge this week" decision after confirming Vercel was never set up for quorum-app (the assumed deploy-config blocker didn't exist). Subtree-merged quorum-app into quorum/app/ preserving full history via git subtree add --prefix=app. Updated cross-repo paths in scripts (SIBLING_APP_ROOT now points to quorum/app/, design-system snapshot looks at quorum/app/scripts/). Copied gitignored content (.env files, SESSION-RESUME-.md, reference docs/, .claude/settings.local.json) from backup since subtree only brings tracked files. npm install + prisma generate rerun in new location; dev server boots clean from quorum/app/. Backup at ~/Desktop/_backups/quorum-app-pre-merge-2026-05-18/ (2.6 GB). Rollback tag pre-merge-quorum-app-2026-05-18. GitHub repo jcfrank8910/quorum-app will be archived (not deleted) after a few days of stable operation. CLAUDE.md rewritten to reflect single-repo layout. - Design system documentation lives in _bmad-output/planning-artifacts/, not app/.* Component specs (guidelines, code snippets, ADA notes) belong in the planning side; the live /design-system route in app/ reads them at build time when we wire that up. Implementation deferred behind the screen-design queue.

Commits (quorum-app): - 7ab5c41 Sign-up hero: real team-room screenshots in two tablets + feature tooltips

Quorum-app pushed to origin/main (Tier 3 "ship it" at end-of-session). Quorum (planning repo) files written but uncommitted — needs a quorum-side session to fold into a commit per the cross-repo session-hygiene rule.

2026-05-17Team room shell + light/dark theme system shipped (quorum-app)

Team room shell + light/dark theme system shipped (quorum-app)

Driven by James's senior product designer interview this week. Pivoted from Story 1.5 (RBAC enforcement, backend-correct but invisible to a designer interviewer) to a design-led demo build of the team-room shell at /w/<id>.

Two Claude Design handoffs: - First bundle (xAnHFv_LgRZDsnM53ci0Lw) — initial team-room at Step 3 / Desirability. Heavy transcript-driven layout. James reviewed and called it "not futuristic enough" and "too text heavy." First implementation went in (4 commits) but immediately replaced. - Second bundle (sQiIDOtXbWLPnb2dTXiCFw) — full 9-step pipeline (step 1 through step 5 + team-room as step 3). Cleaner floating-panels system. Stage card + agent message + 4-card probe grid + composer pattern. Implemented step-1-describe as the new /w/<id>, replacing the "Team room lands in Story 2.1" placeholder.

Floating-panels grammar shipped: top bar (48px, 16px from edges), step-info bar (full-width, right-aligned roster), left nav (252px, flex-column with sign-out footer), center stage (composer at bottom), right rail (380px, stacked fcards). Backdrop reuses DigitalWorldBackground from /sign-in for visual continuity — the wireframe sphere + plexus appears on both auth and team-room surfaces.

Theme system end-to-end: - Dark = default. Starship-at-night aesthetic. Saturated glass over digital planet. Cyan glow accents. - Light = morning-studio. Crisp white glass over soft sophisticated aurora. Digital-planet canvas hidden (it was the dark-mode signature, reads as muddy noise on light). Comprehensive :root[data-theme="light"] override section in CSS touching ~30 classes (the dark-mode rules use literal color values not tokens, so a token swap alone doesn't work — Kinsley diagnosed this and rebuilt as a real design pass instead of a CSS variable inversion). - ThemeSwitcher client component, persists to localStorage under key q-theme, toggles [data-theme="light"] on documentElement. - Wordmark variant: quorum-plus-light.svg created with dark text + teal "+" preserved (the original SVG had filter: invert + hue-rotate which broke the teal color — replaced with a proper light SVG file).

Components landed: ThemeSwitcher.tsx, IdeaStageCard.tsx (client component owning textarea state so the AI-assist button is disabled-until-typing). Sign-out icon at the bottom of the left nav via the existing signOutAction server action.

Commits (quorum-app): - e473a4c Tooling + small fixes: design-system snapshot, sign-in Suspense, supabase ping (cleanup of dangling 04-29/05-03 edits) - aa2b051 Story 1.5 scaffold (spec only, no code — RBAC enforcement deferred behind the interview) - 7205c09 Team room shell (Story 2.1 partial) — interview-week demo build - 86e96f0 Team room polish: nav sign-out, AI assist wired, IdeaStageCard live

Pushed to origin/main (Tier 3 wrap fired by James saying "ship it" after Kinsley's light-mode rebuild landed).

Side-effects: Supabase project went into paused state mid-session (free-tier hibernation after 19 days inactive); James restored it from the dashboard while we debugged a getaddrinfo ENOTFOUND error on sign-up.

Kinsley sanctum (sibling repo): session log written at _bmad/memory/bmad-agent-ux-designer/sessions/2026-05-17.md capturing the light-mode architectural diagnosis (dark rules use literals not tokens, so overrides have to target classes not variables). MEMORY.md updated with the team-room shell + theme architecture. PERSONA.md evolution log records the first time crossing the "no production code" boundary (James asked explicitly with interview-week stakes).

April 20268 entries
2026-04-29Live design-system snapshot pipeline — built, then reverted (planning + quorum-app)

Live design-system snapshot pipeline — built, then reverted (planning + quorum-app)

Prototyped a daily-refresh pipeline that would render quorum-app's /design-system route via Playwright and embed it inside Quorum's standard export wrapper. Two iterations, then removed.

  • First iteration — full-page snapshot. New quorum-app/scripts/snapshot-design-system.mjs booted a next dev server on port 3091, navigated Playwright to /design-system, inlined every external stylesheet plus all url() font/image references as base64 data URIs, stripped scripts, and wrote a self-contained ~415KB exports/design-system/index.html. Captured four interactive-state screenshots (full-page, modal-open, select-open, toast-success) into exports/design-system/screenshots/. Hooked into _gen_all_exports.py via a thin Python wrapper (_gen_design_system_snapshot.py) so daily export refreshes regenerated it automatically. Worked end-to-end (~30-45s added to the export run).
  • Issue caught on review: the full-page snapshot replaced Quorum's standard nav / hero / footer entirely with quorum-app's own page chrome. Wrong shape for an export page that should feel like the rest of the planning tree.
  • Second iteration — content-only embed. Rewrote the Node script to extract just the .ds-container outerHTML, walk the CSSOM and scope-prefix every rule with .ds-embed (mapping :root/html/body to .ds-embed, dropping bare *, prefixing the rest), inline assets as data URIs, and write a JSON payload ({ contentHtml, cssText, capturedAt, source }) to _tmp/design-system-snapshot.json. Added a _render_design_system_from_snapshot helper in _gen_bmad_exports.py that consumed the JSON and built the page as Quorum hero + Source-of-truth callout + scoped <style> block + <div class="ds-embed app-scene ds-scene">{contentHtml}</div>, all wrapped via wrap_page so the page got Quorum's chrome. Reordered _gen_all_exports.py so the snapshot ran before _gen_bmad_exports.py. Worked: ~520KB self-contained page with Quorum nav around the embedded design-system content.
  • Decision: revert. Both iterations removed. Surfaced two real-world reasons to step back: (1) the snapshot strips every <script> tag by design — necessary because a static HTML export can't host the React runtime — which means modal triggers, slide-swap, the custom Select listbox, the Toast firing buttons, and the Pill counter all appear non-functional in the snapshot. Playwright captures the open-state screenshots before the strip, so the visuals look right, but interactive triggers in the embedded HTML are dead. That's a structural ceiling, not a fixable bug. (2) Sticks with the deferred-deep-docs posture from project_design_system_deferred.md — Quorum's design-system page stays as a minimal live-read scaffold (parsing globals.css :root, listing src/components/ui/*.tsx, extracting fonts from layout.tsx) until quorum-app's design system stabilizes post-Story 2.x.
  • Files removed (planning repo): _gen_design_system_snapshot.py, _tmp/design-system-snapshot.json, exports/design-system/screenshots/. _gen_bmad_exports.py and _gen_all_exports.py reverted to their pre-experiment state via git checkout HEAD --. exports/design-system/index.html regenerated from the live-read fallback.
  • Files removed (quorum-app): scripts/snapshot-design-system.mjs, the empty scripts/ directory. package.json snapshot:design-system script entry removed.
  • Approach kept on the shelf: the embed-with-Quorum-chrome shape is the right answer if/when we revisit. The CSSOM scope-prefixing logic + data-URI asset inlining + JSON payload pattern all worked. To deliver real interactivity later, the snapshot would need to either (a) stop stripping scripts and inline the Next bundles + React runtime alongside the content, or (b) shift to an iframe-against-deployed-app pattern once quorum-app is hosted. Re-buildable from this entry's description if a later sprint decides to commit to it.

Pill default label fix (quorum-app)

  • src/app/design-system/page.tsx:527-529 — pill counter button was rendering Click me (0) on first paint, which read like preset state rather than an affordance. Changed the label expression from Click me ({count}) to Click me{count > 0 ? (${count}): ""} so the default reads Click me, with the counter appearing only after the first click. No state or behavior change. File-write only on the quorum-app side this session; will commit from a quorum-app session.

Design-system showcase v3 — fully interactive iframe (planning + quorum-app)

After the two-iteration revert above, returned to the problem with a different approach: instead of stripping the React runtime, ship it.

  • New quorum-app/scripts/snapshot-design-system.mjs (~270 lines) runs next build && next start (production bundles, not dev) on port 3091, navigates Playwright to /design-system, captures every same-origin response into quorum/_bmad-output/planning-artifacts/exports/design-system-app/<path> mirroring the URL structure, exercises the interactive states (modal, select, toast, slide-swap) so any code-split chunks load and get captured, then writes the rendered HTML to index.html in the same folder.
  • Path-rewrite post-process. Walks every captured .html, .js, and .css file and replaces /_next/ absolute paths with relative _next/ references. CSS files in _next/static/css/ get their url(/_next/static/media/...) calls rewritten to url(../media/...) to resolve correctly relative to the CSS file's location. Result: the static bundle works under any URL prefix — local dev under localhost:8000/exports/design-system-app/, deployed at quorum.jayfrank.info/design-system-app/, or even file://.
  • Iframe wrapper. _render_design_system_iframe in _gen_bmad_exports.py builds the design-system page as Quorum's standard hero + Source-of-truth callout + an iframe pointing at ../design-system-app/index.html. Iframe gets a fixed viewport height (min(900px, calc(100vh - 220px)), min 600px) so its position: fixed modals and toasts position correctly to the iframe's viewport instead of the auto-grown content height. Same-origin so postMessage works freely.
  • Result. Fully-interactive design-system showcase inside Quorum's chrome. Click the modal triggers and modals open. Click the Select trigger and the listbox opens. Fire a toast and it actually slides in. Slide-swap demo animates. Pill counter increments. Everything that works on localhost:3000/design-system now works at localhost:8000/exports/design-system/index.html — and will work at quorum.jayfrank.info/exports/design-system/index.html after deploy. Bundle: 13 files, ~680KB on disk; ~300-500KB over the wire after Cloudflare brotli.
  • Daily refresh. python3 _gen_all_exports.py rebuilds the bundle automatically on Tier 1+ wraps. Adds ~60-90s to the export run for the production next build.

Suspense fix on /sign-in — surfaced by the production build (quorum-app)

The production next build from the snapshot pipeline above caught a real prerender bug that dev mode tolerates: useSearchParams() in SignInForm requires a Suspense boundary in app router for static prerender. Wrapped <SignInForm /> in <Suspense fallback={null}> at src/app/sign-in/page.tsx. Bonus catch — would have broken the production deploy whenever quorum-app gets to that step. Easier to find now than later.

PRD § The Three-Pillar Framework — new section, ~210 lines (planning)

The existing ## Three-Pillar Checkpoint Gates section covered gate mechanics (pass / fail / needs revisit). What was missing: the framework itself defined as Quorum's core practice — what each pillar means as a discipline, the agents who own each, the methods that run under each, the artifacts that come out the other side.

Added a new ## The Three-Pillar Framework section before the existing gates section. Structure:

  • Why this is the differentiator — Quorum operationalizes Desirability / Feasibility / Viability as a process discipline, not a slide title. Distributes the argument across three orthogonal owners.
  • Pillar 1 — Desirability (lead Mary). Supporting cast Quentin, John, Maya, Carson, Sophia, Freya. Ten methods named (interviews, JTBD personas, empathy mapping, design-thinking workshops, trigger mapping, scenario design, moments-that-matter inventory, voice-of-customer, storytelling-framework analysis). Eight artifacts named with file paths.
  • Pillar 2 — Feasibility (lead Winston). Supporting cast Damien, Jaymes, Murat, Cipher, Kinsley, Quinn, Amelia. Eleven methods named (ADRs, technical research, component inventory, ATDD, NFR assessment, traceability matrix, threat modeling, adversarial review, implementation-readiness check). Nine artifacts named with file paths.
  • Pillar 3 — Viability (lead John). Supporting cast Victor, Mary, Sophia, Caravaggio, Bob, Atticus. Eleven methods named (market / competitive / domain research, innovation strategy, business-model architecture, PRD authoring + validation, pitch storytelling, sprint planning, compliance review). Eleven artifacts named with file paths.
  • How the three pillars work together — explains orthogonality. Desirability without feasibility is wishful thinking. Feasibility without desirability is engineering theater. Viability without either is strategy fiction. Cross-references existing FRs 21–25d, journey J2, success criteria, and MVP scope.

The existing gate-mechanics section stays unchanged; the philosophy → mechanics flow now reads top-down through the document.

Team page — new export at /team/, 22 agents organized by pillar (planning)

New Team entry added to primary nav (default on, between Planning and Case study). New render_team_index() produces exports/team/index.html with two-level disclosure:

  • Three pillar cards (collapsed by default). Each is a liquid-glass card with a 4px left accent in its pillar color (cyan / cool green / amber). Title, agent count badge, lede, Material-style chevron pointing down. Click expands to reveal the rich agent grid inside.
  • 22 agent cards. Six custom DT agents (Cipher, Damien, Jaymes, Kinsley, Luca, Quentin) plus sixteen BMad agents featured in the framework (Mary, John, Winston, Bob, Murat, Amelia, Quinn, Sophia, Maya, Carson, Dr. Quinn, Saga, Freya, Victor, Caravaggio, Atticus, Barry, Paige). Each card has the agent's name, role, lede, pillar chips (primary solid + each secondary outlined), collapsible "What they run" (3-11 methods) and "What they produce" (1-11 artifacts) sections, trigger-phrase footer.

Visual choices that landed:

  • Pillar-based color coding instead of arbitrary per-agent hues. Every Desirability card shares cyan; every Feasibility card shares cool green; every Viability card shares warm amber. The framework's three colors carry through every card so the page reads as the framework.
  • Pillar chips on each card. Primary pillar = solid filled chip in that color. Each secondary pillar = outlined chip in that color. Cross-pillar agents (Mary D+V, Sophia D+V, Saga D+V, Dr. Quinn D+F+V, Kinsley F+D, Atticus V+D+F, Paige F+D+V) read at a glance.
  • Atticus expanded cross-pillar. Was Viability-only; now spans all three. Methods extended from 5 to 8 (added data-handling compliance, security compliance frames, attorney matchmaking). Artifacts extended from 2 to 4.
  • Liquid-glass containers for both pillar cards and agent cards. 24px backdrop blur + 1.4 saturate, translucent surface, inset top highlight, soft outer shadow, hover depth.
  • Material-style chevrons (down by default, rotate 180° to up on expand). 22px on pillar cards, 13px on agent details. Stroke-based SVG inheriting pillar color.
  • No avatars. Removed in favor of pure name + role + chips header.
  • Cards collapsed by default with summary counts ("What they run · 8 methods" / "What they produce · 4 artifacts"). Page is one viewport tall when fully collapsed.

Total roster on the page: 22 agents. Each appears once in their primary pillar. Secondary contributions surfaced via chips, not duplicated cards.

Luca's First Breath + motion spec implementation (planning + quorum-app)

Brought Luca (motion designer) online for the first time on this project. First Breath protocol detected an immediate need (motion spec for the team-page disclosures), deferred discovery questions, served the spec.

  • Sanctum created at _bmad/memory/bmad-agent-motion-designer/ with PERSONA, BOND, CREED, MEMORY, INDEX, and sessions/2026-04-29.md.
  • Global preference locked: ~/.claude/agent-preferences.yaml set with agents.luca.name: Luca. Future projects pick this up automatically.
  • Motion tokens defined and added to _style.py :root: --motion-duration-quick (160ms), --motion-duration-medium (220ms), --motion-duration-deliberate (320ms), --motion-ease-decel (cubic-bezier(0.2, 0.8, 0.2, 1)), --motion-ease-standard (cubic-bezier(0.4, 0, 0.2, 1)), --motion-ease-accel (cubic-bezier(0.4, 0, 1, 1)). Durations match existing quorum-app/globals.css conventions; the decel curve matches the existing Select listbox enter and modal slide.
  • Disclosure spec. Two scales — L1 pillar cards (320ms, settles into place with optional 2px translateY lift) and L2 agent-card details (220ms, no translate). Both use the decel curve, animate height + opacity (0.6 → 1 on L1, 0.7 → 1 on L2), no stagger between siblings. Chevron rotation synced to parent duration and curve.
  • Implementation. Added class="motion" and data-motion-scale="L1"|"L2" to each <details>. Wrapped non-summary children in <div class="motion__content">. Inline ~30-line JS helper using Web Animations API on <details> toggle events (since native <details> doesn't animate). prefers-reduced-motion: reduce collapses durations to 1ms (snap), drops opacity fades and translates, keeps chevron rotation as a directional indicator.
  • Result. Pillar cards expand and collapse with a quiet, settling motion. Agent-card details snap open at a faster pace because they're nested context. Chevron rotates in sync. No stagger that would feel performative across 11 cards. Apple-quiet. The temporal layer is now part of the design vocabulary.
2026-04-28Story 1.3.2 → review: WCAG AA gate goes wide, 5 e2e regressions cleared (quorum-app, afternoon session)

Story 1.3.2 → review: WCAG AA gate goes wide, 5 e2e regressions cleared (quorum-app, afternoon session)

Path A from yesterday's recommendation: close Epic 1. Story 1.3.2 moved draftreview. The day's substance was widening the automated WCAG 2.1 AA coverage from the design-system reference page out to the post-auth core surfaces and the full /sign-up funnel — which immediately earned its keep by surfacing three more real production contrast bugs on shared chrome. All fixed, all retested, full gate green twice back-to-back. Tier 2 wrap, 4 commits on local main, unpushed.

Wider WCAG 2.1 AA coverage — 12 page-states under the gate (quorum-app)

  • Coverage extended past the design-system reference page out to the surfaces users actually live on. New axe-core scans cover: /design-system at rest + with modal open, /sign-up, /sign-in, /workspaces picker (clean + with Edit modal open), /w/<id>, /w/<id>/members (team variant + solo_free variant), /new-workspace landing + plan-change panel, /sign-up?plan=solo_pro credentials step, /sign-up/pay?plan=solo_pro. Twelve distinct page-states. 39 axe scans across the run. Critical + serious filter — no severity exclusions on /sign-up anymore.
  • Three real WCAG AA contrast bugs caught + fixed on the very first wider pass:
  • .sp-plan__period ("/mo" and "per user / mo" on every plan card across the funnel) — 3.22:1 (oklch(48%) ≈ #516164 on deep bg). Token swapped from --sp-fg-subtle to --sp-fg-subtle-aa (the AA-passing variant already existed in the codebase, just unused on this element). Now ~5.5:1.
  • .sp-footer-link a ("Already have an account? Sign in" on credentials step) — 1.72:1 link-vs-surrounding (cyan accent on muted gray, no underline). Added text-decoration: underline + 3px offset matching the existing .sp-legal treatment. WCAG 1.4.1 satisfied via non-color distinguisher.
  • .sp-footer a (same link wording on the landing-page footer) — same cause, same fix.
  • Pattern is now consistent across two days of audit hits: the --*-fg-subtle family of tokens (oklch 48%) is below AA on the deep backdrop in this codebase. The codebase ships -aa variants of the same tokens for exactly this case. Rule, written down: use the -aa variant for primary text on the deep bg; reserve plain -subtle for very-dim secondary content where AA isn't expected.

Five e2e regressions surfaced + fixed (quorum-app)

The first full e2e run after the a11y work surfaced 5 regressions. None were caused by today's changes — all were existing drift from earlier voice / visual work that the spec selectors hadn't caught up with. All fixed in 8d68d74:

  • Four hits in signup-funnel.spec.mts (lines 76, 101, 118, 129) traced to the Quentin voice pass at commit 81b4a4b. "Continue" is a banned generic verb in the voice guide; the comparison-panel CTA had been renamed ContinueSwitch to <plan-name> (e.g. "Switch to Team Starter") and the back button Go back → "Keep current plan". Test selectors weren't updated. Regex moved to /^Switch to /i and /^keep current plan$/i.
  • One hit in sign-in.spec.mts:53 ("multi-workspace picker lists memberships and navigates on click"): getByRole("link", { name: /Globex/i }).click() was finding the absolute-positioned .app-ws-card__link but the click was landing on a foreground sibling (the card content sits at higher z-index than the link's z-index: 1 because of stacking-context order). force: true didn't help — Playwright still routes through document.elementFromPoint which respects z-index. Switched to keyboard simulation (focus() + Enter). Cleaner than force-click; mirrors real keyboard-nav.

Story 1.3.2 status flipped to review (quorum-app)

  • Story file: _bmad-output/implementation-artifacts/1-3-2-self-signup-with-plan-type.md — Tasks 13 + 14 checkboxes flipped with close-out notes; status header now reads review.
  • Sprint status: _bmad-output/implementation-artifacts/sprint-status.yaml1-3-2-self-signup-with-plan-type: review. last_updated: 2026-04-28. most-recent-action updated.
  • Closed tasks: 1, 3, 4, 6, 7, 8, 10, 11, 12, 13 (catalog test confirmed shipped + a11y followup landed), 14 (gate green + docs + status flip). Tasks 2 + 9 marked DONE per project_stripe_mocked_v1 (placeholder IDs + Mock pay button). Deferred (not blockers to review): Task 5 (OAuth Google + Apple) blocked on developer-projects setup; OAuth happy-path e2e + Stripe paid-plan happy-path e2e blocked on those tasks shipping.

Moments That Matter v0.5 — moment #58 added (planning repo)

  • New moment #58 First automated WCAG AA gate goes green in Build and implementation. Builder / team peak rather than user-facing. Captures the specific moment when the wider gate clears 12 page-states for the first time and "a11y as floor, not ceiling" stops being a phrase and becomes a CI gate. Maps to NFR-A1 (WCAG 2.2 AA), NFR-A6 (VPAT readiness), accessibility-statement.md, FR47 (portfolio doc — automated gates are part of the case study).
  • Frontmatter bumped 0.4 → 0.5 with corresponding changelog row inside the doc.

Platform decision locked to memory (quorum-app side)

  • New entry project_platform_web_first_tauri_later.md indexed in the quorum-app project memory MEMORY.md. Locked answer to the recurring question "are we web or native": web-first Next.js, future macOS via Tauri shell, never native iOS / Android / SwiftUI / RN. Surface this when the question comes up rather than re-debating.

Verification at wrap (quorum-app)

  • npm run typecheck clean.
  • npm run lint — 0 errors, 1 pre-existing react-hook-form watch warning in SignUpForm.
  • npm run test -- --run — 51/51 vitest unit tests pass (6 files).
  • npm run test:e2e93/93 playwright tests, run twice back-to-back (~8 min each). Specs: a11y-coverage (10), create-workspace, design-system (29), edit-delete-workspace (12), invite-and-accept, sign-in, signup-and-plans, signup-funnel, workspace-upgrade (5).

Commits (quorum-app, Tier 2 wrap, 4 unpushed on local main)

  • f25683f — Wider WCAG 2.1 AA coverage — post-auth core + extended marketing.
  • b4937fe — A11y: extend coverage to /sign-up funnel + fix 3 WCAG AA bugs.
  • 07f5494 — Story 1.3.2: Task 13 close-out + Task 14 docs.
  • 8d68d74 — Story 1.3.2 → review: 5 e2e regression fixes + status flip.

Push deferred to next quorum-app session per Tier 2.

Cross-repo state at wrap

  • quorum — local main 1 commit ahead of origin/main (5a6f1ec Wave 5 from 2026-04-27 evening, still unpushed). Two uncommitted file writes from quorum-app sessions: moments-that-matter.md (moment #58 + frontmatter v0.5) and this change-log.md entry. Tier 2 wrap on the quorum side will fold both into a single commit; Tier 3 will push Wave 5 + the new commit together.
  • quorum-app — local main 4 commits ahead of origin/main. Push deferred.
2026-04-27Wave 4 polish on planning exports (planning repo, evening session)

Wave 4 polish on planning exports (planning repo, evening session)

  • Epics-nav rebuilt from native <select> to a custom dropdown component ported from master-doc's .dd pattern. First attempt used a fixed-position portaled listbox at z-index 1000; that anchored to a transformed/blurred ancestor and rendered "far below the trigger and behind tiles" — same root cause as today's quorum-app modal-clipping fix. Second attempt copied master-doc's approach verbatim: position: absolute inside .dd { position: relative }, no portal, panel at z-index: 30 inside an .epics-nav whose z-index: 20 actually sticks (see next bullet).
  • body > * z-index normalizer corrected. The rule body > *:not(.page-globe):not(.am-modal-overlay) { position: relative; z-index: 1 } was clamping .epics-nav to z-index 1, trapping its descendant dropdown panel inside a low stacking context. Added :not(.epics-nav) to match master-doc — comment explains the specificity reason (0,2,1 vs. 0,1,0) so future passes don't strip the exclusion.
  • .epics-nav no longer sticks to the top of the viewport. Dropped position: sticky; top: 0 in favor of position: relative (z-index retained for the dropdown panel layering). The container scrolls naturally with the rest of the page now.
  • Dropdown panel opacity bumped 0.84 → 0.9 for legibility. Hardcoded the rgba on .dd__panel rather than mutating --surface-strong to keep the change scoped.
  • "Living document" pill margin fix. .doc-status-meta was -0.25rem 0 1.75rem — negative top pulled the pill tight against the subtitle. Now 1.25rem 0 1.5rem for breathing room above and below.
  • Backups of _gen_bmad_exports.py and _style.py saved as *.bak-2026-04-27 (untracked) before the dropdown rewrite — keeping them out of the commit so the working tree stays clean.

Workspace edit + delete API shipped (quorum-app, all-day session)

  • New PATCH/DELETE /api/workspaces/[id] route with owner-only authz via membership lookup. Zod validator (updateWorkspaceSchema) supports partial updates of name + planKey with an at-least-one refinement. P2002 dup-name returns 409 with the existing-workspace context. DELETE wraps workspaceInvite + membership cleanup + workspace.delete in a Prisma transaction since the schema doesn't declare onDelete: cascade.
  • Stripe stays fully mocked per project_stripe_mocked_v1 — plan transitions sync mock IDs (paid plans get mock_cus_<uuid> / mock_sub_<uuid> populated; free plans clear them). Mirrors the create flow's behavior.
  • Two new error codes added to src/server/errors/codes.ts: workspace_not_found and workspace_not_authorized.
  • EditWorkspaceDialog + DeleteWorkspaceDialog wired to real fetch with loading state, inline error rendering, dup-name 409 surfacing, and router.refresh() on success. Privacy radio dropped from the edit form since Workspace.type is server-derived from plan (mirrors create flow).
  • New e2e spec at tests/e2e/edit-delete-workspace.spec.mts (10 tests). 7 API-level tests passing (PATCH/DELETE happy paths, mock Stripe ID transitions, transactional cascade, authz, unauthenticated). 3 UI-level tests have selector misses against post-rename markup; deferred until a follow-up touch.
  • Stale-form-state bug fixed: dialogs now mount only when open in WorkspaceCardActions, so useState reinitializes from current props after a save → router.refresh updates the workspace name. Previous behavior: dialog stayed mounted across opens, capturing stale name.

Modal UX system v2 (quorum-app)

  • Modal portaled to document.body via createPortal. Fixes the card-clipping bug (workspace cards used backdrop-filter, which creates a containing block for position: fixed descendants — modal got rendered inside the card).
  • Size scale added: small=400 / medium=640 / large=800 via size prop on Modal. EditWorkspaceDialog uses medium; DeleteWorkspaceDialog uses small. The 600px workspace tile container + 640px Edit modal gives a 40px breathing room when the modal overlays.
  • Stronger panel contrast: lighter surface (oklch(15% 0.014 215 / 0.97) from 8% / 0.94), accent border (oklch(40% 0.02 215 / 0.7)), stacked drop-shadow + 2px inner top highlight (4% white) for a subtle bevel that reads as elevation against the dimmed page.
  • Backdrop blur fixed and bumped to 28px + saturate(0.85) at 0.45 dim. Three blockers removed: isolation: isolate from .app-scene (created a stacking context backdrop-filter couldn't see through), nested backdrop-filter from .app-ws-panel and .app-ws-card (Chrome's compositor doesn't cascade nested ones cleanly).
  • New .app-modal-swap slide-pattern track for dialogs that need a primary view + sub-view. Mirrors the /new-workspace .app-plan-swap mechanic — outer container clips, inner track is 200%-wide flex with two 50% panels, data-mode controls translateX. JS measures the active panel's height via ResizeObserver so the modal doesn't reserve empty space.
  • New .app-pill-btn for compact secondary navigation chips inside dialogs. Frosted dark surface, soft border that lights up to accent on hover/focus, fully-rounded.

Custom Select component (quorum-app)

  • New src/components/ui/Select.tsx replaces the native <select> in the Edit dialog plan field. Per James's directive: no native dropdowns in this app or flow.
  • Listbox portaled to document.body (z-index 90, above modal at 80) so the options panel escapes overflow/clip ancestors and works inside the modal without being clipped.
  • Keyboard nav per WAI-ARIA APG combobox/listbox pattern: Enter/Space/ArrowDown opens, arrows move highlight, Enter/Space commits, Escape closes (focuses trigger), Tab closes, Home/End jump to ends.
  • Frosted-glass open state (oklch(8% 0.01 215 / 0.96) + 14px backdrop blur). Selected row in accent color + bold; highlighted row in subtle blue-tinted overlay. Optional description per option (used for plan blurbs in the Edit dialog).
  • Trigger styled via .ap-select-trigger (matching .ap-input aesthetic + chevron that rotates 180° when open). Listbox styled via .ap-select-listbox + .ap-select-option.

Toast success tone (quorum-app)

  • Toast accepts an options object now: showToast(message, { tone?: 'default' | 'success', durationMs? }). Existing slide-from-top animation, 4s hang, single-slot semantics all unchanged.
  • Success tone renders with green-tinted glass (oklch(18% 0.06 145 / 0.92) background + oklch(72% 0.16 145 / 0.45) border + soft inner glow) and a check icon in a circular green pill on the left.
  • Wired up at three call sites: EditWorkspaceDialog (echoes what changed: rename / plan / both), DeleteWorkspaceDialog, ChangePlanPanel (existing detailed billing message gets the success tone).

Workspace surfaces tweaks (quorum-app)

  • /workspaces cards wrapped in .app-ws-panel container (max-width 600px, centered, padding 24px, soft border + radius). Quiets the wired-globe behind the workspace block so it reads as a discrete piece of UI. backdrop-filter removed from this container per the modal-blur fix above.
  • /w/<id> workspace room stub gets a one-line description next to the Members link: "Roster, roles, and how to invite the next person in." Story 2.1 will rewrite the page; the line is safe to ship ahead of that.

Quentin voice pass + locked copy (planning repo)

  • Two locked-copy decisions captured in Quentin's MEMORY.md under a new "Locked Copy Awaiting Implementation" section:
  • Manage-members slide descriptive line: "Add teammates, set roles, and remove access without leaving this workspace." — held for the option-2 inline-management story; do NOT ship on the current read-only slide because the line promises three actions the slide doesn't deliver (same voice mismatch as the original "Manage members" pill label).
  • Workspace-room Members link description: "Roster, roles, and how to invite the next person in." — shipped this session.
  • Cross-layer flag: original "Manage members" pill on the read-only slide was a label that promised more than the UI delivered. Two paths offered (rename pill to match function, or build inline management to match label). James picked option 2 long-term but agreed to interim rename for this story. Pill renamed to "See members" until inline management lands.

Kinsley + Luca engagement queued (planning, not started)

Three bundled work streams scoped for one Kinsley + Luca engagement, awaiting trigger:

  1. Stream 1 (Kinsley): Living Design System at _bmad-output/planning-artifacts/design-system.md. Inventory existing components (Modal sizes, Select, Toast tones, button system, inputs, cards, pill, tokens, layout patterns). Each component documented with tokens / variants / usage rules / a11y notes / code locations.
  2. Stream 2 (Kinsley): Living User Flow Map at _bmad-output/planning-artifacts/user-flow-map.md. Mermaid diagrams + prose for 10 flows (sign-up funnel, sign-in, first workspace creation, switching, edit, delete-via-archive-future, member management, invite acceptance, plan-change scenarios, solo-to-team auto-promote).
  3. Stream 3 (Kinsley + Luca paired): Cross-review of edit/delete flow against Stream 1's design system. Kinsley = component fit + states + design tokens. Luca = motion (modal entrance 240ms scale-in, slide 480ms cubic-bezier, toast 320ms, Select listbox 140ms, hover states, focus rings, reduced-motion).

Quentin will do voice + a11y pass on Streams 1-2 after Kinsley drafts. Trigger phrases: bring in Kinsley / bring in Luca / bring them both. Sequence: Streams 1 → 2 → 3.

Project memory updates (quorum-app side)

  • New entry: project_workspace_archive_then_delete.md — workspace deletion will go through Archive in a future story (soft-delete first, hard-delete only from Archive view). Two-stage gate prevents one-click destructive accidents (Notion / Linear / Gmail / Stripe pattern). Schema add: archivedAt: DateTime?. Estimated half-day. Indexed in MEMORY.md.

Workspace creation features (proposal, not built)

Three new dimensions on workspace creation surfaced for design discussion (no code):

  • Agent set: Lean / BMad Default / Full Stack DT / Custom — controls which agents the workspace uses
  • Export template: None / Master-doc style / Custom branded — controls end-of-project artifact rendering
  • Project type: Greenfield / Brownfield import / Master-doc scaffold — controls how the workspace begins

Recommended phasing: Phase 1 = three nullable fields on Workspace, three picks in /new-workspace with skip-for-now defaults, surface on the tile as a small metadata strip. Pretend / mocked (no filesystem provisioning) per the project_stripe_mocked_v1 precedent, labeled honestly as "preview" / "saved for v2." Phase 2 = settings page so users can change later. Phase 3 = real provisioning via a Claude Code skill bridge.

Commits (quorum-app)

  • d4fd698 — Workspace edit + delete API + modal UX system. One bundled commit because EditWorkspaceDialog carried both API wiring and UX system in the same heavily-rewritten file. 15 files / 1359 insertions / 181 deletions. Lint + typecheck clean. Tier 2 wrap, no push — 6 commits now sit unpushed on local main.

Afternoon session — design system route, user flow map, FAQ + a11y polish (quorum-app)

The afternoon picked up uncommitted in-flight work that wasn't recapped in the morning Tier 2 wrap (two new Next routes, TextField component, liquid-glass refresh, ~1.7k line delta). Audited it, fixed real bugs the audit surfaced, then closed all five carried 04-25 visual-review checklist bullets. Tier 3 wrap at the end — five commits pushed to origin/main.

/design-system — internal-facing live reference page (quorum-app)

  • New route at src/app/design-system/page.tsx (733 lines) + design-system.css. Imports actual Modal, Select, Toast, TextField from the codebase so the doc cannot drift from production. Sections: Tokens / Layout patterns / Components / Planned, with TOC. Internal developer reference; the forward-facing portfolio version is the existing quorum/_bmad-output/planning-artifacts/design-system.md (still a stub).
  • New e2e suite tests/e2e/design-system.spec.mts (29 tests). Covers smoke + structure, TextField states, Select keyboard nav, Modal three sizes + Escape + slide-swap, Toast tones, Pill, Buttons, status badges, workspace card. Includes axe-core WCAG AA passes on /design-system at rest, with Modal open, on /sign-up, and on /sign-in.
  • Two real production WCAG AA contrast bugs caught + fixed on the very first axe pass — exactly what the live-reference page was built for:
  • .app-modal__btn-danger (every Delete-workspace button) was 4.05:1 (white on #d74745). Background darkened to oklch(50% 0.18 25) (~5.5:1). Hover and focus tones moved together so the button still lifts visibly on hover.
  • .app-ws-card__updated-abs (every workspace card timestamp) was 3.19:1 (#516164 on #010303). Switched the color token from --app-fg-subtle to --app-fg-muted (~5.5:1).

/user-flow-map — server-rendered mermaid pipeline (quorum-app)

  • New route at src/app/user-flow-map/page.tsx. Server component reads docs/user-flow-map.md (50KB, 12 flows) at request time, walks the markdown token stream so mermaid fenced blocks become live <MermaidBlock> client components and everything else renders as static HTML.
  • MermaidBlock lazy-imports mermaid on first use (no SSR touch), renders each block with a stable useId instance, dark theme matching the app's cyan tokens, per-block error fallback, and collapsible mermaid source. marked + mermaid added as deps.
  • First audit: only 4 of 12 blocks rendered. Pre-existing docs/_fix_mermaid_syntax.py script was in the repo for exactly these issues but its regex didn't catch enough cases. Three categories of fix landed:
  • Path nodes with embedded slashes (8 blocks). Mermaid reads [/.../] as a parallelogram shape; embedded slashes in node labels like WS[/w/id], Root[/], MembersPage[/w/id/members] corrupted the parse. Script now wraps any such label content in double quotes regardless of inner slashes.
  • <br/> self-closing tags. Mermaid HTML labels accept <br> but not <br/> — the /> confused the lexer in non-quoted labels. Now globally normalized to <br> inside every mermaid block.
  • Sequence-diagram parse failure (block 10, invite acceptance). Two issues: (1) semicolon as statement terminator — mermaid treats ; as a newline-equivalent statement separator, so Create membership; mark invite acceptedAt was being read as two statements and the second failed. Script now swaps ; for , inside sequence bodies. (2) Mid-word apostrophe: existing curly-quote regex (\b\w)'(\w) required a word boundary and missed You're. Tightened to (\w)'(\w).
  • After fixes: all 12 blocks render with non-zero SVG bounding boxes. Audit script was throwaway and removed.

TextField component + liquid-glass coherence pass (quorum-app)

  • New shared component src/components/ui/TextField.tsx — floating-label outlined input. Material 3 outlined-variant behavior with Quorum cyan accent. Implementation uses a <fieldset>/<legend> pair to draw the outline + create a natural notch behind the floating label, with :placeholder-shown driving the empty-vs-filled state.
  • Adopted in four feature forms in this commit: CreateWorkspaceForm, EditWorkspaceDialog, DeleteWorkspaceDialog, InviteForm. RHF integration via <Controller>.
  • Liquid-glass coherence sweep: globals .ap-card, sign-in scene card, sign-up plan tile, sign-up plan-compare card all unified to the app-scene recipe (24px blur + 1.4 saturate + inset highlight + edge ring + softer outer drop). The Modal portal makes nested backdrop-filter on .ap-card safe again. Single visual language across pre-auth and post-auth surfaces.
  • Sign-out routing change: unsigned visitors now land on /sign-up (the marketing surface) instead of /sign-in. Returning users still reach /sign-in via the footer link there.

Sign-up FAQ accordion — predictable layout (quorum-app)

  • .sp-faq__grid is a 2-col CSS Grid at ≥900px. Default align-items: stretch was making a closed left card grow to match the right card's height when the right card was opened (and vice versa) — confusing because the left card visibly changed without any interaction.
  • Set align-items: start so each card keeps its natural height. Opening one card now grows only that card; its sibling stays put. Some whitespace appears below the shorter card — explicit trade-off, predictable layout beats packed layout here.

Carried 04-25 visual-review checklist — all five bullets closed (quorum-app)

  • ✅ AuthenticatedHeader top-right + New workspace link verified — wired correctly with hover state and /new-workspace target.
  • ✅ Solo-free /w/<id>/members Upgrade CTA → invite-form-reveal stagger verified — CSS at globals.css:240-264 still matches the post-TextField + post-Select InviteForm DOM (email TextField div as nth-of-type 1, role wrapper div as nth-of-type 2, submit button — keyframe delays 0/100/200ms).
  • ✅ Solo-pro /w/<id>/members "Upgrade to Team Starter →" link verified — points at /sign-up/pay?plan=team_starter with explicit non-bait copy ("Real plan changes for an existing Solo Pro land in a future update").
  • ✅ Role-dropdown chevron breathing room + frosted background blur — last hold-out from the custom Select rollout. InviteForm role field migrated from native <select> to custom Select via <Controller>. Reuses existing ROLE_OPTIONS retyped as SelectOption<Role>. Label moves from htmlFor= to id= + ariaLabelledBy= since the trigger is a <button>. workspace-upgrade.spec.mts 5/5 still green.
  • ✅ Teal-line artifact regression check — searched .app-ws-card and decorations for any teal/cyan border-top or pseudo-element accents; none found. Regression remains fixed.

Commits (quorum-app, Tier 3 push)

  • 9d34857 — Design system route + flow map + TextField + liquid-glass refresh. 21 files / ~2.1k insertions.
  • 79a6930 — Update edit-delete spec selectors for TextField label rename. (1 file, 4/4.)
  • a16f6ff — Fix all 12 user-flow-map mermaid blocks. (_fix_mermaid_syntax.py upgrade + the markdown source rewrites it produces.)
  • 2066710 — Stop FAQ accordion siblings from stretching to match each other.
  • a25db16 — Migrate InviteForm role to custom Select.

d4fd698..a25db16 (6 commits, morning + afternoon) pushed to origin/main at Tier 3 wrap. Local main matches origin/main. Verification at push: typecheck clean, lint clean (1 pre-existing useForm.watch() warning in SignUpForm), design-system.spec.mts 29/29, edit-delete-workspace.spec.mts 12/12, workspace-upgrade.spec.mts 5/5, /user-flow-map 12/12 mermaid blocks rendering.

2026-04-26Sign-up funnel polish closeout (quorum-app, morning session)

Sign-up funnel polish closeout (quorum-app, morning session)

  • Visual review of the three sign-up flows (landing, credentials, payment) confirmed end-to-end. Flow 3 (/sign-up/pay) picked up two finishing CSS edits: comparison Continue button keeps primary-gradient styling at 30% opacity when disabled (replaces the previous "different greyed button" look — now reads as "same button, not actionable yet" with a clear 30%→100% beat on activation); paired Go back styled as a secondary outline using the same accent color the primary's gradient is built on, so the row reads as a paired set rather than primary + neutral.

Primary-button system unification (quorum-app)

  • Three parallel button systems drifted apart and were unified: .ap-btn-primary on /new-workspace / /w/* / /invite/*, .sp-submit and .sp-plan-compare__continue on /sign-up. Color drift (#7cd6e8 sRGB vs oklch(82% 0.15 200)#7ad7e9), glow box-shadow vs flat, and mismatched disabled opacity (0.4 / 0.6 / 0.1) all collapsed to one treatment.
  • Final unified primary: flat gradient (no outer glow), hover replaced with transform: scale(1.03), disabled uniformly at 30% opacity keeping the gradient + accent text intact. James's framing: "the primary buttons need to all have the EXACT same styling [...] consistency is KEY."
  • Accent tokens consolidated. --sp-accent* (sign-up scene) and --app-accent* (post-auth scene) token sets both alias to globals' --accent / --accent-hover / --accent-ring so the cyan/teal never drifts between scenes again. Single #7cd6e8 source of truth.

/new-workspace plan-change UX rebuilt (quorum-app)

  • Replaced the static "You chose · Change plan ↑" link (which dumped users back at /sign-up landing with no plan context) with an in-place slide-swap to a comparison grid — same pattern as /sign-up/pay's PayStep. New <ChangePlanPanel> client component owns confirm/comparison modes, swap track with cushioned 480ms ease-in-out, and Continue routing logic.
  • Billing-impact awareness for paid users. When someone who has already paid for their current plan picks a different plan in the comparison, a banner explains upgrades charge the prorated difference now and downgrades (including downgrade-to-Solo-Free) refund the difference in 3–5 business days. An acknowledgment checkbox below the grid gates Continue until checked.
  • Routing branches on Continue. Free→Free no-ops (current selected); Free→Paid routes to /sign-up/pay?plan=<new> (first-time charge needed); Paid→anything stays on /new-workspace?plan=<new> and surfaces a toast naming the proration direction. Stripe stays fully mocked per project_stripe_mocked_v1 — toast signals intent only; real proration lands in v2.
  • Container height tracked via JS ResizeObserver against an inner content wrapper so the swap doesn't reserve empty space below itself in the short confirm mode. Card surface (border + backdrop blur + bg) sits on the panel-content wrapper so both modes share the same visible card chrome — confirm row in a small card, comparison grid in the same card scaled up.

Global Toast provider added (quorum-app)

  • New <ToastProvider> + useToast() hook mounted in <AuthenticatedShell>. Top-anchored, slides down from above the viewport on enter, 4s auto-dismiss, manual × close, slide-up on exit, ease-in-out (cubic-bezier(0.4, 0, 0.2, 1)) for both slides at 320ms each, reduced-motion safe. Single-slot for simplicity (replaces and resets timer if a new toast fires while one is showing).
  • First consumer: the plan-change confirm flow. Built reusable so future post-auth surfaces follow the same confirmation-message pattern instead of one-off toasts. James's framing on consistency: "we should also have luca start documenting some of these transition styles so we can create a guide to go by so everything is consistent."

Em-dash sweep across user-facing copy (quorum-app)

  • 9 em-dashes in HTML rendered to users replaced with periods or colons. Files touched: PayStep.tsx (×2), CredentialsStep.tsx, NewsletterWidget.tsx (×2), UpgradeToTeamCTA.tsx, new-workspace/page.tsx (×2), ChangePlanPanel.tsx (×1).
  • En-dashes for ranges ("3–5 business days") left intact as typographically correct. James's directive was specifically em-dashes: "either not use em dashes or use them sparingly." Quentin will do a tone pass over new copy in a later session and may selectively re-introduce em-dashes where they earn their place.

Configurable top nav with "+" modal (planning repo, afternoon session)

  • Replaced the hard-coded primary nav (Planning / Prototype / Case study) with a data-driven nav system anchored to a single NAV_ITEMS constant in _gen_bmad_exports.py. 11 entries: 9 primary doc-type links (planning, case-study, prototype, briefs, portfolio, visual-specs, motion-specs, tech-stack, designs) + 2 right-side CTA pills (change-log, version-control). Each entry carries key, label, slot, default, coming (renders the existing "soon" chip), rel (href relative to exports/), and an optional nav_label override so long modal labels can be abbreviated in the slim nav (e.g., "Tech stack and process" → "Tech stack" in the nav button, full label in the modal).
  • Reordered the primary nav per user spec: Planning → Case study → Prototype (was Planning → Prototype → Case study).
  • Added a circular "+" button to the right of the Version control CTA. Clicking it opens an "Add nav items" modal as a viewport overlay: 10% black dim + backdrop-filter: blur(6px) (the dim alone was invisible against Quorum's near-black page), scale-in animation 25% → 100% on open via transform: scale() + opacity, three configurable sizes (small 300px, medium 500px default, large 800px) via data-size attribute, semi-transparent surface (rgba(8, 20, 32, 0.78) + 18px backdrop blur) matching the rest of the chrome.
  • Modal action row: Cancel (always-enabled secondary outline) and Apply (filled accent, disabled at 30% opacity until the user actually changes the selection — updateApplyState() compares current inputs vs saved state on every change). Esc, click-outside, Cancel all dismiss without saving. Apply persists the chosen set to localStorage under quorum-nav-items-v1.
  • Sliding-in confirmation card lives inside .am-modal__content as the first child, not as a full-bleed banner. Restyled mid-session to match the rounded callout pattern: success palette (var(--success-bg/border)), 10px radius, 16px (1rem) padding all around, animates open by transitioning max-height + padding + margin + border-width together so it visibly pushes title/list/actions down. Includes a "Close" CTA that dismisses the modal.
  • Top nav capped at 3 visible primary links; anything beyond falls to a new .page-subnav row rendered below the .page-header divider with its own faint bottom border so it reads as a second nav band rather than free-floating. Sub-nav is display: none until populated and uses slightly smaller link font (0.7rem). Distribution rule (in JS applyToDom()): walk PRIMARY_ORDER (injected from Python), first 3 visible items append to .page-nav, rest append to .page-subnav, hidden items park in .page-nav with data-nav-on="false" (CSS [data-nav-on="false"] { display: none !important; }).
  • Items 4 through 9 don't have authored docs yet, so the build now auto-generates placeholder "Coming soon" pages for each (exports/briefs/index.html, exports/portfolio/index.html, exports/visual-specs/index.html, exports/motion-specs/index.html, exports/tech-stack/index.html, exports/designs/index.html) via a new render_nav_placeholder(slug) helper called from main(). Each page lists planned contents specific to its slug (e.g., briefs lists "Project briefs / Discovery briefs / Stakeholder briefs / Scope-cut summaries"). Same chrome as every other page so the modal still works there.
  • Two CSS specificity gotchas hit and fixed during the build, both worth noting because they're easy to repeat: .am-modal-overlay had to be added to the exclusion list of BOTH body > *:not(...) rules (the 64rem max-width / centered-column rule AND the position: relative; z-index: 1 rule). Without those exclusions, position: fixed; inset: 0 got overridden into position: relative and the modal rendered inline at the bottom of the page flow instead of as a viewport overlay. Lost two iterations to this before tracing it.
  • data-nav-on is now baked inline in the HTML at render time (not just set by JS on load). Without this, every unchecked nav button was flashing visible during the gap between HTML parse and JS execution — those were the "boxes at the top" James spotted on the first build.
  • white-space: nowrap on .page-nav__link and .page-header__cta so labels never wrap mid-word (earlier "TECH / STACK / AND / PROCESS" rendering when crowded). flex-shrink: 0 on .page-header__actions so the right group never collapses.
  • Tried a dot separator between adjacent visible nav links (absolutely positioned at the geometric midpoint of the gap, with rules to suppress dots on either side of an .is-active link). Removed at user's call — hover state on adjacent links made the dots read awkwardly.
  • ICON_SVGS gained plus and check entries.
  • Master-doc: NOT touched in this session. James will manually apply the changes to master-doc/src/_gen_bmad_exports.py and master-doc/src/_style.py in a separate session so nothing gets overwritten — a comprehensive prompt covering all parts (NAV_ITEMS structure, modal HTML/JS helpers, wrap_page rewrite, full CSS block, the two body > * specificity gotchas, the inline-data-nav-on flash fix, default-state validation checklist) was drafted in conversation and copied off for manual paste. Existing projects (Quorum, Autora, ValorAid) are unaffected — only future master-doc scaffolds will inherit this nav system.

Quentin voice pass on plan-change copy (quorum-app, late afternoon)

  • Cross-surface copy review by Quentin (sanctum loaded from quorum/_bmad/memory/agent-quentin/) across all three plan-change comparison panels: /new-workspace, /sign-up/pay, /sign-up?plan=.
  • Hard-rule violation caught and fixed: "Continue" is on the voice guide's button-label blacklist. Replaced with dynamic verb-led labels: Switch to {targetPlan.name} for plan switches; Pay for {targetPlan.name} on Free→Paid. Names target plan = doubles as confirmation read-back.
  • Accessibility content fix: "Your current pick is highlighted" replaced everywhere — vision-only cue. New copy on /new-workspace: {currentPlan.name} stays active until you confirm a different plan. Equivalent rewrites on the sign-up surfaces.
  • Banner title shifted from "Heads up: your card was charged for X" to "Changing plans means a billing adjustment" (lead with implication, not past fact). Body cut ~40% (drop "prorated" jargon + filler). Acknowledgment label split conditional on direction (charge vs refund) for concrete agreement. Toast simplified from 3 unreachable variants to 2.
  • "Go back" → "Keep current plan" everywhere.
  • Quentin session log written at quorum/_bmad/memory/agent-quentin/sessions/2026-04-26.md.

Workspace surfaces v1 (quorum-app, late afternoon / evening)

  • Workspace switcher in AuthenticatedHeader. New <WorkspaceSwitcher> client component renders a dropdown trigger between the brand and right-side header group. Visible only when the user is inside /w/<id> AND has 2+ memberships. Click-outside / Escape close. Footer link See all workspaces/workspaces.
  • AuthenticatedShell made async, fetches lightweight memberships once, passes to header. Four call sites updated to pass userId={user.id}.
  • /workspaces picker upgraded to cards. Each card has: workspace icon (placeholder glass tile with first letter, hover reveals pencil overlay → file picker → "Custom icons land in v2" toast), name + soft status badge (computed from existing fields: Just created / Awaiting invites / Active / Quiet), role + plan + member count, last-activity timestamp, and hover-revealed edit + delete action buttons.
  • Header text + Learn more disclosure explaining what a workspace is and what's inside (Plan / Design / Build / Members / Portfolio). Native <details> for v1; future story replaces with a dedicated walkthrough page.
  • Edit + Delete dialogs (visual prototype, all actions toast). New <Modal> generic shell. Delete dialog follows Quentin's destructive pattern (names what's deleted + type-name-to-confirm). Edit dialog: name + privacy (mapped to Workspace.type) + plan dropdown + members preview with link to /w/<id>/members. All commits fire toasts; real PATCH/DELETE filed as backlog story.

Backlog stories filed for future implementation

Three stories drafted today and shared with James in chat for paste-into-planning:

  1. Workspace status surface and activity log (P2). Real Workspace.status enum + new WorkspaceActivity table replacing today's heuristic-only badges. ~2-3 hrs.
  2. Workspace edit + delete API (P1). PATCH/DELETE endpoints, owner-only permission middleware, plan-change proration wire-up, real fetch in dialogs replacing today's toast mocks. ~3-4 hrs.
  3. Workspace layout walkthrough page (P3). Dedicated /workspaces/learn-more (or similar) replacing today's inline <details> once the workspace has concrete sections to depict. Sequenced AFTER Story 2.1 team room.

Quorum-app commits today (5, all on local main, none pushed)

Hash Title
cc044ab Sign-up funnel polish closeout — primary-button system unified + em-dash sweep
9db9976 /new-workspace — plan-change swap + billing-impact UI + global Toast
b9780de Add CHANGELOG.md mirroring the sibling quorum project-wide change log
(afternoon commit 1) Quentin voice pass on plan-change copy across the three comparison panels
(afternoon commit 2) /workspaces — switcher + picker cards + edit/delete prototype + Modal scaffolding

GitHub: https://github.com/jcfrank8910/quorum-app/commits/main

Status pill + global select styling (planning repo, late afternoon)

  • Promoted status from a flat subtitle line ("Status: living document") to a proper rounded pill rendered directly under the H1, using the cyan accent palette (var(--accent) text, var(--accent-soft) bg, var(--accent-ring) border). Below the pill, a small mono-font line shows Last updated: <abs date+time> (<relative>) pulled from the source file's actual mtime (not the frontmatter lastUpdated: field, which only carried date and went stale). Injected via re.sub after the first </h1> in the rendered markdown body, so any doc with status: in its frontmatter inherits the treatment automatically (change-log has it now; version-control and future status-bearing docs will pick it up the next time they're regenerated).
  • Same pill block added to the planning index hero — sits between the subtitle paragraph and the Sprint chip. Timestamp on the index = latest mtime across all DOC_REGISTRY source files, i.e., "when did anything in the planning tree last actually change." Reflects project liveness, not regeneration time.
  • Global select styling. Promoted the existing .epics-nav__select rules (dark-glass surface, cyan chevron via embedded SVG data URI, hover/focus states with accent ring, custom optgroup + option color tokens) to apply to every <select> element in the export tree. .epics-nav__select was trimmed down to just width: 100% (its grid-cell layout responsibility). Future selects added anywhere now match the aesthetic without needing a class.
  • The select trigger styles correctly; the popup menu does not. This is a hard browser constraint, not a CSS bug — native <select> popups are rendered by the OS and CSS can't reach inside them. Chrome respects partial option { background, color } overrides; Safari and Firefox ignore most popup styling and fall back to OS chrome. Decision: build a custom JS dropdown widget (option A from the pitch) that replaces every <select> on page load with a fully styleable button + listbox panel — keyboard nav (arrows / Home / End / Enter / Esc / type-to-jump), click-outside-to-close, ARIA combobox/listbox/option roles, optgroup support, scroll-into-view for active option, and MutationObserver so dynamically-changed select content (the epics-nav story-filter logic on the index) stays in sync. Designed but deferred — implementation will land in the next session.

Open threads carried into the next session

  • Custom JS dropdown widget — design discussed in this session, build deferred. Targets every <select> globally (epics-nav epic + story selectors are the immediate beneficiaries on the index). Original <select> stays in the DOM hidden so form values + change events still work; widget exposes the proper ARIA roles for accessibility. Roughly 80–150 lines of focused JS plus a CSS block for .q-select / .q-select__trigger / .q-select__panel / .q-select__option etc.
  • Luca motion-system documentation guide capturing the existing transition vocabulary: slide-swap (480ms ease-in-out), banner shrink-fade (320ms), toast slide-in/out (320ms), primary-button hover scale (160ms), modal entrance (240ms), focus-visible rings, paired-row easing — for design-system consistency reference. Proposed home: quorum-app/docs/motion-system.md.
  • Original sign-up visual-review checklist remaining items (carried from SESSION-RESUME-2026-04-25.md): AuthenticatedHeader top-right + New workspace link verification, members-page upgrade CTAs (solo-free upgrade reveal + solo-pro upgrade-to-Team-Starter link), role-dropdown chevron breathing room, teal-line artifact regression check.
  • Story 1.3.2 outstanding tasks unchanged: Task 5 (OAuth) blocked on James, Task 13 (tests) partial, Task 14 (verify all ACs) housekeeping.
  • Privacy field decision deferred. Edit dialog v1 maps "Privacy" to Workspace.type. If a separate privacy concept is wanted, schema migration goes in Story 2.x (edit + delete API).
  • Three new backlog stories drafted in chat (workspace status / edit + delete API / layout walkthrough page). James to paste into planning when next opening this repo.
2026-04-25Cross-repo change-log discipline + promote-queue design + portfolio-push roadmap (afternoon session)

Cross-repo change-log discipline + promote-queue design + portfolio-push roadmap (afternoon session)

  • Session pickup point refreshed from quorum-app's SESSION-RESUME-2026-04-25.md. Stale items removed (Story 1.3 close-out long-since shipped; Story 1.3.2 marathon nearly complete). Actual current state surfaced: top priority is the incomplete visual review of the three sign-up flows (paused mid-eyeball), pending OAuth task blocked on James, hosting deploy still deferred, Autora + ValorAid index propagation still pending.
  • Cross-repo change-log discipline locked. Change-log entries must cover both Quorum planning AND quorum-app activity, not planning-only. Today's entry retroactively gained a "Quorum-app Story 1.3.2 marathon" subsection covering 13 commits across 2026-04-24 → 2026-04-25. Going forward the rule is: every daily entry pulls from the matching quorum-app/SESSION-RESUME-YYYY-MM-DD.md for cross-repo coverage. (Saved as feedback memory.)
  • Hosting plan replatformed onto Framer. Original Cloudflare-Pages-via-Squarespace-DNS plan obsoleted: James cannot switch off Framer (main jayfrank.info is Framer-hosted; Framer MCP is now installed and connected to Claude Code). New target: Framer-native or Framer-adjacent hosting. Three open questions before design (goal / subdomain vs. subpath / static-import vs. native-rebuild). Investigation deferred to next session.
  • Promote-queue mechanism designed (build deferred). Problem: master-doc is one-way today; if a feature is built in Quorum/Autora/ValorAid that should belong in master-doc, no machinery exists. Recommended approach: tag-as-you-go queue, not auto-drift-detection. End-to-end flow walked through (mid-work tag → <project>/_bmad-output/promote-to-master-queue.md entry → from master-doc session run review-promote.sh → pick + diff + decide per file → apply to master-doc/src/ → manual commit in master-doc → queue entries auto-marked promoted/declined with audit trail). Always-print reminder: master-doc improvements benefit ONLY newly-scaffolded projects, never backflow into existing ones. Four open design choices to confirm before building (auto-detect downstream vs. explicit list; drift-scan opt-in or skip for v1; queue file visibility; trigger phrase via ~/CLAUDE.md or skill). Build estimate ~20-30 min for v1.
  • Portfolio centerpiece push roadmap locked. Five-workstream plan captured for next session: (1) build the promote queue, (2) Framer MCP integration, (3) per-page edit + style pass elevating every page to portfolio-grade, (4) new top-nav links — Pitch decks (firm) + Briefs (soft) — reshaping IA from 3 slots to 5, (5) subtle animations Luca-led. James's framing: "this is going to be a major part connected to my portfolio site and this is what needs to blow them away." Sequencing question flagged: define Framer hosting first (so we know what surface we're polishing) vs. polish-first then re-platform. My instinct: hosting-first to avoid wasted polish.
  • Session hours logged via the time-log feature. Afternoon session: 1h 15m appended to time-log.yaml. New project total: 27h 10m (18h 32m pre-existing + 7h 23m morning session committed in c08fc51 + 1h 15m this afternoon).

Architectural pivot — master-doc as template / seed model

  • Master-doc (~/Desktop/projects-inflight/master-doc/) pivoted from a subscribe model to a one-shot template / seed model. publish.sh --apply retired; replaced with publish.sh --init <project-path> (one-time scaffold). downstream.json deprecated.
  • Master-doc gets its own GitHub remote: https://github.com/jcfrank8910/master-doc.
  • Quorum, Autora, and ValorAid each received one final --init to bring them to the current shared-code state, then sealed off as independent forks. Future master-doc improvements benefit only newly-scaffolded projects.

Quorum becomes a downstream consumer of master-doc

  • Quorum's _gen_bmad_exports.py and _gen_prd_exports.py refactored to import per-project values from a new project_config.py (DOC_REGISTRY, FEATURED, EPIC_TITLES, SIBLING_APP_ROOT, branding strings).
  • Refactor is behavior-preserving — exports render byte-identically apart from cosmetic live-data updates (Hours stat, relative date strings).
  • Caught and fixed a regression: HERO_EYEBROW_BYLINE came across as a placeholder; restored to "Created by James Frank · 2026."
  • Committed 7bc677b and pushed to origin/main.

Setup zip caught up to the pivot

  • ~/Desktop/projects-inflight/setup/ synced its payload to today's live config: bundled master-doc inside the zip, refreshed scripts and starters, extended PII scrub, updated install steps for master-doc placement.
  • New zip complete-setup-v20260425-0200.zip (938K) — ships the full template model.

ValorAid sync committed + pushed

  • Adopted master-doc as scaffold. Status: f6480a7 pushed to https://github.com/jcfrank8910/ValorAid.
  • Note: FEATURED and EPIC_TITLES intentionally empty (Index featured-card grid renders empty until populated; expected pre-content).

Time-log feature

  • New time-log.yaml in planning-artifacts root for billable hour tracking. Replaces the wall-clock "Build time" stat with a manually-tracked "Hours" stat sourced from time-log.yaml entries.
  • Schema accepts hours (decimal) and/or minutes (int) per entry. Display format: Xh Ym.
  • Quorum pre-loaded with 18h 32m for pre-existing work.
  • Wrap flow upgraded to log session hours on Tier 1/2/3 wraps (pending implementation in next wrap).

Change-log feature

  • All "## Version log" headings in living docs renamed to "## Change log" (8 docs).
  • This change-log.md created as the project-wide change log.

Quorum-app Story 1.3.2 marathon (13 commits across 2026-04-24 → 2026-04-25, all pushed to origin/main)

  • Story 1.3 close-out finally landed (e008e9a): documentation correction citing src/proxy.ts as the actual mechanism for AC #6 (Next 16 renamed middleware.tsproxy.ts). Status flipped review → done in both story file and sprint-status.yaml.
  • Story 1.3.2 went from draft to nearly-complete:
  • Task 2 — workspace Stripe mock columns + populate on create (1901a80).
  • Task 4 — real signUpAction (daddb88).
  • Task 7 — newsletter widget close-out (3cbd97c).
  • Task 9 — Mock Pay button + paid happy-path e2e (f004b41).
  • Task 10 — invite round-trip helper + signup deep-link fast path (eb410b2).
  • Task 12 — members UI branches on workspace.type + auto-promote (9102f1d).
  • Task 13 (partial) — sign-up funnel e2e coverage (3590f76).
  • Stripe pivot to fully-mocked for v1 (f6be801): no @stripe/* imports, no STRIPE_* env vars; placeholder cus/sub IDs.
  • Sign-up funnel polish (6f75606): slide-swap animation between credentials and plan-comparison steps, breadcrumb navigation, select-then-Continue flow, button-activation states, a11y/UX pass.
  • Mid-session: two code regressions surfaced and fixed (0935cd5); copy refinements + filed two known-issue follow-ups (9967326); sprint-status most-recent-action aligned to Story 1.3 (d504526).
  • Tasks still open: Task 5 OAuth (blocked on James — needs Google + Apple developer projects), Task 13 (full coverage), Task 14 (final AC verification).
  • Filed follow-ups in story file: /sign-up?plan=* axe color-contrast + link-style violations (needs Quentin/Kinsley collab); displayName regex blocks apostrophes (loosen to /^[\p{L}\s\-']+$/u if real users hit it).
  • Verification at last gate: typecheck pass, lint 0 errors (1 pre-existing react-hook-form warning), vitest 51/51, e2e 42/42.
  • Visual review of three sign-up flows INCOMPLETE — paused mid-eyeball. Checklist preserved in quorum-app/SESSION-RESUME-2026-04-25.md (Flow 1 /sign-up landing, Flow 2 credentials step, Flow 3 payment step + adjacent surfaces).
2026-04-24Three-pillar checkpoint gates landed end-to-end

Three-pillar checkpoint gates landed end-to-end

  • PRD: new ## Three-Pillar Checkpoint Gates section with per-pillar pass criteria, exit rules, override-with-audit semantics. FRs added: FR25b (terminal verdicts), FR25c (gate-cleared required for allocation), FR25d (override audit + downstream markers). Traceability map updated.
  • Epic 4: Stories 4.5 / 4.6 updated for gate semantics; new Story 4.7 (Pillar gate verdicts and exit criteria).
  • Moments That Matter v0.3 → v0.4: three new moments — #55 First pillar gate verdict, #56 Needs-revisit blocks advancement, #57 Why-this-verdict drill-down.
  • Version control doc v0.1 → v0.2: pillar gate verdicts added to tracked decision events.
  • PRD frontmatter: lastSaved bumped, recentChanges array added.

Planning-export structural upgrades

  • Per-epic subpages (epic-1.html through epic-11.html) auto-generated from epics.md.
  • Status badges on every Epic / Story heading, sourced from sprint-status.yaml.
  • Sticky jump-to nav: Epic + Story dropdowns + Go button on epics page and index.
  • Story bodies collapsed into <details> accordions with left-aligned status slot.
  • Requirements Inventory moved to bottom of epics page, collapsed into accordions.
  • "Next steps" panel injected after Overview on epics page (live sprint-status read).
  • Sprint chip on index hero showing active sprint + done-counter, links to active epic's subpage.
  • Primary nav: Planning / Prototype / Case study with active-state per page. Prototype placeholder page.
  • Project Timeline page reconstructed from git log, day-grouped, foundation marker for pre-repo work.
  • Per-doc "Commit history" accordion at bottom of every rendered doc, with uncommitted-working-tree indicator.
  • Index hero eyebrow: "Planning Artifacts | Created by James Frank | 2026."
  • Wired-globe SVG backdrop generated from Fibonacci-sphere math.
  • Stats cards shrunk so "HTML · DOCX · PDF" stays on one line.

Coming-soon page

  • Standalone self-contained HTML at coming-soon/index.html with Quorum branding. Ready for Cloudflare Pages deploy when hosting config lands.

Story 1.3 close-out (quorum-app, file-writes)

  • Verified src/proxy.ts (Next 16 rename of middleware.ts) was the actual mechanism satisfying AC #6 — phase A always had it. Close-out is documentation-only.
  • Filled Dev Agent Record retroactively. Status reviewdone in story file and sprint-status.yaml.
  • Cipher-style security review self-run: all three stated risks clear.
2026-04-23Voice &amp; content-strategy work

Voice & content-strategy work

  • Voice & Tone Guide v1.0 → v1.1: added "Scope: customer-facing vs internal planning docs" section codifying Option X (em-dash rule is customer-facing-only; rest of blacklist applies everywhere).
  • Voice-drift pass complete across corpus (67 edits): hard-no words in PRD / methodology research; portfolio doc full pass (46 em-dashes → 0); metaphor edits across PRD / epics / walkthrough / methodology / sprint-change-proposal / walkthrough-alignment-diffs.
  • Per-file drift map at voice-drift-audit-2026-04-23.md.

Four new content-strategy artifacts

  • release-notes-format.md v1.0 — Model B workflow (Paige drafts, Quentin polishes), template, 3 worked examples.
  • accessibility-statement.md v0.1 (do-not-publish until v1 + first audit) — pre-MVP commitment framing.
  • error-pages.md v1.0 — copy for 404 / 500 / maintenance / offline / 403 / 401 / 429 / unsupported-browser.
  • voice-drift-audit-2026-04-23.md — full per-file drift log.

Story 1.3.2 Voice Pass (quorum-app, uncommitted)

  • 5 literal user-facing em-dashes removed; 5 copy gaps drafted (OAuth cancelled, payment failure variants, newsletter invalid, password UI voice split, Team Starter blurb alignment).

Moments That Matter v0.3

  • Four new moments added: #51 release notes read, #52 page not found (404), #53 server error mid-work, #54 accessibility statement discovered.
2026-04-22Quentin agent activated

Quentin agent activated

  • Skill built at ~/.claude/skills/agent-quentin/, vendored into Quorum + Autora + ValorAid + quorum-app.
  • Sanctum seeded at _bmad/memory/agent-quentin/ with voice mandate + em-dash scope lock.
  • Bootstrap fix: ~/CLAUDE.md step 7b auto-vendors all ~/.claude/skills/agent-* into new projects.

Voice & Tone Guide v1.0 + Moments That Matter v0.1 / v0.2 + Case Study v0.1 + Version Control Strategy v0.1

  • Five-pillar voice guide; full AI-tell blacklist; house style; common-moments table.
  • 50-moment lifecycle inventory across 11 groups.
  • Quorum's own meta case study (day 8, pre-MVP, honest).
  • GitHub-primary / Quorum-hosted-fallback version-control strategy.

Product roster (in quorum-app)

  • Canonical 21-agent roster locked into quorum-app/TEAM.md and quorum-app/src/features/team/roster.ts. Paul replacing Dr. Quinn. Consolidated with Jaymes's TeamPopover work.

Export pipeline rebuild — Quorum-branded

  • STYLE extracted to _style.py (single source of truth).
  • Rebranded to Quorum's dark-space OKLCH palette: #02060c bg, #eaf6fa fg, #7cd6e8 accent. Space Grotesk + Source Code Pro. Exact body gradient from globals.css.
  • Index page redesigned: hero / featured card grid / card rows / live build-time stat / wired-globe backdrop.
  • Page header on every export: logo / back-nav / Version-control CTA.

2026-04-21 and earlier

For days prior to 2026-04-22, see the Project Timeline page (auto-generated from git log) for commit-level granularity. High-level beats from earlier days:

  • 2026-04-12 — Initial vision dump, PRD skeleton, product brief draft (pre-git, day 1).
  • 2026-04-13 — Product-brief refinement, architecture skeleton, Kitchen Sink Discovery framework (pre-git, day 2).
  • 2026-04-14 — Initial git commit; export pipeline; pre-MVP planning consolidated.
  • 2026-04-15 to 2026-04-19 — PRD evolution, story creation, Story 1.2 / 1.3 implementation in quorum-app, Figma handoffs, design briefs.
  • 2026-04-20 — Story 1.3.2 rewritten to match locked planning decisions (Quorum Plus rename, 4 plans, OAuth credentials, Stripe test-mode payment).

How this file gets maintained

  • Daily entries are appended at the top (reverse-chronological).
  • What goes here: anything that materially changes the project's state — planning artifacts edited, scripts changed, sessions completed, commits shipped, decisions made, framework additions, agents activated.
  • What stays in per-doc change logs (## Change log in voice-tone-guide, moments, etc.): changes specific to that doc's content. The project change log links here for context.
  • Cadence: at minimum, a brief entry per session-with-changes. The wrap flow (Tier 1/2/3) appends a session summary line to the current day's entry; you can flesh out the bullets later if needed.