plan
This skill should be used when transforming feature descriptions into well-structured project plans following conventions.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
This skill should be used when transforming feature descriptions into well-structured project plans following conventions.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
This skill should be used when auditing the recurring per-Anthropic-model-release checklist (model IDs, claude-code-action pin freshness, pricing drift, tier-map re-evaluation): it auto-fixes stale model-ID swaps into a CI-gated PR and flags the rest.
This skill should be used when performing exhaustive code reviews using multi-agent analysis, ultra-thinking, and worktrees.
This skill should be used when designing agent-native applications where agents are first-class citizens: architecting autonomous agents, creating MCP tools, building apps where features are agent-driven outcomes.
This skill should be used when working with DSPy.rb, a Ruby framework for type-safe, composable LLM applications.
This skill provides a promptfoo eval harness that measures whether a Soleur skill or agent edit actually improves behavior, comparing a skill arm against a baseline control arm.
This skill should be used when resolving all TODO comments in the codebase using parallel processing. It analyzes dependencies, creates a resolution plan with a mermaid flow diagram, and spawns parallel resolver agents.
| name | plan |
| description | This skill should be used when transforming feature descriptions into well-structured project plans following conventions. |
You are the planning orchestrator. Whether entered from /brainstorm, /one-shot Step 1, or direct /plan:
plans/ + tasks.md without invoking /work — the plan is a checkpoint, not a deliverable./work <plan-path> (or /deepen-plan when the plan requests it) via slash command — never substitute ad-hoc implementation.plugins/soleur/lib/harness.ts — Grok uses /work, /deepen-plan; Claude uses Skill tool.See plugins/soleur/lib/workflow-fidelity.ts (HANDOFF_SKILLS, mandatorySuccessors('plan')).
Note: The current year is 2026. Use this when dating plans and searching for recent documentation.
Transform feature descriptions, bug reports, or improvement ideas into well-structured markdown files issues that follow project conventions and best practices. This command provides flexible detail levels to match your needs.
<feature_description> #$ARGUMENTS </feature_description>
If the feature description above is empty, ask the user: "What would you like to plan? Please describe the feature, bug fix, or improvement you have in mind."
Do not proceed until you have a clear feature description from the user.
Load project conventions:
# Load project conventions
if [[ -f "CLAUDE.md" ]]; then
cat CLAUDE.md
fi
Branch safety check (defense-in-depth): Run git branch --show-current. If the result is main or master, abort immediately with: "Error: plan cannot run on main/master. Checkout a feature branch first." This check fires in all modes as defense-in-depth alongside PreToolUse hooks -- it fires even if hooks are unavailable (e.g., in CI).
Check for knowledge-base directory and load context:
Check if knowledge-base/ directory exists. If it does:
git branch --show-current to get the current branch namefeat-, read knowledge-base/project/specs/<branch-name>/spec.md if it existsIf knowledge-base/ exists:
CLAUDE.md if it exists - apply project conventions during planning# Project Constitution heading is NOT already in context, read knowledge-base/project/constitution.md - use principles to guide planning decisions. Skip if already loaded (e.g., from a preceding /soleur:brainstorm).feat-<name> pattern)knowledge-base/project/specs/feat-<name>/spec.md if it exists - use as planning inputfeat-<name>"If knowledge-base/ does NOT exist:
Check for brainstorm output first:
Before asking questions, look for recent brainstorm documents in knowledge-base/project/brainstorms/ that match this feature:
ls -la knowledge-base/project/brainstorms/*.md 2>/dev/null | head -10
Relevance criteria: A brainstorm is relevant if:
If a relevant brainstorm exists:
If multiple brainstorms could match: Use AskUserQuestion tool to ask which brainstorm to use, or whether to proceed without one.
If no brainstorm found (or not relevant), run idea refinement:
Refine the idea through collaborative dialogue using the AskUserQuestion tool:
Gather signals for research decision. During refinement, note:
Skip option: If the feature description is already detailed, offer: "Your description is clear. Should I proceed with research, or would you like to refine it further?"
Run BEFORE spawning any research (Phase 1) — research and downstream phases are expensive, and building a plan atop a stale premise wastes all of it. brainstorm Phase 1.1 does this validation when a brainstorm precedes plan, but plan is frequently entered directly (including the one-shot → plan path that skips brainstorm), so the cheap probe must also live here. This is distinct from Phase 1.7 reconciliation (which checks spec claims AFTER research returns) — this gate fires before research is even dispatched.
This also covers your own option-bounding capability claims — not just cited references. Before asserting that a repo tool/skill/script "only does X" or "can't do Y" to bound the plan's options, grep/read it first or phrase it as a question (hr-verify-repo-capability-claim-before-assert).
For every issue, blocker, dependency, or prior-art artifact the feature description cites by reference, verify it still holds:
#N, Closes #N, "blocked by #N", "follow-up to #N"): run gh issue view <N> --json state,title,closedByPullRequestsReferences and gh pr view <N> --json state,merged where applicable. If a blocker is already closed/merged, or the issue this plan targets is already closed by a merged PR, the premise is stale — surface via AskUserQuestion ("Issue #N appears already resolved by PR #M. Re-scope, or close as done?") rather than planning against it.git show origin/main:<path> or git grep -n "<symbol>" origin/main. If the cited artifact does not exist on origin/main, the premise ("fix the bug in X") may really be "X was never built" — flag it; the plan's shape changes from fix to build.git grep) before planning a behavioral fix — a silently-absent feature needs a build plan, not a patch.knowledge-base/engineering/architecture/decisions/ for the mechanism's keywords (not the cited issue number — issues don't know what an ADR decided) and read any hit's ## Decision + ## Alternatives Considered. A mechanism sitting in an ADR's rejected-alternatives table is not an unconsidered idea — it is an explicitly-rejected one; re-scope to "did the ADR leave a gap this still addresses?" rather than planning the rejected approach. Corollary: when the feature pins an absolute value (a fixed model/tier/limit), check its interaction with the most capable end of the range, not just the cheap end (an absolute opus reviewer pin is a downgrade on a Fable session). Why: #5087 — the issue's frontmatter-tiering approach matched the exact alternative ADR-053 rejected the day before (#5096); caught only at deepen-plan, three phases deep. See knowledge-base/project/learnings/2026-06-11-brainstorm-grep-adr-corpus-for-proposed-mechanism-not-just-issue-refs.md.Emit a one-paragraph Premise Validation note (what was checked, what held, what was stale) into the research-insights scratch so Phase 1.7 and the plan's "Research Reconciliation" section can carry it forward. If nothing is cited by reference, state "no external premises to validate" and proceed.
Run these agents in parallel to gather local context:
What to look for:
knowledge-base/project/learnings/ that might apply (gotchas, patterns, lessons learned)These findings inform the next step.
If the feature description matches any of the patterns SSH, connection reset, kex, firewall, unreachable, timeout, 502, 503, 504, handshake, EHOSTUNREACH, ECONNRESET (case-insensitive substring match on the feature description), read plan-network-outage-checklist.md and require its output in the ## Hypotheses section of the final plan.
Also fire this gate when the feature description names terraform apply (with or without -target=) against a resource whose definition contains provisioner "file", provisioner "remote-exec", or a connection { type = "ssh" ... } block. The provisioner block makes SSH a hard apply-time dependency that the prose-only keyword scan won't detect. Why: #3061 — apply on terraform_data.deploy_pipeline_fix hit ssh: handshake failed: connection reset by peer despite zero SSH keywords in the plan, because the firewall allowlist had drifted out from under the operator's egress IP.
The checklist enforces an L3->L7 diagnostic order: firewall allow-list and DNS/routing MUST be verified before sshd/fail2ban/service-layer hypotheses. Per AGENTS.md hr-ssh-diagnosis-verify-firewall, this is a hard rule -- plans that propose sshd or fail2ban fixes without first verifying firewall + egress IP are workflow violations.
When a trigger pattern matches, emit rule-application telemetry so the weekly aggregator records this gate fired (see AGENTS.md hr-ssh-diagnosis-verify-firewall):
source "$(git rev-parse --show-toplevel)/.claude/hooks/lib/incidents.sh" && \
emit_incident hr-ssh-diagnosis-verify-firewall applied \
"When a plan addresses an SSH/network-connectivity s"
This step is a single file read, not a subagent spawn. If the feature description does not match any trigger pattern, skip this step silently.
Read plugins/soleur/skills/plan/references/plan-community-discovery.md now for the full community discovery procedure (stack detection, coverage gap check, agent-finder). Skip if no uncovered stacks detected.
Read plugins/soleur/skills/plan/references/plan-functional-overlap.md now for the functional overlap check procedure (always runs, spawns functional-discovery agent).
Based on signals from Step 0 and findings from Step 1, decide on external research.
High-risk topics → always research. Security, payments, external APIs, data privacy. The cost of missing something is too high. This takes precedence over speed signals.
Strong local context → skip external research. Codebase has good patterns, CLAUDE.md has guidance, user knows what they want. External research adds little value.
Uncertainty or unfamiliar territory → research. User is exploring, codebase has no examples, new technology. External perspective is valuable.
Announce the decision and proceed. Brief explanation, then continue. User can redirect if needed.
Examples:
Only run if Step 1.6 indicates external research is valuable.
Run these agents in parallel:
After all research steps complete, consolidate findings:
app/services/example_service.rb:42)knowledge-base/project/learnings/ (key insights, gotchas to avoid)knowledge-base/project/learnings/best-practices/2026-04-15-plan-skill-reconcile-spec-vs-codebase.md.Optional validation: Briefly summarize findings and ask if anything looks off or missing before proceeding to planning.
After the plan draft has enumerated its ## Files to Edit and ## Files to Create sections (i.e., run this check AFTER Step 2 Issue Planning produces the file list, and BEFORE Step 4 Detail Level selection), verify whether any open code-review issues touch files the plan intends to modify. This prevents two failure modes:
Procedure:
Read the plan's ## Files to Edit and ## Files to Create sections (the plan draft exists by this point). Extract every file path. If the plan is still being drafted and those sections are not yet written, defer this check until they exist rather than guessing from the feature description — guessing produces false negatives.
Query open code-review issues. Use two-stage piping (--json then a standalone jq --arg), not single-stage gh --jq with --arg. The gh CLI does NOT forward --arg to its embedded jq; a single-stage form produces unknown arguments at runtime. See learning knowledge-base/project/learnings/2026-04-15-gh-jq-does-not-forward-arg-to-jq.md.
ISSUES_JSON=$(mktemp -t open-review-issues.XXXXXXXX.json)
gh issue list --label code-review --state open \
--json number,title,body --limit 200 > "$ISSUES_JSON"
echo "ISSUES_JSON=$ISSUES_JSON"
For each planned file path, search the issue bodies using standalone jq with --arg (safe against regex metacharacters in paths):
jq -r --arg path "<file-path>" '
.[] | select(.body // "" | contains($path))
| "#\(.number): \(.title)"
' "$ISSUES_JSON"
A later Bash call does not inherit ISSUES_JSON, so carry the echoed path forward (or
re-derive it in the same call). Do not substitute a fixed name: a concurrent /plan
would overwrite the file between the write and this read.
If any matches are returned, write a ## Open Code-Review Overlap section to the plan file with a one-line bullet per match and an explicit disposition for each:
X open scope-outs touch these files: #2466 (Range cache), #2483 (helper extraction). Fold in / acknowledge / defer: …
For each match, the planner MUST explicitly choose one of:
## Files to edit and note Closes #<N> in the PR-body reminder.If no matches, still record ## Open Code-Review Overlap with None so the next planner can see the check ran.
Why this matters: In the 2026-04-17 window, PR #2486 closed three scope-outs (#2467 + #2468 + #2469) because the planner noticed the overlap. PRs #2463 and #2477 grew the backlog instead because no overlap check ran. This phase makes the #2486 pattern the default, not the exception. See knowledge-base/project/learnings/best-practices/2026-04-17-review-backlog-net-positive-filing.md.
Phase 1 baseline. If the feature description, research findings (1.1), or repo grep (Phase 1.7 consolidation) surfaces a candidate description: edit to any plugins/soleur/skills/*/SKILL.md, run the budget one-liner now (Node form, see knowledge-base/project/learnings/2026-04-21-skill-description-budget-at-cap-requires-plan-time-surgery.md Measurement one-liner section). Record baseline headroom in Research Insights.
Step 2 re-check. Once ## Files to Edit is finalized in Step 2 (Issue Planning), re-run the one-liner if any candidate description: edit landed in the file list — including candidates the planner introduced in Step 2 that Phase 1 did not surface. The check fires on the final list, not the Phase 1 candidate set.
Headroom failure action. If either check reports < 10 words remaining against the 1800-word cumulative cap (enforced by plugins/soleur/test/components.test.ts), include exact sibling-trim text (before/after) in ## Files to Edit before proceeding. Skip silently if no SKILL.md description: edit is ever candidate or finalized.
Title & Categorization:
feat: Add user authentication, fix: Cart total calculation)-plan suffix
feat: Add User Authentication → 2026-01-21-feat-add-user-authentication-plan.mdStakeholder Analysis:
Content Planning:
plans/<this-plan>.md, specs/feat-<branch>/tasks.md, specs/feat-<branch>/session-state.md) from BOTH the sweep file-list AND the residual-zero AC, exactly like **/archive/** -- they are point-in-time migration records that must cite the old path. A residual-zero AC and a "plan retains old path" AC are mutually contradictory unless the carve-out covers all three artifacts, not just the plan file. See learning 2026-06-03-path-rename-sweep-exclude-own-migration-artifacts.md.rg the codebase for every other inline query on the same table that BYPASSES the helper (id-based lookups, pre-helper historical queries, WS-handler inline SELECTs) and list each as a Files to Edit entry -- sibling queries are the most common silent backdoor after a tenant-scope change. See learning 2026-04-22-scope-by-new-column-audit-every-query-not-just-the-helper.md.apps/foo/**, **/doppler*.{yml,yaml,sh}, .github/workflows/*foo*.yml), verify each glob matches ≥1 real file via git ls-files | grep -E '<translated-glob>' AND for negative-coverage gates (security gates, denylist filters, sensitive-path detectors) enumerate sibling files at the same architectural depth — globs constructed from a plan miss files the plan never inventoried. See AGENTS.md hr-when-a-plan-specifies-relative-paths-e-g and learning 2026-04-28-plan-globs-must-be-verified-against-repo-structure.md.claude-code-action, peter-evans/create-pull-request, or any wrapper that constrains workflow architecture (token-revoking post-steps, hardcoded auto-merge, mandated job ordering), ask: "what does this look like as 5 lines of curl + jq?" If the answer is "fine," skip the wrapper. The wrapper's value is in agent tool-use loops or PR-creation generality; a single-shot LLM call or single-PR workflow doesn't need it. Why: 2026-05-11 #2720 v1 plan adopted claude-code-action and contorted into a two-job split + matrix to dodge its post-step token revocation; v2 dropped the wrapper and 4 P0 issues dissolved. See knowledge-base/project/learnings/2026-05-11-five-agent-plan-review-panel-and-architectural-false-trails.md.<script-file>:<line>, <workflow-file>:<section>, or prompt:step-N. Without the pointer, the FR is paper — the planner could not encode the fix in code, only in prose, and the implementer will discover the gap at /work time. Why: 2026-05-11 #2720 v1 plan folded 6 spec-flow P0s as FRs/ACs; spec-flow re-validation against the plan caught 4 as "RESOLVED in spec, NOT IMPLEMENTED in code." Same learning file.After generating the plan structure, assess which business domains this plan has implications for. This gate enforces constitution line 122: plans must receive cross-domain review before implementation.
Step 1 — Domain Sweep:
Brainstorm carry-forward check: If the brainstorm document (loaded in Phase 0.5) contains a ## Domain Assessments section, carry forward the findings. Extract relevant domains and their summaries. Skip fresh assessment.
Fresh assessment (if no brainstorm or no ## Domain Assessments section): Read plugins/soleur/skills/brainstorm/references/brainstorm-domain-config.md. Assess all 8 domains against the plan content in a single LLM pass using each domain's Assessment Question. Use semantic assessment — not keyword matching.
Spawn domain leaders: For each domain assessed as relevant except Product (handled in Step 2), spawn the domain leader as a blocking Task using the Task Prompt from brainstorm-domain-config.md, substituting {desc} with the plan summary. Spawn in parallel if multiple are relevant.
Collect findings: Wait for all domain leader Tasks to complete. Each returns a brief structured assessment. If a domain leader Task fails (timeout, error), write partial findings for that domain with Status: error and continue with remaining domains.
Step 1.5 — Brainstorm Specialist Carry-Forward Gate:
After domain sweep, scan the brainstorm document's ## Domain Assessments section (and any ## Capability Gaps section) for domain leaders that recommended specific specialists by name (e.g., "delegates to conversion-optimizer", "recommends copywriter for cancellation copy", "invoke ux-design-lead for wireframes"). Build a REQUIRED_SPECIALISTS list from these recommendations.
For each specialist in REQUIRED_SPECIALISTS:
**Brainstorm-recommended specialists:**.Enforcement: Specialists recommended by name in brainstorm domain assessments MUST be either invoked or explicitly declined by the user via AskUserQuestion ("Domain leader recommended [specialist] for [reason]. Run now / Skip with acknowledgment"). Silent skipping is a workflow violation. Why: In #1078, the CMO recommended conversion-optimizer and copywriter for the cancellation flow, but the plan skill silently wrote them into Skipped specialists: without asking, producing UX artifacts that lacked brand review.
Step 2 — Product/UX Gate:
Mechanical UI-surface override (runs FIRST, before the subjective relevance check). Scan the plan's ## Files to Create AND ## Files to Edit against the shared UI-surface term list + glob superset (plugins/soleur/skills/brainstorm/references/ui-surface-terms.md). If any path matches, force Product-relevant = true AND tier = BLOCKING, regardless of what the Step-1 semantic sweep concluded. This closes the silent-skip hole where a UI feature whose sweep judged Product NONE would skip the gate entirely (a UI feature must never reach ## NONE by subjective judgment alone). A plan that only discusses UI but implements orchestration/docs (no UI-surface file in its Files lists) is exempt and may be NONE.
After Steps 1 and 1.5 complete, if Product domain was flagged as relevant (by the sweep OR the mechanical override above), run the three-tier classification:
A plan that discusses UI concepts but implements orchestration changes (e.g., adding a UX gate to a skill) is NONE.
Mechanical escalation (overrides subjective assessment): Scan the plan's "Files to create" list. If any new file path matches components/**/*.tsx, app/**/page.tsx, or app/**/layout.tsx, the tier is BLOCKING regardless of subjective assessment. Creating a new component file = new user-facing surface = UX review required. Why: In #1049, a notification prompt component was classified as ADVISORY because the agent judged it "not significant enough." The user had to manually trigger the UX gate post-plan.
On BLOCKING:
Run spec-flow-analyzer via Task with UI-flow-aware prompt: "Analyze the user flows in this plan. Map each screen, identify entry/exit points, dead ends, missing error states, and flows that drop the user. Focus on user journey completeness, not technical implementation."
Run CPO via Task with scoped prompt: "Assess the product implications of this plan: {plan summary}. Cross-reference against brand-guide.md and constitution.md. Identify product strategy concerns, flow gaps, and positioning issues. Output a structured advisory — do not use AskUserQuestion."
Brainstorm carry-forward check. Before invoking ux-design-lead, check the UX signal source. If the only UX validation is brainstorm carry-forward (brainstorm assessed the idea, not the page design), reject it: "Brainstorm validated the idea, not the page design. Proceeding to wireframes." Then continue to step 4. This check applies to BLOCKING tier only — ADVISORY and NONE tiers may still carry forward brainstorm UX findings.
Invoke ux-design-lead via Task with scoped prompt: "Create wireframes for these user flows: {flow list}. Platform: desktop. Fidelity: wireframe." On the one-shot/pipeline path (no brainstorm ran), plan Phase 2.5 is the SOLE PRODUCER of wireframes — it must GENERATE the .pen, not defer. If the agent self-stops because Pencil is unavailable, do NOT record a skip: run bash ${CLAUDE_PLUGIN_ROOT:-plugins/soleur}/skills/pencil-setup/scripts/check_deps.sh --auto (installs @pencil.dev/cli; auth via PENCIL_CLI_KEY from Doppler soleur/dev) and re-invoke. Hard-block (do not proceed, do not write to Skipped specialists:) only if auth is genuinely unsatisfiable or Node < 22.9.0, with a single instruction: "Provision PENCIL_CLI_KEY in Doppler soleur/dev (or pencil login), or install Node ≥ 22.9.0, then re-run plan." The two permitted outcomes are a committed .pen or this hard-block — ux-design-lead may never appear in Skipped specialists: for a UI feature (wg-ui-feature-requires-pen-wireframe). Verifier asserts the invariant, not the proxy: confirm the .pen exists on disk (non-empty) under knowledge-base/product/design/{domain}/ and is referenced in the spec FRs — not "specialist reported done"; set Pencil available: yes.
4b. Wireframe review pause. ux-design-lead ends by running xdg-open <screenshots-directory>, so the wireframes are already open when it returns here. A Task subagent cannot collect operator input (2026-05-12-task-subagent-prompt-text-only.md), so the review pause lives in this orchestrator, right after the step-4 invocation. Mode-branch gate (2026-03-27-skill-defense-in-depth-gate-pattern.md): always run, branch on mode.
AskUserQuestion — "Wireframes are open for review at <screenshots-dir>. Approve and continue, or request changes?" Options: Approve → record the approved design's aesthetic direction to the taste-profile (the agent surface's write path — ux-design-lead never writes taste itself; #5990/ADR-090): bash ${CLAUDE_PLUGIN_ROOT:-plugins/soleur}/scripts/taste-profile-update.sh knowledge-base/product/design/taste-profile.md <context> aesthetic-direction <approved-direction> "$(date -u +%F)" (<context> = the design's surface enum, <approved-direction> = a sanitized lowercase-hyphen token); then continue to step 5 (Content Review Gate). Request changes → collect a free-text note, re-invoke ux-design-lead with feedback: <note> plus the existing .pen path, let it re-export + re-open, then re-ask. Loop until Approve — the Approve branch is the only exit (no dead end).On ADVISORY: block below (step 1 — "If in pipeline/subagent context … auto-accept … proceed silently"). When plan runs in any non-interactive context — HEADLESS_MODE=true, no TTY, /soleur:one-shot, /soleur:go --headless, OR invoked with a plan-file-path argument (the one-shot path chains plan inside a Task subagent, one-shot/SKILL.md:70) — do NOT pause. Record wireframes ready for async review at <dir> and continue to step 5. Load-bearing: the subagent / file-path context is inherently non-interactive — the headless arm MUST fire there or the autonomous pipeline hangs on AskUserQuestion.one-shot/SKILL.md:11 ("no per-phase approval gates"). Keep this mode predicate in sync with brainstorm Phase 3.55b and the canonical Phase 0.4 mode-detection block (brainstorm/SKILL.md:101) — the four context terms (HEADLESS_MODE, no-TTY, /soleur:one-shot, --headless) must stay aligned across all copies; the plan-file-path term is a plan-specific addition.Content Review Gate. Check if any domain leader (CMO, CRO, CPO, or other) recommended a copywriter or content specialist in their Step 1 assessment. If yes: invoke copywriter agent via Task with prompt: "Review the planned page content for brand voice compliance, value proposition clarity, and messaging effectiveness. Reference brand-guide.md." If copywriter ran successfully, add copywriter to **Agents invoked:**. If user declines, add copywriter to **Skipped specialists:** with the user's reason. If copywriter agent fails (timeout, error), add copywriter to **Skipped specialists:** with note (agent error — review manually) and set **Decision:** reviewed (partial). If no domain leader recommended a copywriter, skip this step silently. This gate also fires on ADVISORY tier when a domain leader recommended a copywriter — the recommendation is the signal, not the tier.
Phase 3 SpecFlow is skipped (spec-flow-analyzer already ran in step 1 with UI-aware prompt — avoids duplicate invocation).
If any agent in the pipeline fails (timeout, error), write partial findings with Decision: reviewed (partial). BLOCKING gate enforcement: If the tier is BLOCKING and a required specialist failed, do NOT silently proceed. For ux-design-lead specifically there is NO "skip" option — it is a non-skippable producer (step 4): retry via pencil-setup --auto, or hard-block until Pencil is provisioned. For copywriter / spec-flow-analyzer failures, use AskUserQuestion: "BLOCKING Product/UX Gate: [specialist] failed ([reason]). How to proceed?" Options: (a) Retry now, (b) Skip with acknowledgment (copywriter/spec-flow only — never ux-design-lead), (c) Defer to next session. Record the choice in the Domain Review section. For ADVISORY tier or non-specialist agents, proceed silently with partial findings as before.
On ADVISORY:
Tier: advisory, Decision: auto-accepted (pipeline), proceed silently.On NONE: Skip — no Product/UX Gate subsection needed beyond the domain sweep finding.
If Product domain was NOT flagged as relevant in the sweep AND the mechanical UI-surface override did not fire, skip Step 2 entirely. If the override fired, Step 2 runs at BLOCKING tier regardless of the sweep.
Writing the ## Domain Review section:
After both steps complete, write the ## Domain Review section to the plan file using the heading contract below.
## Domain Review Heading Contract:
## Domain Review
**Domains relevant:** [comma-separated list] | none
### [Domain Name] (one subsection per relevant non-Product domain)
**Status:** reviewed | error
**Assessment:** [leader's structured assessment summary]
### Product/UX Gate (only if Product domain relevant and tier is BLOCKING or ADVISORY)
**Tier:** blocking | advisory
**Decision:** reviewed | reviewed (partial) | skipped | auto-accepted (pipeline)
**Agents invoked:** spec-flow-analyzer, cpo, ux-design-lead, copywriter | [subset] | none
**Skipped specialists:** copywriter (<reason>) | none — `ux-design-lead` is NEVER valid here for a UI feature (non-skippable: `.pen` committed or hard-block per `wg-ui-feature-requires-pen-wireframe`)
**Pencil available:** yes | hard-blocked (auth/Node) | N/A (no UI surface)
#### Findings
[Agent findings summary]
When NO domains are relevant:
## Domain Review
**Domains relevant:** none
No cross-domain implications detected — infrastructure/tooling change.
Place after Acceptance Criteria, before Test Scenarios (or before the last major section). If the plan lacks an Acceptance Criteria heading, place before the last major section or at the end of the plan.
Every plan MUST include a ## User-Brand Impact section. This is the framing-time enforcement of AGENTS.md hr-weigh-every-decision-against-target-user-impact and the gate that catches the #2887-class blind spot — decisions weighed on technical and convenience axes only, with no question asked about what one user's breach would cost the brand.
Step 1 — Insert the section. If the plan draft does not yet contain a ## User-Brand Impact heading, insert one using the template from plugins/soleur/skills/plan/references/plan-issue-templates.md. The section MUST appear between the description and the Acceptance Criteria. The three required lines:
**If this lands broken, the user experiences:** — name a concrete, user-facing artifact.**If this leaks, the user's [data / workflow / money] is exposed via:** — name a concrete exposure vector.**Brand-survival threshold:** none | single-user incident | aggregate pattern — choose one.Step 2 — Brainstorm carry-forward. If the brainstorm document loaded in Phase 0.5 contains a ## User-Brand Impact framing (which it should when brainstorm Phase 0.1 set USER_BRAND_CRITICAL=true), import the threshold and the artifact/vector declarations directly rather than re-authoring. Carry-forward is preferred — re-authoring at plan time risks drift from the brainstormed framing.
Step 3 — Threshold-driven sign-off requirement. If the threshold resolves to single-user incident:
requires_cpo_signoff: true to the plan's YAML frontmatter./work begins. Invoke CPO domain leader if not already covered by Phase 2.5 carry-forward, or confirm CPO has reviewed the brainstorm."user-impact-reviewer will be invoked at review-time (handled by plugins/soleur/skills/review/SKILL.md conditional-agent block).Sign-off lifecycle staging — who participates at which phase:
The set of mandatory leaders changes by lifecycle phase, and that is by design — different leaders weigh in at different decision points:
USER_BRAND_CRITICAL=true. Rationale: the approach has not been chosen yet, so all three lenses (product blast-radius framing, legal/compliance, architectural blast-radius) need to land before the plan exists. See plugins/soleur/skills/brainstorm/references/brainstorm-domain-config.md ## User-Brand-Critical Tag Processing.user-impact-reviewer agent enumerates failure modes against the diff. Rationale: review-time concerns are diff-shaped, not approach-shaped.This tiered model is intentional — re-asking CPO/CLO/CTO at every phase would dilute the framing into ceremony. The framing question is asked once (brainstorm), the answer is locked in (plan), the diff is checked against the answer (review), the gate verifies the answer was given (ship).
If the threshold resolves to aggregate pattern, no per-PR sign-off is added but the section must still be present.
If the threshold resolves to none AND the diff touches a sensitive path (canonical regex defined in plugins/soleur/skills/preflight/SKILL.md Check 6 Step 6.1), the section MUST contain a threshold: none, reason: <one-sentence non-empty reason> scope-out bullet. Without it, preflight will FAIL at ship time.
Step 4 — Sharp-edge note. When emitting the final plan output, add a Sharp Edges entry:
A plan whose
## User-Brand Impactsection is empty, contains onlyTBD/TODO/placeholder text, or omits the threshold will faildeepen-planPhase 4.6. Fill it before requesting deepen-plan or/work.
Why: Triggered by #2887 — the dev/prd Doppler-config collapse shipped for months because every existing gate weighed the decision on technical and convenience axes only. The framing-time enforcement here, combined with deepen-plan Phase 4.6 (halt on missing section), preflight Check 6 (ship-time gate), and the user-impact-reviewer conditional agent, closes the workflow-level loop.
[skill-enforced: gdpr-gate at plan Phase 2.7]
If the plan touches regulated-data surfaces (per the hr-gdpr-gate-on-regulated-data-surfaces canonical regex — schemas, migrations, auth flows, API routes, .sql files), invoke /soleur:gdpr-gate against the plan doc + the FR/TR sections being authored. Output is advisory-only with mandatory disclaimer; Critical findings (Art. 9 special-category, missing lawful basis, Art. 30 trigger) prompt operator-acknowledged write to compliance-posture.md Active Items + GitHub issue with label compliance/critical.
Also invoke when canonical regex misses but ANY of these hold: (a) new processing activity using LLM/external API on operator-session-derived data, (b) brand-survival threshold single-user incident declared in the plan, (c) new cron/workflow that READS from knowledge-base/project/learnings/ or knowledge-base/project/specs/, (d) new artifact distribution surface (plugin update, public PR body, package release). The canonical regex covers schema/auth/API code surfaces; these four expand coverage to cross-controller data-movement surfaces. Why: 2026-05-11 #2720 — plan touched none of the regex surfaces but added Anthropic-bound LLM-summarization of operator-session learnings + draft PRs to public repo; gate-time invocation surfaced a pre-existing Anthropic-DPA gap that no other gate caught. See knowledge-base/project/learnings/2026-05-11-five-agent-plan-review-panel-and-architectural-false-trails.md.
Skip silently if no regulated-data surface is touched AND none of the (a)-(d) triggers fire.
[skill-enforced: terraform-architect at plan Phase 2.8]
If the plan introduces infrastructure that needs to live somewhere — a server, a systemd service, a cron job, a vendor account, a DNS record, a TLS cert, a secret, a firewall rule, a monitoring webhook — route the implementation through Terraform (or another IaC mechanism already in the repo) at plan time. Do NOT bake "operator runs ssh root@host && ...", "operator runs doppler secrets set X=...", or "operator clicks through the vendor dashboard" into the plan's Implementation Phases. Per hr-all-infrastructure-provisioning-servers, manual provisioning is not an acceptable phase output.
Detection (case-insensitive substring scan of the plan draft + the feature description):
ssh root@, ssh deploy@, ssh ubuntu@, ssh <user>@<host>manually install, operator runs, operator installs, operator-driven, out-of-bandsystemctl enable, systemctl start, systemd unit, /etc/systemd/system/doppler secrets set (vs reading via doppler secrets get which is read-only)terraform import of a resource that should have been created by Terraformcron/crontab -e, at <time>, journalctl (when used for state, not diagnosis)service-automator or ops-provisionerIf detected, invoke terraform-architect with the plan draft and the detected phrases. The agent's job is to reshape the affected Implementation Phases so the new resource lives in apps/<app>/infra/*.tf (extending the existing root, or creating a new one with the R2 backend per hr-every-new-terraform-root-must-include-an), with cloud-init/runcmd for first-boot config and an idempotent bootstrap script (e.g. apps/<app>/infra/<resource>-bootstrap.sh) for applying the change to already-running hosts without re-provisioning.
Required output: ## Infrastructure (IaC) section in the plan. Mirror the ## Domain Review heading contract. Required subsections:
### Terraform changes — listed files (existing TF root + new resources), required providers + version pins, sensitive variable list (TF_VAR_<name> plus where the value comes from — Doppler service token, etc.).### Apply path — one of: (a) cloud-init-only (acceptable when the resource has not yet been provisioned), (b) cloud-init + idempotent bootstrap script (the default for existing infra), (c) taint + terraform apply -replace (only when the resource cannot be patched in place). State the chosen path and the expected downtime/blast-radius.### Distinctness / drift safeguards — dev != prd preconditions, lifecycle.ignore_changes callouts, state-storage notes (encrypted backend, secret values land in terraform.tfstate).### Vendor-tier reality check — when the chosen provider has free-tier limits that affect resource creation (e.g., Better Stack free tier rejects betteruptime_policy), document the tier gate (count = var.<provider>_paid_tier ? 1 : 0) before apply time.Why: PR-F (#3940) plan baked in "operator installs inngest-cli + systemd unit via SSH" and "operator sets Doppler keys via CLI" as Phase X items. Both violate hr-all-infrastructure-provisioning-servers. The rule existed; no plan-time gate consulted it. The cost was a post-merge realisation that the entire operator checklist had to be redone as Terraform. See knowledge-base/project/learnings/2026-05-18-plan-baked-in-operator-ssh-violated-iac-rule.md.
Skip silently if the plan introduces no new infrastructure (pure code change against an already-provisioned surface). A plan that only edits files under apps/<app>/src/ or apps/<app>/server/ typically skips. A plan that introduces a new service, a new secret, a new vendor, or a new persistent runtime process does not.
[skill-enforced: plan Phase 2.9 + deepen-plan Phase 4.7]
Every plan whose Files-to-Edit includes a code-class file under apps/*/server/, apps/*/src/, apps/*/infra/, plugins/*/scripts/, or that introduces any new infrastructure surface (per Phase 2.8 trigger set), MUST emit a ## Observability section using the 5-field schema. A feature that requires SSH to verify observability is a feature without observability.
Required schema (verbatim from plan-issue-templates.md):
liveness_signal: # what / cadence / alert_target / configured_in
error_reporting: # destination / fail_loud
failure_modes: # list of {mode, detection, alert_route}
logs: # where / retention
discoverability_test: # command (NO ssh) / expected_output
Reject conditions (enforced at deepen-plan Phase 4.7 — see deepen-plan/SKILL.md):
TODO, TBD, placeholder, or manual operator check AS THE FIELD VALUE (a fallback note in surrounding prose mentioning TBD is allowed; the canonical "field is empty" reject regex is ^\s*<field>:\s*(TODO|TBD|placeholder|manual operator check)\s*$).discoverability_test.command contains ssh (with trailing space — distinguish "ssh " the verb from "ssh-free" in docs).Skip silently when:
Why: #4116 — inngest-heartbeat.service was silently broken for 16+ hours. The plan that introduced it (PR-F #3940) passed every other plan-time gate but had no observability declaration; the operator-blind-zone aggregated across the substrate cascade (#4017 → #4111) until issue #4116 surfaced the gap. Codifying the gate at plan-time prevents the next feature from shipping a dark observability surface.
If any Acceptance Criterion or the liveness_signal declares a post-deploy soak / time-gated close criterion — a signal that must hold for N days/hours before an issue closes or an ADR/amendment status flips (adopting → accepted), e.g. "op:founder-ambiguous stays at ~0 for 7 days post-deploy" — the plan MUST add a Follow-Through Enrollment deliverable so the closure is automated, not left to human memory (the recurring rot the daily follow-through sweeper exists to prevent — see followthrough-convention.md, §Soak trigger shape).
The deliverable names:
<short-name>-<issue>.sh) — exit 0 when the soak holds; for Sentry-rate soaks, mirror reconcile-ff-only-sentry-4977.sh with start= pinned strictly after deploy;<!-- soleur:followthrough script=… earliest=<deploy+Nd> secrets=… --> directive + the follow-through label;secrets= to wire into .github/workflows/scheduled-followthrough-sweeper.yml.This is enforced at ship time (fail-closed) by /ship Phase 5.5's Soak-Gated Follow-Through Enrollment Gate + the ship-soak-followthrough-gate.sh PreToolUse hook; declaring it here means the work phase builds the probe instead of /ship blocking PR-ready on a missing one. Why: 2026-06-29 — PR #5671 (#5673) and PR #5675 (#5689) both shipped soak-gated closures in prose with no enrollment; both trackers were left to rot until caught manually.
If the plan's Files-to-Edit touch a surface the operator/agent CANNOT directly inspect — an agent bwrap sandbox (server/agent-runner-sandbox-config.ts, server/sandbox*.ts, server/bash-sandbox.ts), a container dispatch/readiness gate (server/cc-dispatcher.ts, server/agent-runner.ts, *agent-on-spawn*, any *readiness*/*self-stop* path), or a cron worker — the ## Observability block's failure_modes MUST additionally satisfy:
detection names an in-surface probe (a signal emitted FROM the sandbox/container/worker), not only a host-side layer. A host gate cannot observe a sandbox's internal state.source / gitKind / gitRevParseValid for a host-vs-sandbox-mount split) — not a single boolean that emits for only one failure shape.This is the affected-surface extension of hr-observability-as-plan-quality-gate — the diagnosis-first discipline for blind surfaces, enforced at review by observability-coverage-reviewer §Step 4.6. Why: #5733 — 6 blind server-side fixes over ~2 weeks because the failing agent-sandbox surface emitted no discriminating telemetry; one in-sandbox event decided the root cause the moment it shipped. See knowledge-base/project/learnings/best-practices/2026-07-01-blind-surface-needs-structured-probe-before-nth-fix.md.
[skill-enforced: plan Phase 2.10 — wg-architecture-decision-is-a-plan-deliverable]
If the plan makes or changes an architectural decision, the ADR write and the C4 diagram update are deliverables of THIS plan — never a deferred follow-up issue. Phase 0.6 / line 112 already make you read the ADR corpus; this gate makes you produce the decision record when the plan creates one. Deferring an ADR/C4 update to "later" ships a system whose recorded architecture lies about its real one until someone reopens the issue (usually never).
Detection (the plan introduces or changes any of):
knowledge-base/engineering/architecture/.If detected, the plan MUST emit an ## Architecture Decision (ADR/C4) section naming, as in-scope plan tasks:
### ADR — the ADR to create or amend via /soleur:architecture (number + one-line decision). New decision → new ADR; divergence from an existing one → amend that ADR's ## Decision + add to its ## Alternatives Considered. This is a task in the implementation phases, not a "see also." The chosen ordinal for a NEW ADR is provisional — a sibling PR can claim it during the pipeline (they only surface together post-squash on main, since adr-ordinals is not a required check). /ship's "ADR-Ordinal Collision Gate" re-verifies the next-free ordinal against origin/main before merge and after every Phase 7 sync; do not treat the plan-time number as final. When you DO renumber, sweep the whole feature's artifact set for the old ordinal in the same edit — grep -rn 'ADR-<old>' knowledge-base/project/{plans,specs}/feat-<slug>/ — because the renumber otherwise reaches only the ADR body/seed/code while the plan + tasks + any AC that names the ordinal keep the stale number (a `ADR-<old>-*.md` exists AC then verifies a nonexistent file). Why: #5945 chose ADR-081 → renumber to ADR-082 (#5952); #5990 collided TWICE in one ~2h pipeline (087→089 at rebase, 089→090 at ship as siblings claimed each free ordinal) and the first renumber left AC12 asserting a nonexistent ADR-087-*.md until review caught it (2026-07-05-adr-renumber-must-sweep-planning-docs-and-scripts-glob-orphan.md).
### C4 views — which C4 view(s) (Context / Container / Component) change and how (e.g., "Container: repo connection edge moves from User to Workspace"). The workflow edits the .c4 model files DIRECTLY (via the architecture skill / Edit tool, committed in THIS feature's lifecycle — not a separate issue). The c4-edit flag (commit 3c8849655) gates ONLY direct end-user edits in the in-browser webapp editor (PUT /api/kb/c4, default OFF); it does not gate a workflow and the workflow never routes through that path. Concierge and the Claude Code plugin terminal are equally-trusted agent contexts that edit .c4 on the filesystem and commit — do NOT instruct the implementer to "route the C4 edit through the Concierge."
C4 completeness mandate (load-bearing — no narrow-grep escape hatch). Before writing the ### C4 views task (INCLUDING a "no C4 impact" conclusion), you MUST actually READ all three model files — knowledge-base/engineering/architecture/diagrams/{model.c4,views.c4,spec.c4} — not a single keyword grep. A grep for the feature's own noun (e.g. grep email-triage) returning zero is NOT evidence of "no C4 impact": the relevant elements are frequently the feature's external actors and systems (a human role like an inbound email sender; an integration like Resend/Stripe/Twilio; a new data store), which are named by the vendor/role, not the feature. Enumerate, for the feature, EVERY: (a) external human actor (who sends/receives data — correspondents, reviewers, end recipients), (b) external system / vendor (inbound webhook, outbound API, third-party store), (c) container/data-store touched, (d) actor↔surface access relationship that changes (e.g. single-owner → workspace-Owner-shared). For each, confirm it is already modeled; if NOT, the .c4 edit that adds it (element + #external tag if outside the boundary + the relationship edges + the view … include line in views.c4 so it RENDERS) is an in-scope plan task. Reviewing all three .c4 files for correctness also means fixing any element description the change falsifies (e.g. a "Solo founder" actor description when the change adds multi-Owner sharing). After editing, run the C4 validation tests (apps/web-platform/test/c4-code-syntax.test.ts + c4-render.test.ts) — a view include that references an undefined element fails there, not at tsc. A "no C4 impact" line in the plan MUST cite which actors/systems/relationships were checked and found already-modeled; an unsupported "None" is a reject condition.
### Sequencing — if the decision is only true after a later slice (e.g. a soak-gated migration), the ADR is authored now describing the target state with a "status: adopting" note; it is not postponed to its own issue.
Reject condition (enforced at deepen-plan): an architectural decision is detected but the plan defers the ADR/C4 update to a follow-up issue, OR the ## Architecture Decision (ADR/C4) section is missing while detection fires, OR the ### C4 views task concludes "no C4 impact" without citing the external-actor / external-system / access-relationship enumeration it checked against all three .c4 files (the C4 completeness mandate above).
Skip silently when the plan makes no architectural decision — a bug fix on an existing surface, a copy/UI tweak, a dependency bump, a pure-docs change. The test: would a competent engineer reading only the existing ADRs + C4 be misled about the system after this plan ships? If no, skip.
Why: 2026-06-16 ADR-044 workspace-connection brainstorm (#5437) — the always-enforce-workspace decision and its C4 connection-owner edge were initially filed as a deferred follow-up issue (#5440) instead of being part of the plan. The operator corrected it: the ADR/C4 update is intrinsic to the architectural change and must ship with it. No prior plan-time gate required producing (vs reading) an ADR. See knowledge-base/project/learnings/2026-06-16-adr-c4-update-is-a-plan-deliverable-not-a-deferred-issue.md.
[skill-enforced: plan Phase 2.11 + deepen-plan Phase 4.10]
Every plan that introduces a persistent data store (a Hetzner volume, an R2 bucket, a Supabase table, a queue, a cache, a backup target, a log sink) or a new cross-component/network connection MUST emit a ## Encryption Posture section using the field set below. "The provider handles it" and "the provider supports TLS" are not postures — they are the absence of one.
Detection (the plan's Files-to-Create/Edit match, OR the prose names a store class / a new cross-component connection):
\.tf$supabase/migrations/.*\.sql$cloud-init.*\.ya?ml$docker-compose.*\.ya?ml$Required schema (verbatim from plan-issue-templates.md):
at_rest: # per store: mechanism / evidence / defends_against / does_not_defend / disclosed_as / live_verification
in_transit: # per connection: tls / cert_verification (on|off) / does_not_defend / disclosed_as
exception: # present ONLY when mechanism is plaintext-exception OR cert_verification is off — justification / tracking_issue / reevaluate_when / expires_on
Reject conditions (enforced at deepen-plan Phase 4.10 — see deepen-plan/SKILL.md): section missing entirely while detection fires; a required field empty or matching the placeholder ban-list; mechanism or at_rest prose reading "the provider handles it" / "encrypted by default" with no named attestation / "supports TLS"; does_not_defend empty or "none"/"n/a"; a plaintext-exception or cert_verification: off row with no exception block, or one missing tracking_issue / expires_on.
Skip silently when the plan introduces no persistent store and no new cross-component connection — pure UI/docs/dependency-bump plans, or a change confined to an already-provisioned surface.
Why: ADR-140 and knowledge-base/project/plans/2026-07-23-feat-encryption-posture-design-time-default-plan.md (Plan Review Revisions R1-R11) — a new store or connection shipped with no declared encryption posture is undetectable at review time by name-similarity alone (a plaintext hcloud_volume.workspaces reads identically to its LUKS-backed sibling hcloud_volume.workspaces_luks until the device-binding chain is actually walked). Codifying the posture as a plan deliverable, resolved against real code by lint-encryption-posture.py (repo-root scripts/), closes the gap at design time instead of at incident time.
If spec-flow-analyzer was already invoked in Phase 2.5, skip this phase and proceed to Phase 4.
After planning the issue structure, run SpecFlow Analyzer to validate and refine the feature specification. SpecFlow is especially valuable for CI/workflow and infrastructure changes where bash conditional logic can silently drop edge cases that human review misses.
SpecFlow Analyzer Output:
Read plugins/soleur/skills/plan/references/plan-issue-templates.md now to load the three issue templates (MINIMAL, MORE, A LOT). Select the appropriate detail level based on complexity -- simpler is mostly better. Use the template structure from the reference file for the chosen level.
Before finalizing the plan into issues, get one strong-model second opinion at the highest-leverage decision point — but pay only for a curated payload, not the whole session.
Spawn a Task subagent with model: fable (the top advisor tier; if that spawn is rejected because the org lacks Fable access, retry once with model: opus) and a curated prompt — pass only the plan's ## Overview, ## Implementation Phases, and the phase you judge riskiest. Do NOT pass the conversation: a Task subagent receives prompt text only (knowledge-base/project/learnings/best-practices/2026-05-12-task-subagent-prompt-text-only.md), so curation is the token lever that makes this far cheaper than Claude Code's built-in advisor (which re-sends the full transcript, uncached, every call). Prompt shape:
Review this implementation plan's approach and its riskiest phase. Name the one or two changes most likely to prevent rework or a wrong-architecture commit. Be concise — assume you see only what is quoted. PLAN:\n<overview + phases + riskiest phase>
Apply the returned guidance before Step 5. Advisory only — do not block, loop, or re-consult. Skip silently in a resource-constrained run only if the plan is trivially mechanical (single-file, no architecture choice). Rationale + the model: fable upgrade-pin justification: ADR-083 (knowledge-base/engineering/architecture/decisions/ADR-083-scoped-strong-model-consult-at-decision-gates.md).
When the consult and the session model agree the operator's stated direction should change (drop/merge/split/add scope the operator specified), that is a User-Challenge per decision-principles.md (ADR-084), not guidance to silently apply — the operator's direction is the default. Operator-attached: surface it at the post-plan-review confirmation gate with the 5-line frame. Headless (this Step runs inside a Task subagent under one-shot): do NOT ask — persist it to knowledge-base/project/specs/<branch>/decision-challenges.md for ship to render + file as an action-required issue.
Content Formatting:
<details> tagsCross-Referencing:
Code & Examples:
# Good example with syntax highlighting and line references
```ruby
# app/services/user_service.rb:42
def process_user(user)
# Implementation here
end
```
# Collapsible error logs
<details>
<summary>Full error stacktrace</summary>
`Error details here...`
</details>
AI-Era Considerations:
Pre-submission Checklist:
knowledge-base/product/roadmap.md. A deferral without a tracking issue is invisible.*.njk, *.md, README, apps/**), verify the tokens exist. One of: (a) run <tool> --help or <tool> <subcommand> --help locally and paste the relevant line into Research Insights; (b) cite the tool's official command reference URL; (c) annotate the plan snippet with <!-- verified: YYYY-MM-DD source: <url> -->. A plan that embeds a CLI invocation without ONE of the three MUST NOT ship -- silence (omit the snippet) beats fabrication. tsc and Eleventy build do NOT catch fabricated tokens. Why: #1810/#2550 shipped ollama launch claude --model gemma4:31b-cloud -- every token fabricated, caught 8 days later.Filename: Use the date and kebab-case filename from Step 2 Title & Categorization.
knowledge-base/project/plans/YYYY-MM-DD-<type>-<descriptive-name>-plan.md
Examples:
knowledge-base/project/plans/2026-01-15-feat-user-authentication-flow-plan.mdknowledge-base/project/plans/2026-02-03-fix-checkout-race-condition-plan.mdknowledge-base/project/plans/2026-03-10-refactor-api-client-extraction-plan.mdknowledge-base/project/plans/2026-01-15-feat-thing-plan.md (not descriptive - what "thing"?)knowledge-base/project/plans/2026-01-15-feat-new-feature-plan.md (too vague - what feature?)knowledge-base/project/plans/2026-01-15-feat: user auth-plan.md (invalid characters - colon and space)knowledge-base/project/plans/feat-user-auth-plan.md (missing date prefix)After writing the plan file, automatically run /plan_review <plan_file_path> to get feedback from the reviewer panel in parallel:
cpo/cmo (business), ux-design-lead (design), cto (devex) — spawned only when the plan is relevant to the lens, by an independent content scan (see plan-review/SKILL.md). Their findings are frequently taste, so plan-review tags each consolidated decision decisionClass ∈ {mechanical, taste, user-challenge} per decision-principles.md (ADR-084).After review completes, present the consolidated feedback (agreements first, then disagreements), then apply by class:
mechanical. Treat any decision that is unclassified, ambiguous, or sourced from a named-panel (product/market/design/devex) finding as Taste — surface it, never silently auto-apply. (The producer defaults named findings to Taste, but the consumer must not depend on producer-side tagging fidelity: an untagged decision on the prose path routes to surfacing, not to auto-apply.)plan/SKILL.md §Product/UX Gate step 4b, ":330"] — HEADLESS_MODE, no-TTY, /soleur:one-shot, --headless, OR a plan-file-path arg): do NOT pause. Persist each Taste / User-Challenge to knowledge-base/project/specs/<branch>/decision-challenges.md (append), which ship Phase 6 renders into the PR body + files as an action-required issue. This converges with the Step 4.5 decision-challenges.md wiring (:574) onto one artifact.Operator-attached apply gate (Mechanical already applied above):
Why Plan Review runs BEFORE Save Tasks: tasks.md is a derivative breakdown of the plan's phases. If review prompts material changes (phase cuts, deliverable rewrites), generating tasks.md beforehand would immediately go stale and require regeneration. Running review first → applying changes → then deriving tasks ensures tasks.md reflects the final plan as a single source of truth, and the commit below covers both files in one atomic history entry.
After Plan Review has applied any requested changes, generate tasks.md from the finalized plan and commit all artifacts together:
Check if knowledge-base/ exists. If so, run git branch --show-current to get the current branch. If on a feat-* branch, create the spec directory with mkdir -p knowledge-base/project/specs/<branch-name>.
If knowledge-base/ exists and on a feature branch:
Carry forward lane: from spec.md. Extract using the canonical gsub awk pattern (matches skill-security-scan/scripts/run-scan.sh:34):
LANE=$(awk '/^lane:/ { gsub(/^lane:[[:space:]]*"?|"?$/, ""); print; exit }' "knowledge-base/project/specs/feat-${branch_name}/spec.md")
Validate LANE against the 3-value enum (single-domain, cross-domain, procedural). If empty (legacy spec lacks lane:) or invalid (any other value), set LANE=cross-domain and echo to the operator terminal: plan: spec lacks valid lane: — defaulted to cross-domain (fail-closed). Add a one-line note to the plan body: Spec lacks valid lane: — defaulted to cross-domain (TR2 fail-closed). The plan file's YAML frontmatter MUST include lane: <value>.
Generate tasks.md using spec-templates skill template, derived from the finalized (post-review) plan:
Save tasks.md to knowledge-base/project/specs/feat-<name>/tasks.md
Announce: "Tasks saved to knowledge-base/project/specs/feat-<name>/tasks.md. Use skill: soleur:work to implement."
Commit and push plan artifacts:
Both the plan file and tasks.md are committed together so the final plan and its task breakdown land in the same history entry:
git add knowledge-base/project/plans/ knowledge-base/project/specs/feat-<name>/tasks.md
git commit -m "docs: create plan and tasks for feat-<name>"
git push
If the push fails (no network), print a warning but continue.
If knowledge-base/ does NOT exist or not on feature branch:
knowledge-base/project/plans/ only (current behavior)Pipeline detection: If this skill is running inside a Task subagent (the conversation
contains a RETURN CONTRACT section from a Task delegation), skip the exit gate entirely.
Return the plan file path per the return contract. The calling pipeline handles compound
and lifecycle progression.
If invoked directly by the user:
Run skill: soleur:compound to capture learnings from the planning session.
If compound finds nothing to capture, it will skip gracefully — do not block on this.
Verify all plan artifacts are committed and pushed. The Save Tasks section already
committed the plan file and tasks.md. Run git status --short to check for any
remaining uncommitted changes. If found:
git add knowledge-base/project/plans/ knowledge-base/project/specs/feat-<name>/
git commit -m "docs: plan artifacts for feat-<name>"
git push
If there are no uncommitted changes, skip the commit. If push fails (no network), warn and continue.
Display the resume prompt (per AGENTS.md Communication rule). Format:
All artifacts are on disk. Run `/clear` then paste this to resume:
/soleur:work <plan-file-path>
Context: branch <branch>, worktree <worktree-path>, PR #<N>, issue #<N>.
<one-line summary of what was already done>
Replace placeholders with actual values from the session. The user must be able to paste the command and go without re-explaining context.
Resume prompt (MANDATORY): After the display message above, always output a copy-pasteable resume prompt block. This is required by AGENTS.md whenever /clear is mentioned. Format:
Resume prompt (copy-paste after /clear):
/soleur:work <plan-path>. Branch: feat-<name>. Worktree: .worktrees/feat-<name>/. Issue: #<number>. PR: #<pr-number>. Plan reviewed, implementation next.
After plan review, use the AskUserQuestion tool to present these options:
Resume prompt (MANDATORY — AGENTS.md Communication): Before presenting the question, generate a copy-pasteable resume prompt containing: skill to run (/soleur:work), plan file path, branch name, worktree path, PR number, issue number, and a one-line summary of what was already done. Display it in a fenced code block so the user can paste it into a fresh session after /clear. This is the single most important output of the post-generation phase — without it, the user cannot resume in a new session without re-explaining context.
Question: "Plan reviewed and ready at knowledge-base/project/plans/YYYY-MM-DD-<type>-<name>-plan.md. Context is saved to disk — run /clear before /soleur:work for maximum headroom. What would you like to do next?"
Options:
/deepen-plan - Enhance each section with parallel research agents (best practices, performance, UI)soleur:work - Begin implementing this plan locallysoleur:work on remote - Begin implementing in Claude Code on the web (use & to run in background)Based on selection:
open knowledge-base/project/plans/<plan_filename>.md to open the file in the user's default editor/deepen-plan → Call the /deepen-plan command with the plan file path to enhance with researchsoleur:work → Use skill: soleur:work with the plan file pathsoleur:work on remote → Use skill: soleur:work with knowledge-base/project/plans/<plan_filename>.md to start work in background for Claude Code web