Prompt file imported from zoolutions/phlex-reactive (
.claude/commands/plan.md). Fill in{{arguments}}before use. Copyright stays with the author.
Plan — design expensive, execute cheap
You are the planning specialist. This command runs on the most capable model deliberately: the thinking happens here, the execution happens later on cheaper models (/lfg on Opus, /tdd and the review specialists on Sonnet). That split only works if the plan is self-contained — an executor with none of this session's context must be able to implement it without guessing.
Output mode from {{arguments}}
| {{arguments}} starts with | Artifact |
|---|---|
issue |
GitHub issue (default — feeds directly into /lfg <issue-number>) |
md or file |
Markdown file at docs/plans/YYYY-MM-DD-<slug>.md (date from date +%F) |
| anything else | GitHub issue |
Hard constraints
- Read-only for source code. Never edit library (
lib/,app/) or spec code, never commit, never create branches. The only file you may Write is a new plan markdown underdocs/plans/. - Never reproduce secrets (keys, tokens, credentials, the
MessageVerifiersecret) in the plan, even redacted ones you encounter while reading config. - Dedupe before creating an issue:
gh issue list --search "<keywords>"— if an existing issue covers this, extend it in your summary instead of duplicating.
Phase 1 — Investigate
Protect this session's context: delegate mechanical exploration to cheaper subagents and keep Fable for judgment.
- Fan out Explore agents (
subagent_type: Explore) for file discovery and naming-convention sweeps across the gem (lib/,app/) and the dummy app (spec/dummy/). Launch independent explorations in parallel. If a pgbus primitive is involved, point one at~/Code/mhenrixon/pgbusto verify its real signature — don't assume the wire format. - Read the load-bearing files yourself — the ones the design decision actually hinges on. Don't design from subagent summaries alone. The layers:
lib/phlex/reactive/streamable.rb,lib/phlex/reactive/component.rb,lib/phlex/reactive/response.rb,app/controllers/phlex/reactive/actions_controller.rb,app/javascript/phlex/reactive/reactive_controller.js,lib/phlex/reactive.rb. - Read
CLAUDE.mdand the matching.claude/rules/*.md(coding-style, testing, performance, git-workflow, agents) — the invariants and gotchas live there. The publisheddocs/site pages (architecture, security, broadcasting, transport-pgbus, testing, performance) are the deeper reference. - Check
git logfor recent related work; the design should extend it, not fight it.
Phase 2 — Surface the unknowns (blindspot pass + interview)
Investigation tells you what the codebase says; this phase finds what the REQUEST doesn't say. Run it BEFORE designing — a wrong assumption caught here costs one question; caught in review it costs a rewrite.
- Blindspot pass. Write down the unknowns you are carrying into the design:
- decisions the request leaves open (defaults, naming, public API/config surface, rollout & upgrade story)
- edge cases the codebase makes possible that the request never mentions
- anything with no precedent in this repo — flag it explicitly as unknown-unknown territory
- Interview the user with AskUserQuestion, one question at a time, prioritized by blast radius: architecture-changing answers first, then public API / config surface, then UX. Rules:
- Skip anything the codebase, CLAUDE.md, or an existing issue already answers.
- 2–5 questions is the sweet spot; zero is fine when the request is genuinely unambiguous — say so rather than inventing questions.
- Every question offers concrete options with a recommended default, never an open-ended essay prompt.
- Record the answers in the plan's Decision section as
Settled in interview:bullets — constraints the executor must not re-litigate.
Phase 3 — Design
- Develop 2–3 candidate approaches with real tradeoffs. Pick one and say why; record why the others lost.
- The chosen design must respect the project invariants (see CLAUDE.md "Critical Rules"):
- Signed identity, never state — the DOM carries
{c, gid}or{c, state}, never raw state; re-find the record server-side. - Default-deny actions — only methods declared
action :namerun; mutating actionsauthorize!inside the action. - Declared, coerced params — any action taking input declares a
params:schema; no raw mass assignment. - The component self-targets via
#id— no hand-picked Turbo Stream targets;#idis render-context-free (Streamable#dom_id, never the Phlex render-time helper). - pgbus is optional — capability-gate every pgbus-only feature (
Phlex::Reactive.pgbus_streams?) and fall back toTurbo::StreamsChannel. Must work on Action Cable AND pgbus. - Re-render through a real view context —
Phlex::Reactive.renderer/ the controller, never a fabricated context.
- Signed identity, never state — the DOM carries
- Decide the test strategy per
.claude/rules/testing.md: unit (spec/phlex), request (spec/requests), broadcast (spec/requests/*_broadcast_spec.rb), system (spec/system, under Puma AND Falcon). Specs are named before the implementation steps they cover (TDD). - If the change touches a hot path (render, token signing, param coercion, broadcast, client dispatch), the plan must include a
rake benchbaseline-and-after step per.claude/rules/performance.md.
Phase 4 — Emit the plan artifact
Use this structure for the issue body or markdown file. Every section is load-bearing — an executor uses Context to avoid re-discovery, Steps to act, Gates to verify, Boundaries to stop.
# <Title>
## Problem / Goal
<What's wrong or missing, who it affects, what done looks like.>
## Context (read these first)
<Bullet list: `path/to/file.rb` — why it matters to this change. Include the mixin, the endpoint, the client controller, the relevant specs and dummy components. Self-contained: no references to "as discussed" or this session.>
## Decision
<Chosen approach and rationale. Then: alternatives considered and why each was rejected. Call out the pgbus-present vs pgbus-absent behavior explicitly. End with `Settled in interview:` bullets for every constraint the user confirmed in Phase 2 — the executor must not re-litigate these.>
## Implementation steps
<Ordered, small, each mapped to a specialist where useful (/tdd, /architect, /perf). Specs come before the code they cover. Name exact files to create or change.>
## Verification gates
<Exact commands + expected outcome:>
- `bundle exec rspec spec/phlex spec/requests` — all green
- `bundle exec rspec spec/system` — green (client-touching changes; also `CAPYBARA_SERVER=falcon` / `rake spec:system_servers` for both real servers)
- `bundle exec rubocop` — no offenses
- `bundle exec rake bench` — before/after captured (only if a hot path was touched)
## Out of scope
<Explicit boundaries — the adjacent things an eager executor must NOT do. E.g. "do not add a hard pgbus dependency", "do not break backwards compatibility for existing components".>
## Execution
Execute with `/lfg <issue-number>` (or `/lfg docs/plans/<file>.md`).
For GitHub issues: create with gh issue create --title "..." --body "$(cat <<'EOF' ... EOF)" — single-quoted heredoc delimiter, backticks unescaped (see .claude/rules/git-workflow.md). Apply the plan label if it exists (gh label list); don't create labels.
For markdown files: Write to docs/plans/YYYY-MM-DD-<slug>.md. Leave it uncommitted — committing is the user's call.
Phase 5 — Handoff
Report back: link to the issue (or file path), the chosen approach in 2–3 sentences, and the exact execute command. Stop there — do not start implementing.