---
name: fluent-pre-deploy-check
description: Run pre-deployment checklist for Fluent Commerce modules and workflows. Validates environment readiness, module structure, workflow integrity, settings, and connection topology before deployment. Triggers on "pre-deploy check", "deployment checklist", "ready to deploy", "deploy gate", "can I deploy".
user-invocable: true
allowed-tools: Bash, Read, Write, Edit, Glob, Grep
argument-hint: [--profile <profile>] [--retailer <ref>] [--module-path <path>] [--skip <phase,...>]
cursor-tier: manual
planning-gate: advisory
---

# Pre-Deployment Checklist

Structured deployment gate between "build passes" and "deploy to retailer." Runs 9 phases of validation (29 backend gates + 5 frontend gates) producing a machine-readable pass/fail report that blocks deployment on critical failures.

This skill is the final checkpoint in the Agent-Driven Development (ADD) lifecycle, positioned at Phase 6 (Demo Deployment). It aggregates validation from multiple specialized skills and MCP tools into a single, traceable pre-flight report.

## Pre-flight: Feedback Check

Before starting, check for past learnings from this skill:

1. Check if `accounts/<PROFILE>/feedback/fluent-pre-deploy-check.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

## Planning Gate

**This skill IS the planning gate for deployment.** Running a pre-deploy check is always safe (read-only analysis). No approval needed to run the check itself. However, if the check result includes a GO verdict and the user asks to proceed with deployment, the deployment skills (`/fluent-module-deploy`, `/fluent-workflow`) have their own planning gates that apply.

## Ownership Boundary

This skill owns:
- The checklist execution protocol (phase sequencing, gate evaluation, severity thresholds)
- The aggregate pass/fail decision and overall deployment readiness verdict
- The checklist report artifact (`accounts/<PROFILE>/reports/pre-deploy/<MODULE>-<VERSION>.checklist.json`)

This skill delegates to:
- `/fluent-module-validate` -- module structure validation (Phase 2)
- `/fluent-build` -- Maven build execution (Phase 2)
- `/fluent-version-manage` -- version comparison and drift detection (Phase 2, Phase 7)
- `/fluent-workflow-analyzer` -- workflow structure analysis and orphan detection (Phase 3)
- `/fluent-connection-analysis` -- cross-entity topology and dependency mapping (Phase 4)
- `/fluent-settings` -- settings audit and value validation (Phase 5)
- `/fluent-module-deploy` -- receives the READY signal to proceed with deployment
- `/fluent-session` -- tracks all checklist operations for audit trail

Individual gate validations are NOT reimplemented here. This skill orchestrates existing capabilities and evaluates their results against deployment thresholds.

## Handoff Protocol

### Signals emitted by this skill

| Signal | Condition | Example |
|--------|-----------|---------|
| `-> READY: <path>` | Checklist report produced with READY verdict | `-> READY: accounts/MY_PROFILE/reports/pre-deploy/my-extensions-0.0.30.checklist.json` |
| `-> NEXT: /fluent-<skill>` | Ready for deployment | `-> NEXT: /fluent-module-deploy` |
| `-> BLOCKED: <reason>` | Checklist verdict is BLOCKED | `-> BLOCKED: DEPLOYMENT_BLOCKED — 2 blocking gates: missing settings, unregistered rules` |

### Error codes

| Code | Condition | Recovery |
|------|-----------|----------|
| `PREREQ_MISSING` | Module not built or build artifact not found | Run `/fluent-build` first |
| `VALIDATION_FAILED` | Check phase failed (environment, structure, rules) | Fix issues listed in report |
| `ENV_UNREACHABLE` | Cannot connect to Fluent environment | Check credentials via `config.validate` |
| `DEPLOYMENT_BLOCKED` | Overall verdict is BLOCKED | Resolve all blocking gates before deploying |

## When to Use

- Before deploying a module to any retailer (mandatory gate)
- Before deploying workflow changes to a retailer
- As part of CI/CD pipelines for automated release gating
- When asked "is this ready to deploy?" or "can I deploy?"
- After completing all development tasks from a scope decomposition
- Before go-live as part of Ready For Launch (RFL) preparation

## Progress

Emit this block at each phase transition to show progress:

```
▸ /fluent-pre-deploy-check [1/9]
  ✓ Environment              → Module structure
  ○ Workflow validity         ○ Connections
  ○ Settings                  ○ Target environment
  ○ Risk assessment           ○ Completeness
  ○ Frontend bundle
