---
name: fluent-feature-plan
description: Produce comprehensive feature implementation plans with universal NEW/EXISTING/MODIFIED/REUSED/OOTB classification across all artifacts. Covers rules, workflows, settings, webhooks, GraphQL operations, cross-entity flows, and deployment. Triggers on "plan feature", "feature plan", "plan implementation", "design feature", "plan this feature", "what do I need to build".
user-invocable: true
allowed-tools: Bash, Read, Write, Edit, Glob, Grep
argument-hint: <feature-description> [--profile PROFILE] [--retailer RETAILER_REF]
cursor-tier: manual
---

# Feature Planner

Produce comprehensive, self-contained implementation plans for Fluent Commerce features. A "feature" spans multiple artifacts — rules, workflow rulesets, settings, webhooks, entity types, and deployments. The plan is the contract — an implementer can write code from it without ambiguity.

**This skill is the MANDATORY entry point for any multi-artifact Fluent implementation work.** All downstream implementation skills (`/fluent-rule-scaffold`, `/fluent-workflow-builder`, `/fluent-settings`, `/fluent-build`, `/fluent-module-deploy`) require an approved plan from this skill before they proceed. Each implementation skill has a Pre-flight: Plan Verification step that checks `accounts/<PROFILE>/features/<slug>/status.json` for an approved plan. If no plan exists and the work is multi-artifact, those skills will redirect back here.

