A full session: planning a messenger service
A complete walk-through of /sdcd:* on a greenfield full-stack project — from “I want to build a messenger for small teams” to “GO for implementation.” Abbreviated for readability; the real outputs are longer.
Step 0 — User intent
“Let me plan a messenger service for small teams. Python + FastAPI backend, React frontend, self-hosted.”
Step 1 — /sdcd:new-project
Claude elicits the missing details:
Before drafting the Ur-Plan, tell me in 3–5 sentences: what does this project do for whom, and what is the one non-trivial constraint I should know?
User answers:
“Small teams (5–50 people) want a threaded messenger that lives on their own server. Must support code-snippets and file attachments. Non-trivial constraint: deploys to a single VPS, no k8s, no managed services — low-ops is a hard requirement.”
Tier declared: Larger (multi-month project, full-stack product).
Archetype used: full-stack (Python backend + React frontend detected).
Files scaffolded:
messenger/
├── CLAUDE.md
└── design/
├── UR_PLAN.md
├── CURRENT_STATE.md
└── ARCHITECTURE.md
Ur-Plan drafted with goal / non-goals / success-criteria / stack / milestones / open-questions.
Challenger trio dispatched against the draft. Synthesised pushback, top three:
- block (challenger-security): “Single-VPS deploy with no managed services — how are credentials rotated? If app secrets live in env vars on one box, there is no rotation story at all. Spec this before touching code.”
- high (challenger-performance): “Success criterion says <100 ms message delivery but stack is FastAPI on one VPS with Postgres on the same box. Long-connection patterns (websockets) under 50 concurrent users will be fine; at 50+ you’ll eat the uvicorn worker pool.”
- high (challenger-maintainability): “Non-goals are empty — for a messenger the non-goals list is the difference between a working MVP and feature creep. Stating them now costs nothing and saves three months.”
User addresses 1 and 3 in the Ur-Plan, defers 2 to an Open question (“revisit if we hit worker-pool ceiling; first target is 20-user teams”).
Step 2 — /sdcd:data-plan
Claude reads the Ur-Plan, drafts DATA_PLAN.md with 5 entities:
User— SQL, email + display name + hashed password.Team— SQL, owned by a creator user.Channel— SQL, belongs to team.Thread— SQL, belongs to channel.Message— SQL, belongs to thread, has author + body + attachments list.
Plus relationships, index coverage, retention, migration stance.
Challenger trio on the data plan surfaces:
- high (challenger-performance): “Messages table will be the hottest. Your only stated query pattern is ‘thread messages paginated by time’. Index is
(thread_id, created_at)— state this explicitly.” - medium (challenger-security): “User.hashed_password is noted but which algorithm? Argon2 / bcrypt / scrypt — pick now.”
- medium (challenger-maintainability): “Attachments listed as ‘jsonb array on Message’. That’s a future regret — file IDs should be their own table once you have any non-trivial per-file metadata.”
All three addressed in-place.
Step 3 — /sdcd:backend-plan
Claude reads Ur-Plan + Data-Plan, drafts BACKEND_PLAN.md:
- API contract: auth endpoints, team/channel CRUD, thread fetch, message send, attachment upload.
- Domain model: references
DATA_PLAN.md. - Storage: references
DATA_PLAN.md. - Auth: sessions via signed cookie, rotated every 24h.
- Error handling: single
APIErrorwith problem+json response shape. - Observability: structured logs to stdout, metrics via Prometheus endpoint.
Challenger trio surfaces auth-flow edge cases and logs-PII concerns. Both addressed.
Step 4 — /sdcd:design-system-plan
Claude reads the Ur-Plan, drafts DESIGN_SYSTEM.md with target feel: “minimal, serious, spacious, cool, sharp” (messenger for work teams, not a social app).
Sections filled: palette roles, typography (humanist sans-serif, 1.25 ratio), spacing (4px base), shapes (sm radius for buttons, none for inputs), motion (150/250/400ms durations, reduced-motion respected), iconography (Lucide, outlined), accessibility baseline (WCAG AA, visible focus ring).
Dispatched challengers (design-system uses UX + a11y + maintainability, not the default trio):
- high (challenger-ux): “Threaded conversations need a visual hierarchy that distinguishes top-level messages from replies at a glance. Your component visual language section doesn’t cover thread rendering at all.”
- medium (challenger-accessibility): “Focus ring is spec’d as
color.accent.primary2px offset — that’s fine for light mode but does it hit 3:1 againstcolor.bg.surfacein dark mode? Verify during implementation; if not, introduce a dedicatedcolor.border.focustoken.” - medium (challenger-maintainability): “Token namespace is a five-level tree (
color.bg.surface, etc.). That’s industry-standard but flag anyone tempted to addcolor.header.top— it would break the convention.”
Addressed.
Step 5 — /sdcd:frontend-plan
Claude reads Ur-Plan + Backend-Plan + Design-System, drafts FRONTEND_PLAN.md:
- Routes:
/login,/teams/:id,/teams/:id/channels/:cid,/teams/:id/channels/:cid/threads/:tid,/settings. - Component tree: AppShell → Sidebar / MainPane → ThreadList / MessageComposer, with leaf components noted by category.
- State model: server state (React Query, cache keys per endpoint), URL state (channel + thread IDs), local for composer draft.
- Data fetching: each route names the fetches.
- Forms: login, message composer, team/channel create.
- Error & empty states: per data-fetching component.
- Accessibility: keyboard-first navigation, skip-link to composer, ARIA live region for new messages.
- Visual language anchors: references Design-System tokens.
Dispatched challengers (frontend uses all 4: security + performance + ux + a11y):
- high (challenger-security): “Messages render user content — XSS surface. Your plan doesn’t say whether markdown is rendered server-side or client-side. Decide; client-side means a sanitiser on every render, server-side means HTML is in the payload.”
- high (challenger-performance): “Message list on a busy channel is unbounded. Your plan doesn’t say virtualised list. At 500 messages the DOM will suffer.”
- medium (challenger-ux): “Composer submit-behaviour is ‘Enter to send, Shift+Enter for newline’. Confirm this is stated in the UI (keyboard hint) — discoverability matters.”
- medium (challenger-accessibility): “Message live region is
polite— correct for chat. But new-message-while-scrolled-up state needs a visible ‘new messages below’ affordance, not just an announcement.”
All addressed, except #1 — user prefers server-side markdown and moves “renderer implementation” to Open questions for the backend-plan.
Step 6 — /sdcd:audit
Claude reads all five plans. Trace-link checks pass. Contradictions pass. Open-questions rolled up:
- Blockers: 0.
- Defer during implementation: worker-pool ceiling, markdown renderer choice, attachments schema evolution.
- External input needed: self-hosted deployment story (from Ur-Plan non-goals → needs an explicit deploy guide before v1).
Cross-cutting challenger pass (all 5 lenses). Top concern:
- note (challenger-maintainability): “Auth is session-cookie rotated 24h. Token lifetime + rotation is consistent across Backend + Frontend. Logout revokes server-side. No drift.”
Verdict: GO.
Claude writes design/AUDIT.md and reports:
Ready to start implementation. Run
/sdcd:session-startwhen you begin the first coding session.
Implementation phase
/sdcd:session-start loads state. User codes feature-by-feature under §1 rules. Every source file gets a .brain per §1.6. /sdcd:session-end at the close of each work block.
After milestone M1 (“auth + first endpoint”):
/sdcd:milestone-audit
Claude reads M1’s plan scope + actual code + tests + state. Dispatches plan-drift-detector and sdcd-reviewer. Writes an entry to design/AUDIT_LOG.md:
- Done: login + session + health check endpoint + auth middleware.
- Missing: plan called for account-lock-after-N-failures; code doesn’t implement it. Verdict INCOMPLETE — unblock on that.
User adds the lock logic, re-runs milestone-audit — now COMPLETE. CURRENT_STATE.md advances to M2.
What you don’t see in this walk-through
- The actual plan documents are 200–400 lines each. Challenger outputs are 7 findings each, condensed above.
- Every skill dispatch pauses and waits for user input — the flow above compressed that.
- Challenger pushbacks get written into the plan files, not just the chat. That means re-reading a plan later shows what was pushed back on and how it was resolved.
- Every source file Claude touches gets a
.braincompanion. By the time M3 ships, there are dozens of brain files — and any fresh Claude session onboards via reading them, not the source.
The whole point: Claude in session N+1 can pick up where session N left off without re-inferring the project from scratch.