```

Update the block as each phase completes — mark completed phases with `✓`, the active phase with `→`, and remaining phases with `○`. Replace `[1/9]` with the current phase number. Append gate result (PASS/FAIL count) after each completed phase.

## Required Inputs

| Parameter | Required | Default | Description |
|-----------|----------|---------|-------------|
| `--profile` | No | Active `FLUENT_PROFILE` | Target Fluent CLI profile for environment queries |
| `--retailer` | No | Profile default retailer | Target retailer ref (e.g., `MY_RETAILER`) |
| `--module-path` | No | Auto-detect from `accounts/<PROFILE>/SOURCE/backend/` | Path to module root (directory containing `resources/module.json`) |
| `--workflow-path` | No | Auto-detect from `accounts/<PROFILE>/workflows/<RETAILER>/` | Path to workflow JSON directory |
| `--skip` | No | None | Comma-separated phase numbers to skip (e.g., `--skip 4,7`) |
| `--severity-threshold` | No | `CRITICAL` | Minimum severity that blocks deployment: `CRITICAL`, `HIGH`, or `MEDIUM` |
| `--deployed-version` | No | Auto-detect via `plugin.list` | Currently deployed module version for diff comparison |

### Auto-Detection Logic

When `--module-path` is not provided:
1. Search `accounts/<PROFILE>/SOURCE/backend/` recursively for `resources/module.json`
2. If exactly one found, use it
3. If multiple found, list them and ask user to select
4. If none found, skip module-related phases (2, 7.2, 7.3) and note in report

When `--workflow-path` is not provided:
1. Check `accounts/<PROFILE>/workflows/<RETAILER>/` for `*.json` files
2. If no workflows found, skip workflow-related phases (3, 4) and note in report

Frontend SDK project detection (for Phase 9):
1. Search `accounts/<PROFILE>/SOURCE/frontend/*/package.json` for SDK projects
2. Cross-reference with manifest `plugins[]` URLs from Phase 5 settings scan
3. If no SDK projects found AND no custom plugin URLs in manifests, skip Phase 9
4. If SDK projects found, run Phase 9 gates against each project

## Partial Deployment Scenarios

Not every deployment includes all components. The checklist adapts:

| Scenario | Phases Run | Phases Skipped |
|----------|-----------|---------------|
| Module + Workflow deploy | 1-8 (9 auto-skipped if no SDK project) | 9 when no frontend |
| Module + Workflow + Frontend deploy | All 9 phases | None |
| Module-only deploy | 1, 2, 5, 6, 7, 8 | 3 (Workflow), 4 (Connection), 9 (Frontend) |
| Workflow-only deploy | 1, 3, 4, 5, 6, 8 | 2 (Module), 7.2-7.3 (module-specific risk), 9 (Frontend) |
| Settings-only deploy | 1, 5, 6, 8 | 2 (Module), 3 (Workflow), 4 (Connection), 7 (Risk), 9 (Frontend) |
| Frontend-only deploy | 1, 5, 6, 9 | 2 (Module), 3 (Workflow), 4 (Connection), 7 (Risk) |
| Multiple modules | All 9, repeated per module | None (iterate Phase 2 per module) |

Phases are auto-skipped when their inputs are unavailable. The `--skip` flag forces additional skips beyond auto-detection.

---

## Checklist Phases and Gates

### Phase 1: Environment Readiness

Verify the target environment is accessible, correctly configured, and capable of receiving a deployment.

#### Gate 1.0: CLI Available

**Severity:** HIGH

**Tool:** Bash (`fluent --version`)

**Invocation:**
```bash
fluent --version
```

**Pass criteria:** Command succeeds and returns a version string (e.g., `v2.0.0`).

**Fail criteria:** Command not found or returns an error. Many deployment operations (module install, workflow list/download, verification) require the Fluent CLI. HIGH rather than CRITICAL because MCP tools can handle some operations without CLI, but the standard deployment path requires it.

**Details captured:** CLI version string, CLI path (from `which fluent` or `where fluent`).

#### Gate 1.1: Authentication Valid

**Severity:** CRITICAL

**Tool:** `connection.test` (MCP fluent-mcp-extn)

**Invocation:**
```
connection.test({})
```

**Pass criteria:** Response contains `user` object with `id`, `username`, and at least one role. The `status` field of the user is not `INACTIVE`.

**Fail criteria:** Connection refused, auth error, or user has no roles. Deployment cannot proceed without valid authentication.

**Details captured:** Username, email, roles list, retailer context.

#### Gate 1.2: Retailer Exists and Active

**Severity:** CRITICAL

**Tool:** `environment.discover` (MCP fluent-mcp-extn)

**Invocation:**
```
environment.discover({ include: ["retailer"] })
```

**Pass criteria:** Response contains retailer with `status = "ACTIVE"` and `ref` matching the `--retailer` parameter.

**Fail criteria:** Retailer not found, status is not ACTIVE, or ref mismatch. Cannot deploy to an inactive or non-existent retailer.

**Details captured:** Retailer ID, ref, tradingName, status.

#### Gate 1.3: Locations Exist

**Severity:** HIGH

**Tool:** `environment.discover` (MCP fluent-mcp-extn)

**Invocation:**
```
environment.discover({ include: ["locations"] })
```

**Pass criteria:** At least 1 location exists with `type = "WAREHOUSE"` or `type = "STORE"` and `status = "ACTIVE"`.

**Fail criteria:** No active locations found. Most workflows require at least one location for fulfilment routing. This is HIGH rather than CRITICAL because some module deployments (e.g., pure data modules) do not require locations.

**Details captured:** Total location count, count by type (WAREHOUSE, STORE), active vs inactive.

#### Gate 1.4: Networks Wired

**Severity:** HIGH

**Tool:** `environment.discover` (MCP fluent-mcp-extn)

**Invocation:**
```
environment.discover({ include: ["networks"] })
```

**Pass criteria:** At least 1 network exists with at least 1 associated location.

**Fail criteria:** No networks found, or all networks have zero locations. Fulfilment routing requires network-to-location wiring.

**Details captured:** Network count, locations-per-network count.

---

### Phase 2: Module Integrity

Verify the module builds cleanly, tests pass, structure is valid, and the version has been bumped.

**Skip condition:** No `--module-path` provided and no module found via auto-detection.

#### Gate 2.1: Build Passes

**Severity:** CRITICAL

**Tool:** Bash (`mvn clean install`)

**Invocation:**
```bash
cd "<MODULE_ROOT>/plugins" && mvn clean install -q 2>&1
```

**Pass criteria:** Exit code 0. Maven build completes without compilation errors.

**Fail criteria:** Non-zero exit code. Compilation errors, dependency resolution failures, or plugin errors. Deployment of a broken build must be blocked.

**Details captured:** Build duration, test count from Maven output (e.g., "Tests run: 42, Failures: 0, Errors: 0, Skipped: 0").

#### Gate 2.2: Tests Pass

**Severity:** CRITICAL

**Tool:** Included in the Maven build output from Gate 2.1.

**Pass criteria:** Maven reports 0 failures and 0 errors in test execution. The string `BUILD SUCCESS` appears in output.

**Fail criteria:** Any test failure or error. Parse Maven output for `Tests run: X, Failures: Y, Errors: Z`. If Y > 0 or Z > 0, this gate fails.

**Details captured:** Total tests, failures, errors, skipped count.

#### Gate 2.3: module.json Valid

**Severity:** CRITICAL

**Tool:** Read (`resources/module.json` in the module root)

**Invocation:**
```
Read file: <MODULE_ROOT>/resources/module.json
```
Then validate the parsed JSON:

**Pass criteria:** All of the following:
- File exists and is valid JSON
- Has `name` field (non-empty string)
- Has `version` field (matches semver pattern `^\d+\.\d+\.\d+(-SNAPSHOT)?$`)
- Has `modules` array with at least one entry
- Each module entry has `provides` array with rule registrations
- No duplicate rule names across all `provides` arrays

**Fail criteria:** Missing file, invalid JSON, missing required fields, or duplicate rule registrations. The module manifest is the deployment identity -- any defect here is CRITICAL.

**Details captured:** Module name, version, rule count, any validation errors.

#### Gate 2.4: Version Bumped vs Deployed

**Severity:** HIGH

**Tool:** `plugin.list` (MCP fluent-mcp-extn) + Read (`resources/module.json`)

**Invocation:**
```
plugin.list({})
```
Then extract the deployed module version by matching module name from the rule key prefix pattern `<ACCOUNT>.<context>.<RuleName>`.

Alternatively, if `--deployed-version` is provided, compare directly.

**Pass criteria:** Local version in `module.json` is strictly greater than the currently deployed version. Semver comparison: `localVersion > deployedVersion`.

**Fail criteria:** Local version equals or is less than deployed version. Deploying the same version causes confusion; deploying a lower version is a potential rollback. This is HIGH because version-same deployments are technically possible (idempotent reinstall) but indicate a process gap.

**Edge case:** If `plugin.list` returns no rules matching this module (first-time deployment), this gate passes with a note: "First deployment -- no previous version to compare."

**Details captured:** Local version, deployed version (or "not deployed"), comparison result.

---

### Phase 3: Workflow Validity

Verify all workflow JSON files are structurally sound, internally consistent, and reference only existing rules.

**Primary gate:** Run **`/fluent-workflow-validate <workflow-path> --profile <PROFILE>`** on each workflow file. This single invocation covers schema compliance (S01-S10), status graph integrity (G01-G10), trigger routing (T01-T10), rule references (R01-R09), user actions (U01-U10), and cross-entity checks (X01-X06). If it returns FAIL (any CRITICAL or HIGH), the entire Phase 3 fails.

The individual gates below are retained for reference and for cases where `/fluent-workflow-validate` is unavailable.

**Skip condition:** No `--workflow-path` provided and no workflows found via auto-detection.

#### Gate 3.1: Workflows Parse

**Severity:** CRITICAL

**Tool:** Read + JSON validation (each `*.json` file in the workflow directory)

**Invocation:**
```
For each *.json file in <WORKFLOW_PATH>/:
  Read file content
  Parse as JSON
  Validate required fields
```

**Pass criteria:** Every workflow JSON file:
- Parses as valid JSON
- Has a `name` field (string, e.g., `"ORDER::HD"`)
- Has a `statuses` array with at least one status entry
- Has a `rulesets` array with at least one ruleset entry
- Each ruleset has `name`, `rules` (array), and `triggers` (array)

**Fail criteria:** Any file fails to parse, or any required structural field is missing. Deploying a malformed workflow will cause runtime failures.

**Details captured:** Per-file parse status, workflow names found, total ruleset count, total status count.

#### Gate 3.2: No Orphaned Rulesets

**Severity:** HIGH

**Tool:** Workflow JSON analysis (apply `/fluent-workflow-analyzer` orphan detection logic)

**Invocation:**
For each parsed workflow, build the trigger graph:
1. Index all statuses defined in `statuses[]`
2. Index all rulesets and their `triggers[].status` entries
3. Index all `SendEvent` / `ScheduleEvent` / `ForwardEvent*` rule props for `eventName`
4. For each ruleset, check if it is reachable:
   - Has a trigger on a defined status, OR
   - Has its name as a `SendEvent` target from another reachable ruleset, OR
   - Is the `CREATE` ruleset (always reachable)

**Pass criteria:** Every ruleset is reachable from either a status trigger or an inbound SendEvent chain.

**Fail criteria:** One or more rulesets have no inbound path. Orphaned rulesets indicate dead code or missing wiring that could cause silent failures.

**Details captured:** List of orphaned rulesets (if any), total rulesets analyzed.

#### Gate 3.3: Rules Exist in Registry

**Severity:** CRITICAL

**Tool:** `plugin.list` (MCP fluent-mcp-extn)

**Invocation:**
```
plugin.list({ compact: true })
```
Then cross-reference every rule class name referenced in workflow rulesets against the registered rules.

**Pass criteria:** Every rule `name` in every ruleset's `rules[].name` field exists in the `plugin.list` response. The rule key pattern is `<ACCOUNT>.<context>.<RuleName>` or `FLUENTRETAIL.<context>.<RuleName>`.

**Fail criteria:** Any rule referenced in a workflow ruleset is not found in the registry. This means the rule's module has not been deployed, or the rule name is misspelled. Deploying a workflow that references non-existent rules causes NO_MATCH events at runtime.

**Details captured:** Total rules referenced, total matched, list of unmatched rules with the rulesets that reference them.

#### Gate 3.4: No Breaking Removals

**Severity:** HIGH

**Tool:** `workflow.diff` (MCP fluent-mcp-extn)

**Invocation:**
Download the currently deployed workflow for comparison:
```bash
fluent workflow download -p <PROFILE> -r <RETAILER> -w <WORKFLOW_NAME> -o /tmp/deployed-<WORKFLOW_NAME>.json
# OR via MCP: workflow.get({ entityType: "<TYPE>", entitySubtype: "<SUB>", retailerId: "<id>" })
```
Then:
```
workflow.diff({
  base: <deployed_workflow_json>,
  target: <local_workflow_json>,
  format: "detailed"
})
```

**Pass criteria:** No rulesets with `change: "REMOVED"` that have `risk: "HIGH"`. Added rulesets and modified props are acceptable.

**Fail criteria:** Any ruleset removal flagged as HIGH risk by the diff tool. Removing a ruleset that handles active entity states can cause orders/fulfilments to get stuck.

**Edge case:** If no deployed workflow exists (first deployment), this gate passes automatically.

**Details captured:** Rulesets added, modified, removed. Risk level for each removal.

#### Gate 3.45: Workflow Major Version Impact

**Severity:** HIGH

**Tool:** `workflow.get` or `workflow.list` (MCP fluent-mcp-extn) + Read (local workflow JSON)

**Invocation:**
For each workflow JSON being deployed:
1. Read the `version` field from the local workflow JSON (format: `<major>.<minor>`)
2. Fetch the currently deployed version via `workflow.get({ entityType, entitySubtype })` or `workflow.list`
3. Parse both versions and compare major components

**Pass criteria (INFO):** Minor version bump only (e.g., 1.2 → 1.3). All existing entities on that major version will use the new workflow immediately. No entity isolation boundary changes.

**Pass criteria (WARN):** Major version bump detected (e.g., 99.10 → 100.0). This is valid but has significant behavioral impact:
- Existing entities (orders, fulfilments, etc.) stay pinned to the **old major** and will continue using its latest minor — they will **never** execute against the new major's rulesets
- Only **newly created** entities will be assigned to the new major version
- If the intent was to update all entities (including in-flight), a **minor bump** is required instead

**Fail criteria:** None — major bumps are valid. But the gate MUST emit a prominent warning so the deployer consciously acknowledges the entity isolation impact.

**Edge case:** First deployment (no deployed version exists) — pass with note "First deployment, no version comparison needed."

**Details captured:** Local version, deployed version, bump type (major/minor), number of major versions apart, explicit impact statement.

#### Gate 3.5: User Action Schema Validity

**Severity:** HIGH

**Tool:** Workflow JSON analysis (inline validation of `userActions` arrays)

**Invocation:**
For each parsed workflow, for each ruleset that contains a `userActions` array:
1. Check ruleset has a `subtype` field (string, non-empty)
2. Check each user action has `eventName` (string, non-empty)
3. Check each user action has `context` (array, non-empty)
4. For each context entry, validate all 4 mandatory fields:
   - `label` (string, non-empty)
   - `type` (string, `"PRIMARY"` or `"SECONDARY"`)
   - `modules` (array, non-empty, values are the app's `orchestrationAlias`: `"adminconsole"` (OMS App — manifest is `fc.mystique.manifest.oms`), `"servicepoint"` (Store App — manifest is `fc.mystique.manifest.store`), or custom — **OMS App uses `"adminconsole"` NOT `"oms"`**, **Store App uses `"servicepoint"` NOT `"store"`** due to `orchestrationAlias` override)
   - `confirm` (boolean, not string `"true"`)
5. If `attributes` array has entries, check each attribute:
   - `source` must be `""` (empty) or `"settings.<key>"` — values like `"OVERRIDE"` silently break ALL user actions for the entity type
   - If `source` starts with `"settings."`: must be **lowercase** `"settings."` (NOT `"Settings."` — capital S silently fails), the referenced setting must exist, and its value must have `{ "active": [...] }` wrapper format (plain array silently fails)
   - `defaultValue` must be `""` (empty) or a literal — template expressions like `"{{me.username}}"` silently break ALL user actions for the entity type

**Pass criteria:** Every user action across all rulesets passes all checks.

**Fail criteria (HIGH — silent UI breakage):**
- **Missing `subtype` on ruleset** → buttons silently invisible in ALL apps (#1 cause of missing user action buttons)
- **Missing `eventName`** → UI may not resolve the button correctly
- **Missing or empty `modules`** → buttons invisible
- **`confirm` as string instead of boolean** → unpredictable UI behavior
- **Attribute poisoning: `source: "OVERRIDE"` or `defaultValue: "{{...}}"`** → breaks ALL user actions for that entity type across the entire workflow (not just the affected action). This is CATASTROPHIC and must be CRITICAL severity when detected.

**Details captured:** Per-ruleset user action count, validation errors with field paths, attribute poisoning detected (yes/no).

#### Gate 3.6: Action Visibility Checks

**Severity:** HIGH — missing any of these causes silent button invisibility with no error message.

**Tool:** Workflow JSON analysis + `plugin.list` (MCP fluent-mcp-extn) for app name validation

**Skip condition:** Workflow has no `userActions` in any ruleset.

**Invocation:**
For each parsed workflow that contains rulesets with `userActions`:

1. **Module values are valid** — Each `context[].modules` value must match a deployed app's `orchestrationAlias` (NOT the manifest setting suffix or URL path): OMS App → `"adminconsole"` (manifest is `fc.mystique.manifest.oms`), Store App → `"servicepoint"` (manifest is `fc.mystique.manifest.store`), or a custom app's alias
2. **OMS App buttons use `"adminconsole"`** — If the feature targets the OMS App, verify `modules` includes `"adminconsole"` (NOT `"oms"` — the OMS App manifest has `orchestrationAlias: "adminconsole"` which overrides the module name sent to Transition API)
3. **Parent-child workflow placement** — For child entity user actions (CREDIT_MEMO, FULFILMENT, FULFILMENT_CHOICE), verify the user action ruleset is in the PARENT workflow, not a standalone child workflow. Child entities inherit `workflowRef` from their parent, and the UI uses `workflowRef` as `flexType` when calling the Transition API. Note: the Transition API itself accepts both parent and child workflow names as `flexType`, but the UI always uses the parent's `workflowRef`, so placement in the parent workflow is required for button visibility
4. **Ruleset has `subtype`** — Every ruleset with `userActions` must have a `subtype` field matching the workflow's `entitySubtype`
5. **`eventName` is present** — Every user action must have an explicit `eventName`
6. **`confirm` is boolean** — Not a string `"true"`, not a `confirmationMessage` — must be boolean `true` or `false`

**Pass criteria:** All six checks pass for every user action across all rulesets.

**Fail criteria:**
- **`modules` contains `"oms"` instead of `"adminconsole"`** → buttons invisible in the OMS App despite correct workflow wiring
- **User action in child workflow instead of parent** → UI cannot find the action because the child entity's `workflowRef` points to the parent workflow, and the UI uses `workflowRef` as `flexType` (note: the Transition API itself accepts both parent and child workflow names, but the UI always uses the parent)
- **Unrecognized module name** → button invisible in target app with no error
- **Missing `subtype`** → buttons silently invisible (overlaps with Gate 3.5 but re-checked here for completeness)
- **Missing `eventName`** → UI cannot resolve the button
- **`confirm` as string** → unpredictable dialog behavior

**Details captured:** Per-action module values, parent-vs-child workflow placement analysis, unrecognized module names, OMS module mismatch detected (yes/no).

---

### Phase 4: Connection Topology

Verify cross-entity event wiring, SendEvent target resolution, and absence of circular dependencies.

**Skip condition:** No workflows available (no `--workflow-path` and none found via auto-detection).

#### Gate 4.1: SendEvent Targets Exist

**Severity:** HIGH

**Tool:** Workflow JSON analysis (apply `/fluent-connection-analysis` emitter index logic)

**Invocation:**
For each workflow in the workflow set:
1. Scan all rules for `eventName` and `noMatchEventName` props
2. Build the emitter index: `{ emittedEventName -> [sourceRuleset, ...] }`
3. For each emitted event name, check if a ruleset exists anywhere in the workflow set that:
   - Has `name` matching the emitted event name, OR
   - Has a trigger that matches the emitted event name

**Pass criteria:** Every emitted `eventName` has at least one matching target ruleset in the workflow set.

**Fail criteria:** An emitted event has no matching target. This means the event will fire but nothing will process it, causing a NO_MATCH event at runtime. Exception: events targeting external systems (webhooks) or events known to be received from external integration partners are exempt -- flag these as INFO rather than FAIL.

**Details captured:** Total SendEvent emissions found, matched count, unmatched list with source rulesets.

#### Gate 4.2: Cross-Entity Refs Valid

**Severity:** MEDIUM

**Tool:** Workflow JSON analysis

**Invocation:**
Scan all rules for entity type references in props:
- `SendEventForOrder` implies ORDER entity type
- `SendEventForAllFulfilmentChoices` implies FULFILMENT_CHOICE entity type
- `SendEventForAllFulfilments` implies FULFILMENT entity type
- `CreateFulfilmentFromSourcingLocation` implies FULFILMENT creation
- Any rule prop referencing `entityType` values

For each cross-entity reference, verify a workflow exists for that entity type in the workflow set.

**Pass criteria:** Every cross-entity reference targets an entity type that has a corresponding workflow loaded in the workflow set.

**Fail criteria:** A cross-entity event targets an entity type with no loaded workflow. This may indicate a missing workflow download or a broken cross-entity chain.

**Details captured:** Cross-entity edges found (source -> target entity type), matched/unmatched counts.

#### Gate 4.3: No Circular Dependencies

**Severity:** MEDIUM

**Tool:** Workflow JSON analysis (apply `/fluent-connection-analysis` cycle detection logic)

**Invocation:**
Build the directed event chain graph from all workflows:
1. Nodes = rulesets
2. Edges = SendEvent emissions (source ruleset -> target ruleset)
3. Run depth-first cycle detection on the graph

**Pass criteria:** No cycles detected in the event chain graph. Note: status-based cycles (entity returns to a previous status via user action) are NOT circular dependencies -- only automated event chains are checked.

**Fail criteria:** An automated event chain forms a cycle (A sends to B, B sends to C, C sends to A). This causes infinite event loops at runtime. Cycles through user actions or external integration events are acceptable (they require human/system intervention to continue).

**Details captured:** Cycle paths found (if any), total nodes and edges in the graph.

---

### Phase 5: Settings Completeness

Verify all settings referenced by workflow rules exist in the target retailer with valid values.

#### Gate 5.1: Required Settings Exist

**Severity:** CRITICAL
Missing settings cause silent runtime rule failures that are difficult to trace. Elevating to CRITICAL ensures deployment is blocked until all required settings exist.

**Tool:** MCP `setting.get` (preferred) or `graphql.query` (MCP fluent-mcp-extn)

**Invocation:**
1. Extract all setting key references from workflow rules (scan rule props for setting-related patterns: `settingName`, `settingKey`, `webhookSettingKey`, `configKey`, and any prop value matching known setting name conventions)
2. For each extracted setting key, check existence using `setting.get` (simpler) or GraphQL with cascading scope resolution:

**Preferred — MCP `setting.get`:**
```
setting.get({ name: "<SETTING_KEY>" })
```
Returns settings matching the name across scopes. Use `context: "RETAILER"` or `context: "ACCOUNT"` to filter scope.

For large settings (manifests, config blobs 10-120KB), use `outputFile` to save content to disk instead of consuming LLM context:
```
setting.get({ name: "<SETTING_KEY>", outputFile: "accounts/<PROFILE>/settings/backups/<SETTING_KEY>.json" })
```
The inline response is fine for existence checks; `outputFile` is recommended when you need to inspect the full value (e.g., manifest JSON structure, plugin URLs, route definitions).

**Alternative — GraphQL cascading resolution (existence check only — do NOT request lobValue):**
```
graphql.query({
  query: "{ settings(first: 50, context: \"RETAILER\", contextId: <RETAILER_ID>, name: [\"<SETTING_KEY>\"]) { edges { node { id name value valueType } } } }"
})
```

If not found at RETAILER scope:
```
graphql.query({
  query: "{ settings(first: 50, context: \"ACCOUNT\", contextId: 0, name: [\"<SETTING_KEY>\"]) { edges { node { id name value valueType } } } }"
})
```

**Pass criteria:** Every setting key referenced by workflow rules is found at either RETAILER or ACCOUNT scope.

**Fail criteria:** A referenced setting is missing from both scopes. Missing settings cause rules to fail silently or throw exceptions at runtime.

**Details captured:** Per-setting: key, scope found (RETAILER/ACCOUNT), or MISSING status.

#### Gate 5.2: Setting Values Valid

**Severity:** MEDIUM

**Tool:** Read setting values from Gate 5.1 query results, then validate format

**Invocation:** Analyze each found setting's value:
- Webhook settings (key contains `webhook`, `url`, `endpoint`): Value must be a valid URL (starts with `http://` or `https://`) or valid JSON containing a `url` field
- JSON settings (value starts with `{` or `[`): Must parse as valid JSON
- Non-empty check: `value` or `lobValue` must be non-empty
- For manifest settings (`fc.mystique.manifest.*`) and other large JSON blobs, use `outputFile` from Gate 5.1 to write the value to disk, then read and validate from the file rather than inline. This avoids MCP response budget truncation on payloads over 50KB.

**Pass criteria:** All found settings have non-empty values in the expected format.

**Fail criteria:** A setting exists but has an empty value, or the value format does not match expectations (e.g., a webhook URL setting contains plain text instead of a URL).

**Details captured:** Per-setting: key, value preview (first 50 chars, redact if contains sensitive patterns), format validation result.

#### Gate 5.3: No Stale Settings

**Severity:** LOW

**Tool:** Compare settings list against current workflow rules

**Invocation:**
1. Query all settings at RETAILER scope:
```
graphql.query({
  query: "{ settings(first: 100, context: \"RETAILER\", contextId: <RETAILER_ID>) { edges { node { id name value } } } }"
})
```
2. Cross-reference with the setting keys extracted from current workflow rules
3. Identify settings that exist in the retailer but are NOT referenced by any current workflow rule

**Pass criteria:** No stale settings found, or all unreferenced settings are clearly infrastructure/system settings (not workflow-specific).

**Fail criteria:** Settings exist that were likely created for removed rulesets. This is LOW severity because stale settings are not harmful but indicate configuration drift.

**Details captured:** List of potentially stale settings with their current values.

#### Gate 5.4: GraphQL Operations Valid

**Severity:** HIGH

**Tool:** `graphql.validate` + `graphql.introspect` (MCP fluent-mcp-extn or fluent-mcp)

**Skip condition:** MCP tools unavailable — record SKIP with note "GraphQL validation requires MCP connectivity."

**Invocation:**

1. **Workflow rule GraphQL** — For each workflow file, scan rules for GraphQL-related props:
   - Rules matching `*Dynamic*`, `*Attribute*`, `*Path*` patterns → extract field paths from props, verify via `graphql.introspect({ type: "<entityType>" })`
   - Rules with `mutationName` or `createMutation` props → verify mutation exists via `graphql.introspect({ mutation: "<value>" })`

2. **Manifest page queries** — For each manifest setting (`fc.mystique.manifest.*`) found in Gate 5.1:
   - Extract page `data.query` values
   - Validate each: `graphql.validate({ query: "<page-query>" })`
   - Check `response.valid` (not `response.ok`)

3. **Component-embedded queries** — If SDK project source exists (`accounts/<PROFILE>/SOURCE/frontend/`):
   - Grep for `gql\`` or `useQuery(` patterns in `.tsx` files
   - Extract query strings and validate: `graphql.validate({ query: "<embedded-query>" })`

**Pass criteria:** All extracted GraphQL operations return `valid: true`. All DynamicUtils field paths resolve via introspection.

**Fail criteria:** Any operation returns `valid: false` or any field path does not resolve. Invalid GraphQL causes silent runtime failures — pages show no data, rules fail with null responses.

**Details captured:** Per-operation: source (workflow rule / manifest page / component), operation text (first 100 chars), validation result (valid/invalid), errors if invalid.

---

### Phase 6: Target Verification

Verify the deployment target is correct and the environment is healthy.

#### Gate 6.1: Target Retailer Matches

**Severity:** CRITICAL

**Tool:** Config validation + `environment.discover`

**Invocation:**
Compare the `--retailer` parameter (or profile default) against the authenticated session context:
```
environment.discover({ include: ["retailer"] })
```

**Pass criteria:** The retailer ref returned by `environment.discover` matches the `--retailer` parameter. If the module has retailer-scoped configuration (e.g., `module.config.json` with retailer tokens), the configured retailer must also match.

**Fail criteria:** Mismatch between target retailer and authenticated context. This prevents deploying to the wrong retailer -- a common and dangerous mistake in multi-retailer accounts.

**Details captured:** Expected retailer ref, actual retailer ref, match result.

#### Gate 6.2: No Active Incidents

**Severity:** MEDIUM

**Tool:** `metrics.healthCheck` (MCP fluent-mcp-extn)

**Invocation:**
```
metrics.healthCheck({
  window: "1h",
  thresholds: {
    failureRate: 5,
    pendingRate: 10,
    dominanceRate: 50
  }
})
```

**Pass criteria:** No CRITICAL findings in the health check response. HIGH findings are noted but do not block.

**Fail criteria:** One or more CRITICAL health findings (e.g., failure rate above 5%, NO_MATCH events detected). Deploying during an active incident risks compounding the problem.

**Edge case:** If metrics are unavailable (Prometheus not configured), this gate passes with a note: "Metrics unavailable -- manual environment health check recommended."

**Details captured:** Health check findings summary, failure rate, pending rate, top events.

---

### Phase 7: Risk Assessment

Quantify the scope of changes, verify rollback capability, and scan for security concerns.

#### Gate 7.1: Change Scope Quantified

**Severity:** INFO

**Tool:** `workflow.diff` (reuse results from Gate 3.4) + file system analysis

**Invocation:**
1. Count changed workflow rulesets from `workflow.diff` results
2. Count changed source files:
```bash
cd "<MODULE_ROOT>" && git diff --stat HEAD~1 --name-only 2>/dev/null | wc -l
```
If git history is unavailable, count all `.java` files as the change scope.
3. Count changed settings (from Phase 5 analysis)

**Pass criteria:** Always passes (INFO severity). This gate quantifies risk, it does not block.

**Fail criteria:** N/A -- this gate always passes but produces a risk summary.

**Details captured:** Number of changed rulesets, changed source files, changed settings. Risk categorization: SMALL (< 5 changes), MEDIUM (5-20), LARGE (> 20).

#### Gate 7.2: Rollback Path Exists

**Severity:** HIGH

**Tool:** Version check + `plugin.list`

**Invocation:**
1. Query the currently deployed module version (from Gate 2.4)
2. Verify the previous version's artifact is available:
   - Check `dist/` directory for a ZIP with the previous version
   - Or confirm the previous version exists in the module registry via `plugin.list`

**Pass criteria:** A previous module version is recorded and its artifact is accessible for rollback. For first-time deployments, this gate passes with a note: "First deployment -- no rollback version exists."

**Fail criteria:** A previous version is deployed but its artifact cannot be located for rollback. Deploying without a rollback path is HIGH risk.

**Details captured:** Current deployed version, rollback artifact location (or "not found").

#### Gate 7.3: No PII Exposure

**Severity:** CRITICAL

**Tool:** Grep (scan module source files)

**Invocation:**
```
Grep for patterns in <MODULE_ROOT>/plugins/:
  - Email patterns: [a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}
  - Hardcoded tokens: (Bearer |token[=:]\s*["']|api[_-]?key[=:]\s*["']|password[=:]\s*["'])
  - PII patterns: (social.?security|ssn|credit.?card|passport.?number)
```

Exclude test files (`src/test/`) and known safe patterns (annotation strings, log format templates).

**Pass criteria:** No matches found in production source code (`src/main/java/`). Matches in test files are reported as INFO but do not fail the gate.

**Fail criteria:** Hardcoded credentials, email addresses, or PII patterns found in production source. This is CRITICAL because deployed modules run in the Fluent platform and any hardcoded secrets become visible in the rule registry.

**Details captured:** Files scanned, matches found (file path + line number + pattern type), exclusions applied.

---

### Phase 8: Completeness

Verify all preparatory work is done before deployment.

#### Gate 8.1: All Tasks Complete

**Severity:** MEDIUM

**Tool:** Read task list artifact (if available from `/fluent-scope-decompose`)

**Invocation:**
```
Read file: accounts/<PROFILE>/analysis/scope/<MODULE>.tasks.json
```

**Pass criteria:** Either:
- No task list exists (deployment is ad-hoc, not from a scope decomposition) -- passes with note
- Task list exists and all tasks have `status: "completed"` except the CHECKLIST and DEPLOY tasks themselves

**Fail criteria:** Task list exists and one or more tasks (excluding CHECKLIST and DEPLOY) are still `pending` or `in_progress`. Deploying with incomplete tasks risks shipping partial functionality.

**Details captured:** Total tasks, completed count, pending count, list of incomplete tasks.

#### Gate 8.2: CHANGELOG Updated

**Severity:** LOW

**Tool:** Read (`CHANGELOG.md` in module root)

**Invocation:**
```
Read file: <MODULE_ROOT>/CHANGELOG.md
```

**Pass criteria:** Either:
- `CHANGELOG.md` exists and has an entry for the current version (matching version from `module.json`), OR
- `CHANGELOG.md` exists and has a non-empty `[Unreleased]` section

**Fail criteria:** `CHANGELOG.md` is missing, empty, or has no entry for the current version and no unreleased content. This is LOW severity because missing changelogs do not cause deployment failures but indicate poor documentation practice.

**Details captured:** CHANGELOG exists (yes/no), current version entry found (yes/no), unreleased entry count.

### Phase 9: Frontend Bundle (auto-skipped when no SDK project)

Verify custom SDK component bundles are production-ready and no development artifacts remain.

**Auto-skip condition:** No `accounts/<PROFILE>/SOURCE/frontend/*/package.json` exists AND no manifest `plugins[]` references custom components. When skipped, record `SKIP: No frontend SDK projects detected`.

#### Gate 9.1: No Localhost Plugin URLs

**Severity:** CRITICAL

**Check:** Scan all manifest settings being deployed for `plugins[]` entries containing `localhost` or `127.0.0.1`.

**Invocation:**
If manifest settings were already saved to disk via `outputFile` in Gate 5.1, search those files directly:
```bash
grep -r "localhost\|127\.0\.0\.1" accounts/<PROFILE>/settings/backups/fc.mystique.manifest.*.json
```
Otherwise, fetch each manifest setting with `outputFile` and then search:
```
setting.get({ name: "fc.mystique.manifest.<app>", outputFile: "accounts/<PROFILE>/settings/backups/fc.mystique.manifest.<app>.json" })
```
Then search the saved files for localhost/127.0.0.1 in `plugins[].src` values.

**Pass criteria:** No manifest `plugins[]` entry contains `localhost` or `127.0.0.1`.

**Fail criteria:** Any deployed manifest fragment has `plugins[].src` pointing to localhost. This means the production UI will try to load a bundle from the developer's local machine, causing a broken UI for all users.

**Details captured:** Setting name, plugin index, localhost URL found.

#### Gate 9.2: Bundle Exists

**Severity:** HIGH

**Check:** For each SDK project referenced in manifest `plugins[]`, verify `dist/bundle.*.js` and `dist/version.json` exist locally.

**Invocation:**
```bash
ls accounts/<PROFILE>/SOURCE/frontend/<project>/dist/bundle.*.js
cat accounts/<PROFILE>/SOURCE/frontend/<project>/dist/version.json
```

**Pass criteria:** Bundle file exists and `version.json` is valid JSON with a `bundle` key.

**Fail criteria:** No bundle file in `dist/` or `version.json` missing/invalid. This means either `yarn build` was never run or failed.

**Details captured:** Project path, bundle filename, bundle size, version.json content.

#### Gate 9.3: Externals Not Bundled

**Severity:** HIGH

**Check:** Verify React, ReactDOM, and Material-UI are NOT accidentally included in the production bundle.

**Invocation:**
```bash
# Count react-dom occurrences in bundle (should be < 5 for import references only)
grep -c "react-dom" accounts/<PROFILE>/SOURCE/frontend/<project>/dist/bundle.*.js || true