**Do NOT use IDE-native plan mechanisms** (e.g., Claude Code's `EnterPlanMode`) as a substitute for this skill. Those mechanisms write to ephemeral locations that are lost between sessions and do not follow the structured 18-section template.

## Pre-flight: Feedback Check

Before starting, check for past learnings from this skill:

1. Check if `accounts/<PROFILE>/feedback/fluent-feature-plan.jsonl` exists
2. If yes, read last 20 records
3. Filter to: FAILURE or USER_CORRECTED outcomes, confidence = CONFIRMED or PROMOTED
4. Extract top 3 relevant learnings — use as internal guidance during execution
5. Do NOT show raw feedback to the user — silently adjust approach based on past issues

## Template Reference

**The full plan template with worked examples and section applicability guide lives at: `PLAN_TEMPLATE.md` (in this skill directory).**

Read that file before producing any plan. It defines:
- The 18-section structure with TOC (including §6.1 Complete Workflow Inventory and §3.6 Workflow Processing Flow)
- Universal Source classification (NEW / EXISTING / MODIFIED / REUSED / OOTB)
- Section applicability guide (which sections are required vs optional)
- Rules classification decision flow
- Diagram requirements (Mermaid stateDiagram-v2, sequenceDiagram, flowchart)
- Plan lifecycle (PENDING → APPROVED → implementation)

**The self-critique protocol lives at: `CRITIQUE_PROTOCOL.md` (in this skill directory).**

Read that file before Phase 4a. It defines:
- The automated adversarial review loop (up to 3 rounds)
- Critic rubric (7 criteria: spec alignment, architecture, classification, ordering, risks, pseudo logic, completeness)
- Critic agent prompt template
- Guardrails (max rounds, convergence, evidence requirement)
- Deliberation log format

> **Mandatory validation:** Before writing any Mermaid diagram to the plan file, validate syntax via `knowledge/mermaid-syntax-rules.md`. Common pitfalls: missing `direction` in flowcharts, spaces in state names for `stateDiagram-v2`, unquoted special characters in labels. Invalid diagrams render as error blocks in markdown viewers.

## When to Use

Use `/fluent-feature-plan` when the work involves **multiple artifacts**:
- A new capability needing workflow changes + new rules + settings + possibly webhooks
- A change spanning multiple entity types (ORDER → FULFILMENT → LOCATION)
- Any implementation request where the scope isn't covered by a single skill

**For single-artifact work**, the individual skill's Planning Gate is sufficient:
- Single new rule → `/fluent-rule-scaffold` Planning Gate
- Single workflow edit → `/fluent-workflow-builder` Planning Gate
- Settings-only change → `/fluent-settings` Planning Gate
- Retrospective feature documentation → `/fluent-feature-explain`
- Scope document decomposition → `/fluent-scope-decompose`

## Progress

Emit this block at each phase transition to show progress:

```
▸ /fluent-feature-plan [1/7]
  ✓ Pre-flight checks       → Discovery & classification
  ○ Rule inventory           ○ Pseudo logic (NEW rules)
  ○ Write plan               ○ Self-critique (automated)
  ○ Present for approval
```

Update the block as each phase completes — mark completed phases with `✓`, the active phase with `→`, and remaining phases with `○`. Replace `[1/7]` with the current phase number.

## Pre-flight: Project Knowledge Check

Check for project-specific knowledge that should inform feature planning:

1. Check if `accounts/<PROFILE>/knowledge/` exists
2. If yes, read it and find files where `relevant-skills` includes `fluent-feature-plan`
   **Account knowledge:** Read from `accounts/<PROFILE>/knowledge/` when `FLUENT_PROFILE` is set. These contain project-specific conventions.

3. Read matching knowledge files — typically:
   - `knowledge/platform/domain-model.md` — use for entity edges, cross-domain relationships, GraphQL connections
   - `accounts/<PROFILE>/knowledge/naming-conventions.md` — use for all naming in the plan
   - `accounts/<PROFILE>/knowledge/coding-standards.md` — use for architecture decisions and conventions
   - `accounts/<PROFILE>/knowledge/client/business-rules.md` — use for constraints, routing, exception handling
   - `accounts/<PROFILE>/knowledge/client/data-model.md` — use for entity types, attribute schemas
   - `accounts/<PROFILE>/knowledge/client/integrations.md` — use for integration touchpoints
   - `knowledge/platform/rule-development-contract.md` — **MANDATORY**: annotation contract (`@ParamString` vs `@EventAttribute`), reading patterns, enhancement protocol for Rules Inventory section
   - `knowledge/platform/create-order-reference.md` — createOrder/createReturnOrder/createFulfilment input schemas, fulfilmentChoice wiring, ORDER::MULTI patterns. Use when planning features that create or modify orders.
4. If `accounts/<PROFILE>/memory/index.md` exists, read the top account-specific gotchas and apply them silently while planning.
5. Also check `accounts/<PROFILE>/knowledge/templates/plan-addendum.md` — if it exists, append its sections to the plan
6. Apply knowledge throughout the plan — naming, constraints, architecture patterns. Do NOT show raw knowledge to user.

## Pre-flight: Requirements Verification (MANDATORY)

**A Business Spec is MANDATORY before feature planning.** The agent MUST NOT judge whether requirements are "clear enough" to skip the spec — that decision belongs exclusively to the end user.

### Step 1: Check for approved Business Spec

```bash
# Check feature directories for an approved spec
ls accounts/<PROFILE>/features/*/spec.md
# Or check status.json for spec approval state
cat accounts/<PROFILE>/features/<slug>/status.json   # look for "spec": "APPROVED"
```

If an **APPROVED** spec exists that matches the requested feature (check `status.json` for `"spec": "APPROVED"`):
- Read the spec file at `features/<slug>/spec.md`
- Confirm it covers the feature scope
- Check the spec's Completeness Score (Section 12 in the spec). If score < 75%, warn: *"Business Spec completeness is below 75%. Specs below this threshold may cause planning gaps. Run `/fluent-use-case-discover` Phase 10 gap analysis to resolve, or proceed with `--force`."*
- **Check for phases.md** — if `features/<slug>/phases.md` exists and `status.json` has `phasesApproved: true`, scope this plan to the current phase only:
  - Read `currentPhase` from `status.json` (defaults to 1 if absent)
  - Include ONLY artifacts listed in the current phase's Artifacts table
  - Mark artifacts from future phases as "DEFERRED (Phase N)" in the plan
  - Note phase dependencies in §1 Business Context
- Proceed to Phase 1 using the spec (and phases.md if present) as primary input
- Reference the spec file path in the plan's §1 Business Context
- If the spec has §5a (User Journey Diagrams), carry those into Plan §3 Architecture & Diagrams — refine from business-level to technical-level (add workflow states, GraphQL operations, event names). The spec diagrams become the "before" view; the plan diagrams add implementation detail

### Step 2: No approved spec → BLOCKED

If no approved spec exists at `features/<slug>/spec.md`:
- **STOP.** Do not proceed to Phase 1.
- Inform the user: *"No approved Business Spec found. A spec is required before feature planning. I recommend running `/fluent-use-case-discover` to produce a structured Business Spec first. If you want to skip the spec step and go straight to planning, say 'skip spec'."*
- **IMPORTANT:** Always recommend the spec path. Present it as the default. The skip option is mentioned so the user knows it's available, but the recommendation is always to write the spec.
- Invoke `/fluent-use-case-discover` to produce a spec
- Resume `/fluent-feature-plan` only after the spec is **APPROVED**
- Resume command: `/fluent-feature-plan --feature <slug>`

### User override (explicit only)

The user can bypass this check ONLY by explicitly saying: "skip spec", "skip use case", "go straight to plan", or similar **clear, unambiguous instruction**. The agent must NEVER infer a skip from vague statements or from judging that requirements "look structured enough".

When the user explicitly overrides:
1. Log `Pre-flight: Requirements Check SKIPPED (user override — no approved spec)` in the plan header
2. Warn: *"Proceeding without a Business Spec. The plan may contain assumptions that require mid-implementation revision. Consider writing a spec after the plan if gaps emerge."*
3. Proceed to Phase 1

**What does NOT count as a user override:**
- The user providing a one-sentence feature description
- The user listing some requirements conversationally
- The user saying "this is straightforward" or "it's simple"
- The agent deciding the request is "clear enough"

Only an **explicit instruction to skip** the spec step counts.

## Slug Resolution

If the feature directory doesn't exist yet, use the slug auto-suggestion protocol from `/fluent-use-case-discover`. The slug should have been established during spec creation; if not, apply the same rules here:
1. Derive from feature/spec title → kebab-case → max 4 words → no dates → no skill prefixes
2. Remove filler words (the, a, an, for, with, and)
3. Check if `accounts/<PROFILE>/features/<slug>/` already exists
4. If exists, reuse the existing slug
5. If new, present to user for confirmation before creating directory

### Decision summary

```
User requests feature
        │
        ▼
┌───────────────────────────┐
│ 1. Approved spec in       │──YES──▶ Proceed to Phase 1
│    features/<slug>/       │
│    spec.md?               │
├───────────────────────────┤
│ 2. No spec exists         │──────▶ BLOCKED
│                           │        Recommend: /fluent-use-case-discover
│                           │        Mention skip option to user
├───────────────────────────┤
│ 3. User explicitly says   │──YES──▶ Proceed to Phase 1 (log override + warn)
│    "skip spec"?           │
└───────────────────────────┘

NEVER auto-proceed without a spec. NEVER judge requirements as "sufficient".
The decision to skip belongs to the end user, not the agent.
```

## Handoff Protocol

### Mandatory approval gate before implementation

After writing the plan to `features/<slug>/plan.md`, the agent MUST:
1. Present the plan to the user for review
2. **STOP and WAIT** for explicit user approval ("approved", "go ahead", "looks good", "do it")
3. Only after user approval: update `status.json` to `plan: "APPROVED"` and emit `-> NEXT`
4. If the user asks questions or requests changes → answer/apply changes, keep waiting for approval
5. **NEVER auto-advance to implementation skills** — the approval gate is mandatory

### Signals emitted by this skill

| Signal | Condition | Example |
|--------|-----------|---------|
| `-> REVIEW: <path>` | Plan written, awaiting user review | `-> REVIEW: accounts/MY_PROFILE/features/curbside/plan.md` |
| `-> READY: <path>` | Plan reviewed AND approved by user | `-> READY: accounts/MY_PROFILE/features/curbside/plan.md` |
| `-> NEXT: /fluent-<skill>` | First implementation skill from plan (only after READY) | `-> NEXT: /fluent-rule-scaffold` |
| `-> BLOCKED: <reason>` | Requirements insufficient | `-> BLOCKED: PREREQ_MISSING — No approved spec. Run /fluent-use-case-discover` |

### Human-Friendly Translation

When presenting handoff signals to the user, translate agent jargon into plain language:

| Raw Signal | User-Facing Translation |
|------------|------------------------|
| `-> NEXT: /fluent-rule-scaffold` | "Plan approved. Next step: scaffold the Java rules. Shall I proceed?" |
| `-> BLOCKED: Module not found` | "I can't build the workflow yet — the Java module needs to be created first. Want me to scaffold it?" |
| `-> READY: plan.md` | "The feature plan is ready for your review." |
| `-> REVIEW: plan.md` | "I've written the implementation plan. Please review it and let me know if it looks good." |
| `-> SKIP: No settings` | "No settings changes needed for this feature — moving on." |

**Rule:** Raw `->` signals should NEVER be shown to the user verbatim. Always wrap them in a natural-language sentence. The signals exist for agent-to-agent coordination; the user sees the translated version.

### Error codes

| Code | Condition | Recovery |
|------|-----------|----------|
| `PREREQ_MISSING` | No approved Business Spec (spec.md with status APPROVED) | Run `/fluent-use-case-discover` to produce a spec. Agent cannot bypass — only user can say "skip spec" |
| `SPEC_REQUIRED` | Agent attempted to skip spec without user override | Inform user: spec is mandatory, recommend `/fluent-use-case-discover`, mention skip option |
| `VALIDATION_FAILED` | Plan template structure invalid or incomplete | Fix the plan sections flagged as incomplete |
| `USER_OVERRIDE` | User explicitly said "skip spec" | Logged in plan header; proceed with assumptions |
| `APPROVAL_PENDING` | Plan written but not yet approved by user | Wait for user review and explicit approval before proceeding |

## Plan Revision Handling

When a user requests plan changes during implementation (feature status is `IN_PROGRESS`):

### Triggering a revision

If the user says "change the plan", "update the plan", or requests modifications to an approved plan:

1. **Read current plan** at `features/<slug>/plan.md`
2. **Save current version** as `features/<slug>/plan.v<N>.md` where N = current `planRevision`
3. **Apply changes** to `plan.md`, marking revised sections with:
   ```
   > **REVISED in v<N+1>:** <summary of what changed and why>
   ```
4. **Update status.json:**
   - `status`: `"PLANNING"` (regressed from IN_PROGRESS)
   - `planRevision`: increment by 1
   - `plan`: `"DRAFT"` (pending re-approval)
5. **Present revised plan** to user for review
6. **WAIT for re-approval** — same mandatory gate as initial plan approval
7. After approval: `status` → `"APPROVED"`, `plan` → `"APPROVED"`

### Impact assessment

After a plan revision, the agent MUST assess impact on already-completed work:

1. List which plan sections changed (§ numbers)
2. Cross-reference against completed implementation:
   - Scaffolded rules → check if rule logic, parameters, or entity types changed
   - Modified workflows → check if rulesets, statuses, or transitions changed
   - Created settings → check if keys, values, or scopes changed
3. Present impact summary: "These sections changed: §7, §9. Scaffolded rule X may need updating because [reason]."
4. Let the user decide which completed artifacts to update — do NOT automatically modify scaffolded code

### Revision history

All plan versions are preserved in the feature directory:
```
features/<slug>/
├── plan.md          ← current (latest) version
├── plan.v1.md       ← original approved version
├── plan.v2.md       ← first revision
└── status.json      ← planRevision: 3
```

## Phase 1: Discovery

Before writing a plan, gather evidence to classify every artifact.

### 1.1 OOTB Rule Search

```
plugin.list name="<keyword>"     # e.g., "Fulfilment", "Pickup", "Webhook"
plugin.list name="SendEvent"     # standard event forwarding rules
plugin.list compact=true         # full inventory (compact payload)
```

Determine which parts of the feature can use OOTB rules vs. need custom. For every rule the feature needs, try to find an OOTB match FIRST.

### 1.2 Existing Workflows

```bash
# Check what's deployed
fluent workflow list -p <PROFILE> -r <RETAILER_REF>
# Download if not local
fluent workflow download -p <PROFILE> -r <RETAILER_REF> -w all -o accounts/<PROFILE>/workflows/<RETAILER_REF>/
# If CLI returns 401 or on Windows, use MCP: workflow.list + workflow.get for each
```

Read workflow JSONs to map existing statuses, rulesets, and triggers. Identify which workflows need modification and their current versions.

**For §6.1 Complete Workflow Inventory:** Parse each modified workflow's JSON to extract the complete ruleset list — entity type, subtype, trigger event, trigger status, and rule names. This feeds directly into the §6.1 table and §3.6 Workflow Processing Flow diagram. Don't rely on the implementer to manually enumerate rulesets.

### 1.3 Existing Settings

```bash
# Via MCP
graphql.query: settings(first: 100) filtered by name pattern
# Or via CLI
fluent setting list -p <PROFILE> -r <RETAILER_REF> -n "*keyword*"
```

Find settings that already exist vs. need creation.

### 1.4 Local Source Analysis

Search `accounts/<PROFILE>/SOURCE/` for:
- `backend/*/module.json` — rule registrations (Java Maven plugin repos)
- `frontend/*/package.json` — Mystique SDK component projects
- `source-map.json` — if `/fluent-custom-code` was run
- `behavior-map.md` — rule behavior descriptions
- Existing Java rule classes under `backend/` for reusable patterns

### 1.5 Module Identification

Identify the target module for new custom rules:
- Search `accounts/<PROFILE>/SOURCE/backend/` for existing Java modules
- Search `accounts/<PROFILE>/SOURCE/frontend/` for existing SDK component projects
- If no module exists, flag `/fluent-module-scaffold` as a prerequisite task

### 1.6 OOTB UI Component Search (when Spec §9a exists)

Mirror of §1.1 for frontend. For every UI element the feature needs, check if an OOTB Mystique component already provides it:

1. **Search OOTB catalog:** Check deployed manifest fragments for existing `fc.*` component aliases (list, card, quantity list, barcode filter, page wizard, tabs)
2. **Check reference plugin source:** Search `accounts/<PROFILE>/SOURCE/frontend/` and workspace reference source (Store plugin WavePickList.tsx, Returns plugin) for `ComponentRegistry.get('fc.*')` usage patterns
3. **Classify each UI element:**
   - **OOTB** — existing component fits as-is → use directly in manifest, no custom code
   - **WRAP** — OOTB component exists but needs augmentation → thin wrapper via `ComponentRegistry.get()` with settings-driven props
   - **NEW** — no OOTB equivalent → build custom (document why in plan)

**Common OOTB matches to check first:**

| UI Need | OOTB Component | Notes |
|---------|---------------|-------|
| Item list with quantities | `fc.quantity.list` (QuantityList) | Includes scanner (BarcodeFilter) natively |
| Data table / list view | `fc.list` | Columns, pagination, filtering |
| Entity detail card | `fc.card.attribute` | Attribute display with labels |
| Tabbed layout | `fc.tabs` | Tab labels from `layouts[]` |
| Multi-step form | `fc.page.wizard` | Pick/pack/dispatch flows |
| Barcode scanner | Built into `fc.quantity.list` | Do NOT build a separate scanner component |

**Anti-pattern:** Planning custom sub-components (e.g., `fc.pick.scanner`, `fc.pick.itemList`) when OOTB components already provide that behavior. The correct plan wraps OOTB components, only adding custom code for the delta logic (data fetching, validation, settings-driven config).

### 1.7 Existing Manifest Discovery (when Spec §9a exists)

If the approved spec includes §9a (UI / Frontend Requirements), discover existing manifests before planning:

1. Query existing manifest settings: `settings(name: "fc.mystique.manifest.oms%", first: 50)`
2. For each fragment the feature will modify:
   - Download current baseline from platform CDN: `https://fluent.apps.fluentcommerce.com/_plugins/oms/manifests/{settingName}.json`
   - Check if an ACCOUNT-level override already exists (via settings query)
   - If an override exists, download it and compare against baseline to understand existing customizations
   - Note which routes and components are already present — avoid duplicating existing pages
3. This discovery feeds into Plan §10 (UI / Manifest Artifacts). Without it, the plan may propose creating pages that already exist or modifying fragments that have undocumented customizations.

## Phase 2: Classification

For EVERY artifact the feature touches, apply one of these labels:

| Label | Meaning | Required Detail in Plan |
|-------|---------|------------------------|
| **NEW** | Doesn't exist yet, must be created | Full pseudo logic / value shape / trigger spec |
| **EXISTING** | Already deployed, no modification needed | State current value, confirm no change |
| **MODIFIED** | Already exists but needs changes | Show before → after diff |
| **REUSED** | Pattern exists in codebase, copy the approach | Reference source file/rule |
| **OOTB** | Platform rule, use with configuration only | State which props/values to configure |

This applies universally across ALL plan sections — rules, rulesets, statuses, settings, webhooks, GraphQL operations, cross-entity impacts, files.

## Phase 3: Pseudo Logic for NEW Rules

For every **NEW** rule, write pseudo logic that is:
- **Unambiguous** — a developer can implement from it without asking questions
- **Shows data flow**: READ → VALIDATE → QUERY → BUILD → MUTATE → LOG
- **Shows branching**: IF/ELSE with error paths and thrown exceptions
- **References specific APIs**: `DynamicUtils.queryList()`, `SettingUtils.getSettingByRef()`, `JsonUtils.getJsonPath()`
- **Stays at design level** — NOT Java code, but precise enough to translate directly

```
FUNCTION run(context):
    order = context.getEntity()
    event = context.getEvent()

    // 1. Extract required fields
    pickupLocationRef = extractFromPath(event, props.pickupLocationPath)
    IF pickupLocationRef IS NULL:
        THROW "Pickup location ref required but null at path: {pickupLocationPath}"

    // 2. Fetch order items
    items = DynamicUtils.queryList(context, "items", OrderItem.class, null)
    IF items IS EMPTY:
        THROW "Order has no items — cannot create fulfilment"

    // 3. Read config from setting
    config = SettingUtils.getSettingByRef(context, props.configSettingName)
    maxPickupHours = config.lobValue.maxPickupHours

    // 4. Validate
    IF requestedPickupTime > order.createdOn + maxPickupHours hours:
        THROW "Pickup window expired"

    // 5. Build and mutate
    fulfilmentRef = "CURB-{order.ref}-{pickupLocationRef}"
    DynamicUtils.create(context, CreateFulfilmentInput { ref, type, items, attributes })

    // 6. Log
    context.addLog("Created curbside fulfilment {fulfilmentRef}")
```

**For OOTB rules**: just state the configuration props to set in the ruleset — no pseudo logic needed.

**For EXISTING rules**: confirm "no code changes" or describe the modification.

## Phase 4: Plan Writing

**Write to:** `accounts/<PROFILE>/features/<slug>/plan.md`

Follow the 18-section template from `PLAN_TEMPLATE.md` (sibling file). Validate all Mermaid diagram blocks per `knowledge/mermaid-syntax-rules.md` before writing the plan file. Key per-section notes:

> **Diagram validation:** All Mermaid blocks must pass `knowledge/mermaid-syntax-rules.md` rules before writing to the plan file.

| Section | Source-Column Required | Key Content |
|---------|----------------------|-------------|
| §4 Workflows | Yes (NEW/EXISTING/MODIFIED) | Workflow name, current version, action |
| §5 Statuses | Yes | Status, entity type, which ruleset adds it |
| §6 Rulesets | Yes | Trigger event, from/to status, ordered rule list with source annotations |
| §6.1 Complete Workflow Inventory | Yes (when modifying) | ALL rulesets in each modified workflow with NEW/EXISTING/MODIFIED annotations |
| §3.6 Workflow Processing Flow | Yes (when modifying) | Flowchart: complete status→ruleset→status chain, NEW/MODIFIED highlighted |
| §7 Rules Inventory | Yes | ALL rules for the feature with source + purpose |
| §8 Detailed Design | For NEW rules only | Class, params table, pseudo logic, GraphQL ops |
| §9 Settings | Yes | Context, contextId, value type, JSON example for NEW |
| §10 UI / Manifest Artifacts | Yes (when UI work) | Routes, component hierarchy, data queries, fragment changes, i18n keys. Maps from Spec §9a |
| §11 Webhooks | Yes | Setting name, method, payload shape |
| §12 Scheduled Events | Yes | Event name, delay, purpose |
| §13 GraphQL Ops | Yes (NEW/REUSED) | Query/mutation, root field, selected paths |
| §14 Cross-Entity | Yes | Source → target entity, mechanism |
| §15 Files | Yes (NEW/MODIFIED) | All created/modified files |

## Phase 4a: Self-Critique Loop (Automated)

**The full protocol, rubric, critic prompts, runtime adaptation table, guardrails, and deliberation log format live in `CRITIQUE_PROTOCOL.md`. Read that file and follow it exactly.**

After writing the initial plan, refine it through automated adversarial review before presenting to the user for approval. This phase is fully automated — no user interaction. All discovery (Phases 1–3) is complete.

### Orchestration Steps (Claude Code)

1. **Read** `CRITIQUE_PROTOCOL.md` (sibling file)
2. **Pre-Critique Feedback Check** — Read `accounts/<PROFILE>/feedback/fluent-feature-plan.jsonl` (last 10 records). Extract top 3 pitfalls from FAILURE/USER_CORRECTED outcomes. Build `{feedback_pitfalls}` string (empty if no records).
3. **Assess complexity** — Count entity types in §4, workflows in §6, NEW rules in §8. If HIGH complexity (5+ entities OR 3+ workflows OR 10+ NEW rules), set `maxRounds=5` and enable multi-critic. Otherwise `maxRounds=3`, single critic.
4. **Build Round 1 critic prompt** — From CRITIQUE_PROTOCOL.md template, inject: `{plan_path}`, `{spec_path}`, knowledge file paths (if they exist), `{feedback_pitfalls}`.
5. **Spawn critic(s):**
   - **Standard:** `Agent(subagent_type: "general-purpose", name: "plan-critic-r1", prompt: <round1_prompt>)`
   - **Multi-critic (HIGH):** Spawn TWO agents in parallel — `plan-arch-critic-r1` (CR-1,2,4) and `plan-impl-critic-r1` (CR-3,5,6,7). Merge findings.
6. **Evaluate findings** — For each finding, apply verdict: ACCEPTED (apply fix to plan) / REJECTED (log reason) / DEFERRED (log for user).
7. **Convergence check** — If 0 new CRITICAL/HIGH findings → exit loop. Otherwise continue.
8. **Rounds 2+** — Build round N prompt from CRITIQUE_PROTOCOL.md template, inject prior deliberation context. Spawn critic(s) again. Apply same evaluation. If a CRITICAL finding is rejected twice with new evidence both times → mark ESCALATED.
9. **Append deliberation log** to plan file (after §19, before Revision Log).
10. **Build user-facing summary** — Key changes, deferred items, escalated items. Present in Phase 5.

### Revision Mode

When `planRevision > 1` in `status.json`, re-run the critique on CHANGED sections only. Max 2 rounds. Critic receives the diff + original deliberation log. Append as `### Revision Round N` in the deliberation log.

**After Phase 4a completes**, continue to Phase 4b (if §10 has UI work) or Phase 5.

## Phase 4b: UI Mock Review _(conditional — when §10 exists)_

When the plan includes §10 (UI / Manifest Artifacts), build a visual mock before presenting the plan for approval. This gives the user a concrete picture of what they're approving.

**Trigger:** Plan has §10 AND at least one UI change (custom SDK component, new column, new card, new page).

**Skip when:** Pure backend feature, or user says "skip mock".

### Three-Tier Mock Approach

Pick the highest-fidelity tier available. Tier 1 is always preferred when the environment is accessible.

| Tier | Approach | Fidelity | Requires | Best For |
|------|----------|----------|----------|----------|
| **1** | **Live UI Injection** | Perfect | Logged-in browser session | Manifest changes (columns, cards, tabs), showing real data |
| **2** | **MUI CDN Mock** | Very high | Nothing (offline) | Custom SDK components, complex visualizations, before/after comparisons |
| **3** | **ASCII Wireframe** | Low | Nothing | Quick layout sketches, early discussion |

---

### Tier 1: Live UI Injection _(primary — use when environment is accessible)_

Navigate to the real Fluent OMS/Store app, take a "Before" screenshot, inject DOM changes + annotations, take an "After" screenshot. The theme, fonts, spacing, and data are all 100% real.

**Steps:**

1. **Navigate to the target page** — Use Chrome DevTools MCP:
   ```
   navigate_page → https://<account>.<env>.apps.engineering.fluentcommerce.com/oms
   wait_for → page-specific marker (e.g., "Orders", table data)
   ```

2. **Take "Before" screenshot**:
   ```
   take_screenshot → features/<slug>/assets/<page>-before.png
   ```

3. **Inject DOM changes** — Use `evaluate_script` to modify the live page:
   ```javascript
   // Example: Add a "Channel" column to the order list table
   evaluate_script → () => {
     // 1. Find the table header row
     const headerRow = document.querySelector('table thead tr');
     // 2. Insert new column header with annotation styling
     const th = document.createElement('th');
     th.innerHTML = '<span style="position:relative">Channel <span style="...new-badge...">NEW</span></span>';
     th.style.cssText = 'background: rgba(26,115,232,0.06); border-left: 2px solid #1a73e8; ...';
     headerRow.insertBefore(th, headerRow.lastElementChild);
     // 3. Insert data cells in each body row
     document.querySelectorAll('table tbody tr').forEach(row => {
       const td = document.createElement('td');
       td.innerHTML = '<span class="MuiChip-root" style="...">WEB</span>';
       td.style.cssText = 'background: rgba(26,115,232,0.06); border-left: 2px solid #1a73e8;';
       row.insertBefore(td, row.lastElementChild);
     });
     // 4. Add annotation callout
     const callout = document.createElement('div');
     callout.innerHTML = '<strong>NEW column</strong> — reads channel from order attributes';
     callout.style.cssText = 'position:absolute; background:#fff8e1; border:1.5px solid #ffb300; ...';
     document.querySelector('table').parentElement.prepend(callout);
   }
   ```

4. **Add annotation CSS** — Inject annotation styles into the page:
   ```javascript
   evaluate_script → () => {
     const style = document.createElement('style');
     style.textContent = `
       @keyframes pulseGlow {
         0%, 100% { box-shadow: 0 0 4px rgba(26,115,232,0.3); }
         50% { box-shadow: 0 0 12px rgba(26,115,232,0.6), 0 0 24px rgba(26,115,232,0.2); }
       }
       .mock-glow { animation: pulseGlow 2s ease-in-out infinite; border: 2px solid #1a73e8 !important; border-radius: 8px !important; }
       .mock-new-highlight { background: rgba(26,115,232,0.06) !important; border-left: 2px solid #1a73e8 !important; }
       .mock-badge { display:inline-block; background:#1a73e8; color:white; font-size:9px; font-weight:700; padding:2px 6px; border-radius:8px; margin-left:8px; vertical-align:middle; text-transform:none; }
     `;
     document.head.appendChild(style);
   }
   ```

5. **Take "After" screenshot**:
   ```
   take_screenshot → features/<slug>/assets/<page>-after.png
   take_screenshot fullPage=true → features/<slug>/assets/<page>-after-full.png
   ```

6. **Reload to reset** — `evaluate_script → () => { location.reload(); }` restores the original page (injection is DOM-only, non-persistent).

**Why Tier 1 is best:**
- Pixel-perfect — IS the real app with the real theme
- Real data from the environment (actual orders, real statuses, live attributes)
- Shows exactly how the change will look in production context
- No CSS approximation — the entire Material-UI theme, sidebar, topbar, cards are all genuine
- Non-destructive — DOM injection is temporary, reload clears all changes

**When Tier 1 is not available:** If the environment requires login, the agent should auto-login using stored credentials (see Auto-Login below), ask the user to log in, or fall back to Tier 2.

**Tier 1 Auto-Login:** Read credentials from the Fluent profile and fill the browser login form:
1. Read `~/.fluentcommerce/<PROFILE>/profile.json` → get `user` field
2. Read `~/.fluentcommerce/<PROFILE>/user.<username>.json` → get `username` and `password`
3. Navigate to `https://<account>.<env>.apps.engineering.fluentcommerce.com/<app>`
4. Use `fill_form` or `fill` to enter username and password into the login form
5. Click the login button
6. Wait for the app to load (look for "SUMMARY", "Orders", or similar markers)

**OMS URL patterns:**
- Order list: `#/orders` or `#orders`
- Order detail: `#/orders/{id}/{retailerId}/{ref}` (all three segments required)
- Navigate to detail via clicking from list is often more reliable than direct URL

---

### Tier 2: MUI CDN Mock _(fallback — offline or custom SDK components)_

Build a self-contained HTML file that loads the same React + MUI versions as Fluent OMS from CDN. Best for custom SDK components that don't exist in the app yet.

**Steps:**

1. **Build HTML mock** — Create `features/<slug>/assets/<component>-mock.html`:
   - Load **real MUI components from CDN** (same versions as Fluent OMS SDK):
     ```html
     <script crossorigin src="https://unpkg.com/react@17.0.2/umd/react.development.js"></script>
     <script crossorigin src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js"></script>
     <script crossorigin src="https://unpkg.com/@material-ui/core@4.12.4/umd/material-ui.development.js"></script>
     <script crossorigin src="https://unpkg.com/@babel/standalone@7.24.0/babel.min.js"></script>
     <link href="https://fonts.googleapis.com/css2?family=Lato:wght@300;400;700;900&display=swap" rel="stylesheet">
     <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
     ```
   - Write React components in `<script type="text/babel">` blocks using MUI components
   - Simulate the target app shell (sidebar, topbar, breadcrumbs, tabs)
   - Render with real or representative data from the environment
   - If reusable, show multiple use cases (different entity types, data volumes)

2. **For Before/After comparisons**, use annotation conventions:
   - **Blue highlight**: `background: rgba(26,115,232,0.06); border-left: 2px solid #1a73e8`
   - **"NEW" badge**: Blue pill (`background: #1a73e8; color: white; font-size: 9px; border-radius: 8px`)
   - **Pulsing glow**: CSS `@keyframes pulseGlow` on new element headers
   - **Yellow callout**: `background: #fff8e1; border: 1.5px solid #ffb300` with explanation text
   - **Annotation Legend**: Section at bottom explaining all visual markers
   - Stack Before/After vertically (`flex-direction: column`) for full-width tables

3. **Render and capture** — Use Chrome DevTools MCP:
   ```
   new_page → file:///path/to/mock.html
   wait_for → text marker confirming MUI rendered
   resize_page → 1280x900
   take_screenshot fullPage=true → features/<slug>/assets/<component>-fullpage.png
   ```

**Why Tier 2 still works well:** React 17 + MUI 4.12 from CDN = identical component rendering to the real OMS SDK. Same Paper elevations, Chip styles, Table density, Icon set, font weights.

---

### Tier 3: ASCII Wireframe _(quick sketch)_

For early discussion or simple layout pages. Inline in the plan, no file needed.

```
┌─────────────────────────────────────────┐
│ Order Detail                            │
├────────────────┬────────────────────────┤
│ Summary Card   │ Status Timeline [NEW]  │
│ ref, type, $   │ ● CREATED  → 10:15    │
│                │ ● BOOKED   → 10:22    │
│                │ ● COMPLETE → 14:30    │
├────────────────┴────────────────────────┤
│ Fulfilments Table                       │
└─────────────────────────────────────────┘
```

---

### Annotation Conventions (shared across all tiers)

These visual markers communicate what's NEW vs existing:

| Marker | CSS | Purpose |
|--------|-----|---------|
| **Pulsing glow border** | `@keyframes pulseGlow { 50% { box-shadow: 0 0 14px rgba(26,115,232,0.5) } }` + `border: 2px solid #1a73e8` | Wraps the entire NEW component/card to draw attention |
| **"NEW" badge** | `background: #1a73e8; color: white; font-size: 9px; padding: 2px 6px; border-radius: 8px` | Inline badge on the component heading |
| **Blue highlight** | `background: rgba(26,115,232,0.06); border-left: 2px solid #1a73e8` | Marks NEW columns, cells within existing components |
| **Thought bubble** | `background: #fff8e1; border: 1.5px solid #ffb300; border-radius: 10px` with upward-pointing CSS arrow | Implementation note OUTSIDE the component |

**Critical rule — annotations must be OUTSIDE the injected component:**

Callouts and implementation notes must NOT be inside the new UI component. They must be separate DOM elements (thought bubbles) positioned below or beside the component with a CSS arrow pointing to it. This prevents confusion between what's the actual UI and what's an explanation note.

**Thought bubble pattern (Tier 1 injection):**
```javascript
// 1. Inject the clean component (matching OMS native styling)
// 2. Below the component, add a separate thought bubble:
`<div style="position:relative;margin-top:6px;margin-left:30px;">
  <!-- Up-pointing arrow -->
  <div style="position:absolute;top:-8px;left:40px;">
    <div style="width:0;height:0;border-left:10px solid transparent;
      border-right:10px solid transparent;border-bottom:10px solid #ffb300;"></div>
  </div>
  <!-- Bubble -->
  <div style="background:#fff8e1;border:1.5px solid #ffb300;border-radius:10px;
    padding:10px 14px;font-family:Lato,sans-serif;font-size:11px;color:#5d4037;">
    <strong style="color:#e65100;">Custom SDK Component</strong> —
    Reads <code>fcOrderStatusHistory</code> attribute. Registered as
    <code>company.orderStatusTimeline</code> via ComponentRegistry.
  </div>
</div>`
```

**OMS native styling reference:** See `knowledge/frontend/mystique-patterns.md` § "OMS DOM Structure and Styling Reference" for exact font (Lato), card hierarchy, heading styles, and injection best practices.

### Animated GIF (Before → After)

Create animated GIFs to show the transition from current state to proposed changes. Embed in plans, dashboards, and feature docs.

**Method: Multi-screenshot → GIF** (most reliable):
1. Take "Before" screenshot (clean state)
2. Inject DOM changes + annotations
3. Take "After" screenshot (with glow, badges, highlights)
4. Stitch into animated GIF via ImageMagick:
   ```bash
   # 2-second delay per frame, loop forever
   magick convert -delay 200 -loop 0 \
     features/<slug>/assets/<page>-before.png \
     features/<slug>/assets/<page>-after.png \
     features/<slug>/assets/<page>-transition.gif
   ```
   If ImageMagick not available, use ffmpeg with concat demuxer:
   ```bash
   # Create frame list file
   printf "file '%s'\nduration 2\nfile '%s'\nduration 2\n" \
     "mocks/<page>-before.png" "mocks/<page>-after.png" > /tmp/gif-frames.txt
   ffmpeg -f concat -safe 0 -i /tmp/gif-frames.txt -vf "scale=1280:-1" -loop 0 mocks/<page>-transition.gif
   ```

**Method: CSS Animation Capture** (for richer transitions):
1. Inject changes with CSS transitions (slide-in column, fade-in glow)
2. Capture multiple screenshots at intervals via `take_screenshot` during the animation
3. Stitch frames into GIF using ImageMagick or ffmpeg concat

### Mock file conventions

```
features/<slug>/assets/
├── <page>-before.png              ← Tier 1: screenshot of real app before injection
├── <page>-after.png               ← Tier 1: screenshot after DOM injection + annotations
├── <page>-transition.gif          ← Animated GIF: Before → After (2s per frame)
├── <component>-mock.html          ← Tier 2: self-contained HTML with React 17 + MUI 4.12 from CDN
├── <component>-fullpage.png       ← Tier 2: full-page screenshot of mock
├── <component>-detail.png         ← Tier 2: viewport screenshot of specific section
└── <component>-<variant>.png      ← Additional variant screenshots
```

### Embed in plan and dashboard

Screenshots and GIFs in §10.8:
```markdown
**Before (current OMS order list):**
![Before](assets/order-list-before.png)

**After (with Channel column injected + annotations):**
![After](assets/order-list-after.png)

**Animated transition:**
![Before → After](assets/order-list-transition.gif)
```

In the feature dashboard, mock images are embedded via relative paths from the plan file's directory. The dashboard generator resolves `mocks/` paths relative to `features/<slug>/`.

### Present to user

Show mock screenshots inline. Ask:
- Does the visual design match expectations?
- Any layout or data display changes needed?
- If reusable, do the entity-type variations look right?

Iterate if needed — Tier 1: re-inject, Tier 2: edit HTML and re-render.

## Phase 5: Approval

1. Set `Status: PENDING`, `Revision: 1`
2. Present the full plan content to the user
3. Wait for explicit approval before any implementation
4. On approval: update `Status: APPROVED`, `Approved by: user`
5. On rejection: increment `Revision`, revise, re-present
6. On "just do it": write `Status: APPROVED (auto-skip)`, `Approved by: user (gate skipped)`, proceed

## Phase 6: Handoff to Implementation Skills

After approval, the plan becomes the source of truth. Each skill reads its relevant sections:

| Artifact Type | Implementation Skill | Plan Sections |
|--------------|---------------------|---------------|
| New custom rules | `/fluent-rule-scaffold` | §7 Rules, §8 Detailed Design |
| Workflow changes | `/fluent-workflow-builder` | §4 Workflows, §5 Statuses, §6 Rulesets |
| Settings | `/fluent-settings` | §9 Settings |
| Module validation | `/fluent-module-validate` | §18 Deployment (step 1) |
| Module build | `/fluent-build` | §18 Deployment (step 2) |
| Pre-deploy check | `/fluent-pre-deploy-check` | §18 Deployment (step 3) |
| Module deploy | `/fluent-module-deploy` | §18 Deployment (step 4) |
| Workflow deploy | `/fluent-workflow-deploy` | §18 Deployment (steps 5-6) |
| Data module scaffold | `/fluent-data-module-scaffold` | When the feature requires data modules (no Java) |
| Manifest building | `/fluent-mystique-builder` | §10 UI / Manifest Artifacts |
| SDK component scaffold | `/fluent-mystique-scaffold` | §10 UI / Manifest Artifacts (Custom SDK Components) |
| UI verification | `/fluent-ui-test` | §10 UI / Manifest Artifacts, §17 Test Plan |
| E2E verification | `/fluent-e2e-test` | §17 Test Plan |

The deployment sequence in §18 defines execution order. Track tasks from §18 via TodoWrite.

**Module-first deployment:** When workflows are bundled inside the module (`resources/workflows/`), `fluent module install` deploys rules, workflows, and settings together. The separate `/fluent-workflow-deploy` step (steps 5-6) is only needed for standalone workflows NOT included in the module, or when workflows were excluded during module install (`--exclude workflows`).

**Critical ordering constraint:** Module deploy (registers rules) MUST complete before workflow deploy (references rules). Deploying workflows that reference unregistered custom rules causes NO_MATCH events at runtime. The §18 template enforces this: workflow deploy steps depend on module deploy.

**Version bump required for any content change:** Any change to Java code, workflow JSONs, settings, or resources requires bumping the module version in BOTH `resources/module.json` AND all `pom.xml` files. See `/fluent-build` for the sync procedure.

**Validation chain:** `/fluent-module-validate` -> `/fluent-build` -> `/fluent-pre-deploy-check` -> `/fluent-module-deploy`. The pre-deploy check is the final gate before deployment and produces a READY/BLOCKED verdict.

## Updating a Plan Mid-Implementation

Plans are living documents. Mid-implementation changes happen when discovery reveals missing artifacts, requirements change, or technical constraints emerge. This section defines the revision protocol.

### When Revision is Triggered

| Trigger | Example | Severity |
|---------|---------|----------|
| Missing artifact discovered | Rule referenced in workflow but not in plan | MEDIUM — add to plan |
| Requirement change from user | "We also need SMS notifications" | HIGH — re-scope |
| Technical constraint found | OOTB rule doesn't support needed parameter | MEDIUM — reclassify rule |
| Dependency failure | Module build reveals missing import | LOW — fix in plan |
| Test failure reveals gap | E2E test shows missing status transition | MEDIUM — add status + ruleset |

### Revision Protocol

1. **Increment revision** — Edit the plan file header: `Revision: N+1`, update `Updated: <today>`
2. **Add revision log entry** — Append to the bottom of the plan:
   ```markdown
   ---
   ## Revision Log

   ### Revision N+1 — <date>
   **Trigger:** <what caused the revision>
   **Changes:**
   - Added: <new artifacts>
   - Modified: <changed artifacts with before → after>
   - Removed: <artifacts no longer needed>
   **Impact on completed work:** <what already-built artifacts are affected>
   ```
3. **Re-present changed sections** — Show ONLY the sections that changed, not the full plan
4. **Require re-approval** — User must explicitly approve the revision before implementation continues
5. **Update status.json** — Set `planRevision: N+1`, `updated: <today>`

### Status Regression Rules

| Current Status | Revision Type | Status After Revision | Gate resets |
|---------------|--------------|----------------------|-------------|
| `APPROVED` | Any change to plan | Stays `APPROVED` | none |
| `IN_PROGRESS` / `BUILT` | Additive (new rules, rulesets, settings) | Stays current | none |
| `IN_PROGRESS` / `BUILT` | Subtractive or trigger change | Regresses to `APPROVED` | `build: null` |
| `IN_PROGRESS` / `BUILT` | Structural (new workflows, entity types, integrations) | Regresses to `PLANNING` | `build: null` |
| `DEPLOYED` | Change requiring rebuild | Regresses to `IN_PROGRESS` | `build: null`, `deploy: null` |
| `DEPLOYED` | Workflow-only change | Regresses to `BUILT` | `deploy: null` |
| `VERIFIED` | Any change | Regresses to `IN_PROGRESS` | `build: null`, `deploy: null`, `test: null` |

> **After VERIFIED:** Features that have passed E2E verification are complete. Use `/fluent-feature-status` to inspect lifecycle state at any point.

### Impact on Completed Work

When a plan revision occurs, assess impact on already-implemented artifacts:

| Already Completed | Revision Impact | Action |
|------------------|-----------------|--------|
| Rule scaffolded, not yet built | Plan adds new parameter to the rule | Edit the scaffolded Java class — add parameter |
| Rule built and deployed | Plan changes rule logic | Re-scaffold is risky — edit existing source directly |
| Workflow deployed | Plan adds new ruleset | Add ruleset via `/fluent-workflow-builder`, re-deploy |
| Workflow deployed | Plan removes a status | **BREAKING** — check for entities at that status first |
| Settings created | Plan changes setting value shape | Update setting value — no re-deploy needed |
| E2E test passed | Plan adds new test case | Add test case, re-run E2E |

**Critical rule:** Removing a status from a deployed workflow is a **BREAKING CHANGE** if any entities are currently at that status. Always check via GraphQL before removing:
```
graphql.query: { <entityType>s(status: ["<STATUS_TO_REMOVE>"], first: 1) { edges { node { ref } } } }
```

### Revision Limits

- **Revision 1-3:** Normal iteration. Proceed with re-approval.
- **Revision 4+:** Flag as "HIGH CHURN" — recommend stepping back to review the Business Spec. Frequent plan revisions often indicate incomplete requirements gathering.
- **Scope-changing revision on VERIFIED feature:** Flag as **REGRESSION RISK** — the feature passed E2E and is now being re-opened. Require explicit justification.

## Cross-References

| For | Use |
|-----|-----|
| Plan template structure & worked examples | `PLAN_TEMPLATE.md` (in this skill directory) |
| OOTB rule search | `plugin.list` via MCP |
| Workflow analysis | `/fluent-workflow-analyzer` |
| Custom code analysis | `/fluent-custom-code` |
| Connection topology | `/fluent-connection-analysis` |
| Requirements gathering (before planning) | `/fluent-use-case-discover` |
| Scope decomposition (from scope docs) | `/fluent-scope-decompose` |
| Feature reverse-engineering (existing) | `/fluent-feature-explain` |
| Module scaffolding (if needed) | `/fluent-module-scaffold` |

## Post-Execution: Feedback Capture

After completing this skill (whether success or failure), write a feedback record:

1. **Classify outcome:** `SUCCESS` (completed cleanly), `PARTIAL_SUCCESS` (completed after fixing issues), `FAILURE` (could not complete), `BLOCKED` (prereq missing), `USER_CORRECTED` (user overrode approach)
2. **Build record:** Create a `feedback-record-v1` JSON object with:
   - `skill`: `"fluent-feature-plan"`
   - `feature`: feature slug if applicable, null otherwise
   - `phases`: trace of each phase with PASS/FAIL/SKIP
   - `learnings`: any gotchas discovered during execution
   - `userCorrections`: any corrections the user provided
3. **Redact secrets:** Strip tokens, passwords, API keys. Keep business identifiers.
4. **Append** one JSON line to `accounts/<PROFILE>/feedback/fluent-feature-plan.jsonl`
5. **Update** `accounts/<PROFILE>/feedback/index.json` counters (create with `mkdir -p` if missing)

**Skip capture if:** The execution was trivially simple (e.g., user asked a question, no actual write operation happened).

## Known Pitfalls
<!-- feedback-promoted: managed section, updated by feedback loop -->

_(No promoted learnings yet.)_

<!-- end feedback-promoted -->