# Check bundle size (> 200KB suggests missing externals)
wc -c accounts/<PROFILE>/SOURCE/frontend/<project>/dist/bundle.*.js
```

**Pass criteria:** `react-dom` count < 5 AND bundle size < 200KB.

**Fail criteria:** `react-dom` count >= 5 OR bundle size > 500KB. This indicates the webpack externals configuration is incorrect, causing version conflicts and bloated bundles at runtime.

**Details captured:** react-dom occurrences, bundle size bytes, externals config snippet from webpack.config.ts.

#### Gate 9.4: Bundle Size Reasonable

**Severity:** MEDIUM

**Check:** Verify the production bundle is within acceptable size limits.

**Pass criteria:** Bundle size < 200KB.

**Warn criteria:** Bundle size 200KB–500KB. Likely missing tree-shaking or including unnecessary dependencies.

**Fail criteria:** Bundle size > 500KB. Almost certainly includes externals or dead code.

**Details captured:** Bundle size bytes, comparison to previous build (if available).

#### Gate 9.5: Manifest Data Wiring

**Severity:** HIGH

**Check:** Validate manifest dataSource paths match page query root fields, dataSource placement is correct, and required data wiring is present.

**Invocation:**
If manifest settings were saved to disk via `outputFile` in Gate 5.1, run the Mystique validator against them:
```bash
node content/dev/skills/fluent-mystique-validate/validator.mjs accounts/<PROFILE>/settings/backups/fc.mystique.manifest.*.json --json
```
Alternatively, invoke `/fluent-mystique-validate` skill for each manifest file.

Focus on these blocking rules:
- **S16** (CRITICAL): `dataSource` inside `props` — silent data binding failure
- **D03** (MEDIUM): `dataSource` root segment does not match any page query field
- **P04** (HIGH): `fc.list` missing required `dataSource`
- **P07** (HIGH): `fc.repeater` missing required `dataSource`

**Pass criteria:** No CRITICAL or HIGH issues from the Mystique validator.

**Fail criteria:** Any S16, P04, or P07 rule violation. D03 violations produce warnings (MEDIUM) but do not block deployment — they indicate likely data binding errors that should be investigated.

**Details captured:** Per manifest: file name, issue count by severity, list of blocking issues with paths.

---

## Severity Definitions

| Severity | Meaning | Default Behavior |
|----------|---------|-----------------|
| **CRITICAL** | Deployment will fail or cause data corruption | Always blocks deployment |
| **HIGH** | Deployment may succeed but will cause runtime issues | Blocks at default threshold |
| **MEDIUM** | Potential issues that should be reviewed | Blocks only with `--severity-threshold MEDIUM` |
| **LOW** | Best practice recommendations | Never blocks, reported as warnings |
| **INFO** | Informational findings for audit trail | Never blocks, included in report |

### Severity Threshold Logic

The `--severity-threshold` parameter controls which gate failures block deployment:

```
overallResult = "READY"
for each gate in all phases:
  if gate.result == "FAIL" and gate.severity >= severityThreshold:
    overallResult = "BLOCKED"
    blockedBy.append(gate.id)
```

Severity ordering: `CRITICAL > HIGH > MEDIUM > LOW > INFO`

| Threshold | Blocks on |
|-----------|----------|
| `CRITICAL` (default) | Only CRITICAL failures block |
| `HIGH` | CRITICAL and HIGH failures block |
| `MEDIUM` | CRITICAL, HIGH, and MEDIUM failures block |

---

## Output Report Schema

The checklist report is written as a JSON file with the following structure:

```json
{
  "schema": "pre-deploy-checklist-v1",
  "profile": "<PROFILE>",
  "retailer": "<RETAILER_REF>",
  "retailerId": "<RETAILER_ID>",
  "module": "<module-name-from-module.json>",
  "moduleVersion": "<version-from-module.json>",
  "timestamp": "<ISO-8601>",
  "severityThreshold": "CRITICAL",
  "overallResult": "READY | BLOCKED",
  "blockedBy": ["<gate-id>", "..."],
  "phases": [
    {
      "number": 1,
      "name": "Environment Readiness",
      "result": "PASS | FAIL | SKIP",
      "skipReason": null,
      "gates": [
        {
          "id": "1.1",
          "name": "Auth valid",
          "severity": "CRITICAL",
          "result": "PASS | FAIL | SKIP | ERROR",
          "details": "User: admin@acmedev, Roles: [ADMIN, SUPER_ADMIN]",
          "tool": "connection.test",
          "duration_ms": 1250,
          "error": null
        },
        {
          "id": "1.2",
          "name": "Retailer exists",
          "severity": "CRITICAL",
          "result": "PASS",
          "details": "MY_RETAILER (ID 5), status=ACTIVE, tradingName=My Retailer",
          "tool": "environment.discover",
          "duration_ms": 890,
          "error": null
        },
        {
          "id": "1.3",
          "name": "Locations exist",
          "severity": "HIGH",
          "result": "PASS",
          "details": "3 locations: 2 WAREHOUSE (active), 1 STORE (active)",
          "tool": "environment.discover",
          "duration_ms": 0,
          "error": null
        },
        {
          "id": "1.4",
          "name": "Networks wired",
          "severity": "HIGH",
          "result": "PASS",
          "details": "1 network with 3 locations",
          "tool": "environment.discover",
          "duration_ms": 0,
          "error": null
        }
      ]
    },
    {
      "number": 2,
      "name": "Module Integrity",
      "result": "FAIL",
      "skipReason": null,
      "gates": [
        {
          "id": "2.1",
          "name": "Build passes",
          "severity": "CRITICAL",
          "result": "PASS",
          "details": "BUILD SUCCESS in 45s, 42 tests run",
          "tool": "bash:mvn",
          "duration_ms": 45200,
          "error": null
        },
        {
          "id": "2.2",
          "name": "Tests pass",
          "severity": "CRITICAL",
          "result": "PASS",
          "details": "Tests run: 42, Failures: 0, Errors: 0, Skipped: 0",
          "tool": "bash:mvn",
          "duration_ms": 0,
          "error": null
        },
        {
          "id": "2.3",
          "name": "module.json valid",
          "severity": "CRITICAL",
          "result": "PASS",
          "details": "Name: fc-module-my-extensions, Version: 1.3.0, Rules: 8",
          "tool": "read:module.json",
          "duration_ms": 50,
          "error": null
        },
        {
          "id": "2.4",
          "name": "Version bumped",
          "severity": "HIGH",
          "result": "FAIL",
          "details": "Local 1.2.3 == deployed 1.2.3. Run /fluent-version-manage bump",
          "tool": "plugin.list",
          "duration_ms": 2100,
          "error": null
        }
      ]
    },
    {
      "number": 3,
      "name": "Workflow Validity",
      "result": "PASS",
      "skipReason": null,
      "gates": []
    },
    {
      "number": 4,
      "name": "Connection Topology",
      "result": "SKIP",
      "skipReason": "No workflow changes detected",
      "gates": []
    },
    {
      "number": 5,
      "name": "Settings Completeness",
      "result": "PASS",
      "skipReason": null,
      "gates": []
    },
    {
      "number": 6,
      "name": "Target Verification",
      "result": "PASS",
      "skipReason": null,
      "gates": []
    },
    {
      "number": 7,
      "name": "Risk Assessment",
      "result": "PASS",
      "skipReason": null,
      "gates": []
    },
    {
      "number": 8,
      "name": "Completeness",
      "result": "PASS",
      "skipReason": null,
      "gates": []
    }
  ],
  "summary": {
    "totalGates": 26,
    "pass": 22,
    "fail": 2,
    "skip": 1,
    "error": 0,
    "bySeverity": {
      "CRITICAL": { "total": 8, "pass": 8, "fail": 0 },
      "HIGH": { "total": 8, "pass": 6, "fail": 2 },
      "MEDIUM": { "total": 5, "pass": 5, "fail": 0 },
      "LOW": { "total": 2, "pass": 2, "fail": 0 },
      "INFO": { "total": 2, "pass": 2, "fail": 0 }
    }
  },
  "recommendations": [
    {
      "gateId": "2.4",
      "action": "Run /fluent-version-manage bump --level patch to increment version",
      "skill": "fluent-version-manage"
    },
    {
      "gateId": "3.3",
      "action": "Deploy the module first, then re-run checklist for workflows",
      "skill": "fluent-module-deploy"
    }
  ]
}
```

### Output Path

```
accounts/<PROFILE>/reports/pre-deploy/<MODULE_NAME>-<VERSION>.checklist.json
```

Where `<MODULE_NAME>` is derived from `module.json` name with `/` replaced by `--` (e.g., `fluent-commerce--fc-module-my-extensions`).

For workflow-only deployments without a module, the filename uses the primary workflow name: `<WORKFLOW_NAME>.checklist.json`.

---

## Execution Flow

```
1. RESOLVE inputs:
   a. Determine profile (--profile or active FLUENT_PROFILE)
   b. Determine retailer (--retailer or profile default)
   c. Locate module path (--module-path or auto-detect from accounts/<PROFILE>/SOURCE/backend/)
   d. Locate workflow path (--workflow-path or auto-detect from accounts/<PROFILE>/workflows/<RETAILER>/)
   e. Parse --skip list (comma-separated phase numbers)
   f. Parse --severity-threshold (default: CRITICAL)

2. DETERMINE deployment scenario:
   a. Module found? -> include Phases 2, 7.2, 7.3
   b. Workflows found? -> include Phases 3, 4
   c. Apply --skip overrides on top of auto-detection

3. INITIALIZE report:
   a. Create report JSON skeleton with profile, retailer, module, timestamp
   b. Set overallResult = "READY" (optimistic)

4. EXECUTE phases sequentially (1 through 9):
   For each phase:
     a. Check if phase is skipped (auto or --skip) -> record SKIP with reason
     b. For each gate in the phase:
        i.   Record start time
        ii.  Execute the gate's tool/invocation
        iii. Evaluate pass/fail criteria
        iv.  Record result, details, duration, any errors
        v.   If result == FAIL and severity >= threshold:
             - Add gate.id to blockedBy[]
             - Set overallResult = "BLOCKED"
     c. Set phase result = FAIL if any gate failed, PASS if all passed, SKIP if skipped

   IMPORTANT: Do NOT short-circuit on failure. Run ALL phases and ALL gates
   regardless of failures. The complete report is more valuable than an early exit.

5. COMPUTE summary:
   a. Count pass/fail/skip/error across all gates
   b. Break down by severity level
   c. Generate recommendations for each failed gate

6. WRITE report:
   a. Ensure output directory exists:
      mkdir -p accounts/<PROFILE>/reports/pre-deploy/
   b. Write JSON report using the Write tool
   c. Record output path

7. DISPLAY console summary:
   a. Print results for each checklist phase
   b. Print overall verdict (READY or BLOCKED)
   c. If BLOCKED: list failures with recommended actions
   d. If READY: confirm deployment can proceed via /fluent-module-deploy
```

---

## Console Output Format

```
PRE-DEPLOYMENT CHECKLIST
========================
Profile: MY_PROFILE
Retailer: MY_RETAILER (ID 5)
Module: fc-module-my-extensions v1.3.0
Threshold: CRITICAL
Timestamp: 2026-02-23T10:30:00Z

Phase 1: Environment Readiness ........................ PASS
  [PASS] 1.0 CLI available (HIGH) -- fluent v2.0.0
  [PASS] 1.1 Auth valid (CRITICAL) -- admin@acmedev, roles: ADMIN
  [PASS] 1.2 Retailer exists (CRITICAL) -- MY_RETAILER, ACTIVE
  [PASS] 1.3 Locations exist (HIGH) -- 3 locations (2 WH, 1 STORE)
  [PASS] 1.4 Networks wired (HIGH) -- 1 network, 3 locations

Phase 2: Module Integrity ............................. FAIL
  [PASS] 2.1 Build passes (CRITICAL) -- BUILD SUCCESS, 42 tests
  [PASS] 2.2 Tests pass (CRITICAL) -- 0 failures, 0 errors
  [PASS] 2.3 module.json valid (CRITICAL) -- 8 rules registered
  [FAIL] 2.4 Version bumped (HIGH) -- 1.2.3 == 1.2.3 (not bumped)

Phase 3: Workflow Validity ............................ PASS
  [PASS] 3.1 Workflows parse (CRITICAL) -- 4 workflows, all valid
  [PASS] 3.2 No orphaned rulesets (HIGH) -- 0 orphans in 47 rulesets
  [PASS] 3.3 Rules exist (CRITICAL) -- 82/82 rules found
  [PASS] 3.4 No breaking removals (HIGH) -- 2 added, 1 modified, 0 removed
  [PASS] 3.5 User action schema (HIGH) -- 6 user actions in 4 rulesets, all valid
  [SKIP] 3.6 Action visibility (HIGH) -- no userActions in target workflows

Phase 4: Connection Topology .......................... PASS
  [PASS] 4.1 SendEvent targets exist (HIGH) -- 15/15 targets resolved
  [PASS] 4.2 Cross-entity refs valid (MEDIUM) -- 3 cross-entity edges, all valid
  [PASS] 4.3 No circular dependencies (MEDIUM) -- 0 cycles in 47 nodes

Phase 5: Settings Completeness ........................ PASS
  [PASS] 5.1 Required settings exist (CRITICAL) -- 12/12 found
  [PASS] 5.2 Setting values valid (MEDIUM) -- 12/12 valid format
  [PASS] 5.3 No stale settings (LOW) -- 0 stale settings

Phase 6: Target Verification .......................... PASS
  [PASS] 6.1 Target retailer matches (CRITICAL) -- MY_RETAILER confirmed
  [PASS] 6.2 No active incidents (MEDIUM) -- 0 CRITICAL findings

Phase 7: Risk Assessment .............................. PASS
  [PASS] 7.1 Change scope quantified (INFO) -- MEDIUM: 12 files, 3 rulesets
  [PASS] 7.2 Rollback path exists (HIGH) -- v1.2.3 artifact in dist/
  [PASS] 7.3 No PII exposure (CRITICAL) -- 0 matches in 8 source files

Phase 8: Completeness ................................. PASS
  [PASS] 8.1 All tasks complete (MEDIUM) -- 10/10 tasks completed
  [PASS] 8.2 CHANGELOG updated (LOW) -- v1.3.0 entry present

Phase 9: Frontend Bundle .............................. SKIP
  [SKIP] 9.1-9.4 -- No frontend SDK projects detected

SUMMARY
-------
Total: 32 gates | PASS: 25 | FAIL: 1 | SKIP: 5

VERDICT: READY
(Gate 2.4 failed at HIGH but threshold is CRITICAL -- does not block)

Recommendation: Bump version before deploying to avoid version confusion.
  -> Run: /fluent-version-manage bump --level patch

Report saved: accounts/MY_PROFILE/reports/pre-deploy/fluent-commerce--fc-module-my-extensions-1.3.0.checklist.json

To proceed with deployment:
  -> Run: /fluent-module-deploy --profile MY_PROFILE --retailer MY_RETAILER
```

When the verdict is `BLOCKED`:

```
VERDICT: BLOCKED
Deployment blocked by 2 gate failures at or above CRITICAL threshold:

  [FAIL] 2.1 Build passes (CRITICAL) -- Compilation error in CancelOrderRule.java:45
    -> Fix compilation error, then re-run /fluent-pre-deploy-check

  [FAIL] 3.3 Rules exist (CRITICAL) -- 2 rules not found: MY_PROFILE.custom.NewRule, MY_PROFILE.custom.OtherRule
    -> Deploy module first to register rules, then re-run for workflows

  [FAIL] 3.5 User action schema (CRITICAL) -- ATTRIBUTE POISONING in CancelOrder ruleset
    -> Attribute "actionedBy" has source: "OVERRIDE" — this breaks ALL ORDER-type user actions.
       Fix: set source to "" (empty string). See /fluent-workflow-builder UA10-UA11.

Resolve all CRITICAL failures before deployment.

If deployment was already made and issues are discovered post-deploy, use `/fluent-rollback` to revert to the previous known-good module or workflow version.
```

---

## Integration with Other Skills

| Skill | Integration Point | Direction |
|-------|------------------|-----------|
| `/fluent-module-validate` | Phase 2 reuses module validation logic; can also read cached `.report.json` if module unchanged | Input |
| `/fluent-build` | Phase 2 gate 2.1 executes the Maven build | Input |
| `/fluent-version-manage` | Phase 2 gate 2.4 and Phase 7 gate 7.2 use version comparison | Input |
| `/fluent-workflow-analyzer` | Phase 3 gate 3.2 applies orphan detection algorithm | Input |
| `/fluent-connection-analysis` | Phase 4 applies connection topology and cycle detection | Input |
| `/fluent-settings` | Phase 5 applies settings audit patterns | Input |
| `/fluent-scope-decompose` | Phase 8 gate 8.1 reads the task list artifact | Input |
| `/fluent-frontend-build` | Phase 9 reuses bundle verification and externals check results | Input |
| `/fluent-mystique-validate` | Phase 9 gate 9.1 cross-references manifest plugin URLs | Input |
| `/fluent-module-deploy` | Receives the READY verdict to proceed | Output |
| `/fluent-workflow` | Receives the READY verdict for workflow-only deploys | Output |
| `/fluent-session` | All gate executions are tracked for audit trail; checklist report path recorded in audit document | Bidirectional |
| `/fluent-rollback` | Revert to previous version if post-deploy issues are discovered | Output |

### Recommended Sequencing in ADD Lifecycle

```
/fluent-scope-decompose  ->  /fluent-rule-scaffold  ->  /fluent-build
      |                            |                        |
      v                            v                        v
/fluent-workflow-builder  ->  /fluent-version-manage  ->  /fluent-pre-deploy-check
                                                              |
                                            READY? ---------> /fluent-module-deploy
                                            BLOCKED? -------> Fix issues, re-run
```

---

## Edge Cases

### No module path (workflow-only deploy)
Phases 2, 7.2, and 7.3 are auto-skipped. The report module field is set to `null` and the filename uses the primary workflow name. Phase 3-4 gates still execute normally.

### No workflows (module-only deploy)
Phases 3 and 4 are auto-skipped. Phase 5 still runs because settings may be module-related. Phase 7.1 reports change scope based on source files only.

### Multiple modules in SOURCE directory
When auto-detection finds multiple `resources/module.json` files, the skill lists them and asks the user to select one. Alternatively, the user can run the checklist multiple times with explicit `--module-path` for each module.

### First-time deployment (no previous version)
Gates 2.4 (version bumped), 3.4 (no breaking removals), and 7.2 (rollback path) pass automatically with informational notes indicating this is a first deployment.

### MCP tools unavailable
If MCP tools fail (connection error, timeout), the affected gate records `result: "ERROR"` instead of PASS/FAIL. ERROR gates do not block deployment but are flagged prominently in the report with the recommendation to fix MCP connectivity and re-run.

### Module validates but build has not been run recently
Gate 2.1 always runs a fresh `mvn clean install` to ensure the build is current. It does not rely on cached build artifacts. This adds time but guarantees the build state matches the source.

### Settings referenced by rules that are not yet deployed
When Gate 3.3 (rules exist) fails, Gate 5.1 (settings exist) may also show misleading results because the settings may be correct but the rules referencing them are not yet registered. The report includes a cross-reference note: "Settings validation may be incomplete because some rules are not yet deployed."

### Windows platform
All Bash invocations use cross-platform patterns. Maven commands use the same syntax on Windows (the `mvn` wrapper handles platform differences). File path operations use forward slashes in report output for consistency.

---

## Troubleshooting

| Issue | Likely Cause | Fix |
|-------|-------------|-----|
| Gate 1.1 fails with auth error | Expired token or wrong profile | Run `fluent profile update <PROFILE> --password <new-pass>` or check profile directory |
| Gate 2.1 hangs | Maven downloading dependencies | Wait for completion or check network; set timeout with `mvn -T 5m` |
| Gate 3.3 shows many missing rules | Module not yet deployed | Deploy module first, then re-run checklist for workflows |
| Gate 5.1 shows MISSING for module-installed settings | Settings deployed at ACCOUNT scope | Cascading resolution should find these; check `contextId=0` query |
| Gate 6.2 returns ERROR | Prometheus not configured on environment | Gate passes with warning; recommend manual health check |
| Gate 7.3 false positives | Test email addresses in production code | Move test data to `src/test/` or add to exclusion list |
| All gates pass but deployment still fails | Runtime issue not covered by static checks | Run `/fluent-e2e-test` after deployment to validate runtime behavior |
| Report file path too long on Windows | Module name with many segments | Use the `--` separator convention to keep filenames reasonable |

## 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-pre-deploy-check"`
   - `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-pre-deploy-check.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 -->
