# Autonomous Development Workflow

> [!CAUTION]
> **🧪 EXPERIMENTAL — LABS PROJECT**
> This package is not production-ready. No stability guarantees, no support, no warranty. See [README](../README.md) for full disclaimer.

Orchestration protocol for AI agents to analyze existing Fluent Commerce implementations, add new functionality, deploy, test end-to-end, and fix issues in a seamless loop.

## Overview

```
WORKSPACE CHECK → ANALYZE → EXPLAIN (if requested) or PLAN → [USER APPROVAL] → IMPLEMENT → VALIDATE → BUILD → DEPLOY → TEST → DIAGNOSE → FIX → (loop back)
```

This is a closed loop with a mandatory planning gate. After analysis, the agent presents a structured implementation plan (workflow changes, settings, rules, Mermaid diagrams, risk assessment, test plan) and waits for explicit user approval before making changes. The agent then continues iterating until all E2E tests pass or an unresolvable blocker is hit (missing credentials, infrastructure down, ambiguous requirements). The planning gate is skipped for pure read-only tasks (tracing, monitoring, querying). When the user asks to **explain** an existing feature instead of change it, the EXPLAIN phase produces a Feature Architecture Document (persisted to `accounts/<PROFILE>/features/<slug>/architecture.md`) and terminates — no PLAN/IMPLEMENT needed.

**Three-agent architecture:** The `fluent-dev` orchestrator routes work to domain-specific agents: `fluent-backend-dev` (workflows, rules, modules, settings, events, deployment) and `fluent-frontend-dev` (Mystique manifests, SDK components, manifest validation, UI analysis, browser UI testing). Cross-domain features use `/fluent-feature-plan` at the orchestrator level. Frontend work follows: `/fluent-mystique-builder` → `/fluent-mystique-validate` → deploy via `/fluent-settings` (setting upsert) → optionally `/fluent-ui-test` (browser verification via Chrome DevTools MCP). Custom SDK components: `/fluent-mystique-scaffold` → `/fluent-frontend-build` (7-gate pipeline incl. GraphQL schema validation) → `/fluent-frontend-review` (9-phase code quality audit incl. GraphQL) → `/fluent-frontend-readme` (docs) → self-host bundle → update manifest `plugins[]`.

Event API documentation is incorporated using selective extraction (operational, tool-anchored guidance only), not full-text mirroring.

### Agent Routing

The development lifecycle uses a three-agent architecture:

- **`fluent-dev` (orchestrator)** — receives user requests, routes to the appropriate domain agent, and handles cross-cutting tasks (feature planning, E2E testing, session tracking)
- **`fluent-backend-dev`** — executes backend phases: workflow analysis, rule scaffolding, module building, deployment, event tracing
- **`fluent-frontend-dev`** — executes frontend phases: manifest building, SDK component scaffolding, SDK build/test/verify, code quality review, README generation, manifest validation, deployment as settings

**Routing decision:** If the request mentions workflows, rules, modules, settings, events, or Java → backend. If it mentions manifests, pages, components, UI, or Mystique → frontend. If it spans both → orchestrator creates a unified plan, then dispatches to each domain.

---

## Phase 0: Workspace Check

Before analyzing, ensure the workspace is initialized for the target profile.

1. Check if `accounts/<PROFILE>/workspace-state.json` exists.
2. If it exists, compute the content hash and compare with the stored `contentHash`.
3. If hashes match: workspace is current. Print summary and proceed to Phase 1.
4. If missing or stale: run `/fluent-connect --profile <PROFILE>` to discover profiles, wire MCP, download workflows, scan source repos, decompile JARs, build rule inventory, and persist state.
5. After connect completes, proceed to Phase 1 with all artifacts available.

This ensures all downstream phases have workflows, source code, decompiled artifacts, and connectivity state ready before any analysis begins. See `/fluent-connect` for the full onboarding protocol.

---

## Phase 1: Analyze Existing State

Before making any changes, build a full picture of the current implementation.

### 1.0 Account workspace intake

Use one account-scoped workspace:

- `accounts/<PROFILE>/SOURCE/backend/` — Java Maven plugin repos and module artifacts (`*.jar`, `*.zip`) — account-level, shared across retailers
- `accounts/<PROFILE>/SOURCE/frontend/` — Mystique SDK component projects (package.json, webpack, src/index.tsx)
- `accounts/<PROFILE>/workflows/<RETAILER_REF>/` — downloaded workflow JSON — retailer-scoped
- `accounts/<PROFILE>/analysis/` — generated reusable artifacts

Rules:

1. Prefer local evidence first (source + artifacts already under `SOURCE/backend/`).
2. If artifacts exist, decompile into `accounts/<PROFILE>/SOURCE/backend/.decompiled/<artifact-name>/` and include in analysis.
3. Treat JAR/ZIP and decompiled output as read-only evidence.
4. Recommend source-level implementation options; if only artifacts are present, request source onboarding before code changes.

Always keep workflow context explicit for safety:

5. Download and edit workflows only under `accounts/<PROFILE>/workflows/<RETAILER_REF>/`.
6. Persist `workflow-context.json` in that folder and verify it before merge/upload.

### 1.1 Verify connectivity

Call these MCP tools in sequence — stop if any fails:

```
config.validate  →  must return ok: true
health.ping      →  must return ok: true
connection.test  →  must return ok: true (also reveals retailerId, user context)
```

If `config.validate` fails: environment variables are missing or wrong. Report and stop.
If `connection.test` fails: auth or network issue. Report and stop.

### 1.2 Discover deployed workflows

```
fluent workflow list -p <PROFILE> -r <RETAILER_REF>
```

Parse the output to get all workflow names, entity types, and versions. Store this as the baseline.

### 1.3 Reusable custom-code artifacts

If `accounts/<PROFILE>/analysis/code/` exists, read and reuse these artifacts before re-scanning. Downstream phases (Implement, Trace, Rule Scaffold) should consume them first. Regenerate via `/fluent-custom-code` when stale or out-of-scope.

| File | Purpose |
|------|---------|
| `source-map.json` | Maps rule names to source file paths |
| `workflow-rule-map.json` | Maps workflow rulesets/rules to implementing classes |
| `constraints.json` | Extracted constraints and invariants |
| `behavior-map.md` | Human-readable behavior summary |
| `extension-plan.md` | Suggested extension points and changes |
| `fingerprint.json` | Input fingerprint/hash manifest used to decide reuse vs regenerate |

Use incremental refresh by default:
- Rule source changed -> refresh `source-map.json` + impacted rows in `workflow-rule-map.json` + relevant `constraints.json` risks.
- Workflow JSON changed -> refresh `workflow-rule-map.json` + `behavior-map.md`.
- Test-only change -> refresh test metadata in `source-map.json` only.
- Structure/module metadata change -> full regenerate.

### 1.4 Download relevant workflows

For each workflow relevant to the task:

```
fluent workflow download -p <PROFILE> -r <RETAILER_REF> -w all -o accounts/<PROFILE>/workflows/<RETAILER_REF>/
```

Write/update retailer context at:

`accounts/<PROFILE>/workflows/<RETAILER_REF>/workflow-context.json`

```json
{
  "profile": "<PROFILE>",
  "retailerRef": "<RETAILER_REF>",
  "retailerId": "<RETAILER_ID>",
  "baseUrl": "<FLUENT_BASE_URL>",
  "downloadedAt": "<ISO-8601>"
}
```

Before merge/upload, verify the command target (`-p`, `-r`) matches this context file.

Read the downloaded JSON. Extract:
- All rulesets (name, triggers, rules with props)
- All statuses (name, category)
- The state machine: which events transition between which statuses
- Gate rulesets: which rulesets check child entity statuses before advancing

### 1.4A Query live transitions

Use `workflow.transitions` to complement workflow JSON analysis with runtime-confirmed transitions:

```
workflow.transitions({
  "triggers": [{
    "type": "ORDER",
    "subtype": "HD",
    "status": "CREATED",
    "retailerId": "<RETAILER_ID>",
    "flexType": "ORDER::HD"
  }]
})
```

This reveals:
- Which user actions are available at each status (runtime truth vs. workflow JSON definition)
- Required attributes for each action (avoids missing-attribute errors during testing)
- UI context (button labels, modules, confirmation dialogs)

### 1.5 Discover deployed modules and rules

```
fluent module list -p <PROFILE>
```

If the project has local source code, scan it:

```
Glob: plugins/rules/**/src/main/java/**/*.java
Grep: @RuleInfo in those files → extract rule names
Read: resources/module.json → extract registered rules and version
Read: pom.xml (and parent pom) → extract groupId/artifactId/version when module.json is missing or incomplete
```

If JAR/ZIP artifacts are already under `accounts/<PROFILE>/SOURCE/backend/`, decompile to:

`accounts/<PROFILE>/SOURCE/backend/.decompiled/<artifact-name>/`

Then include that decompiled tree in rule mapping before asking for more inputs.

Module identity precedence (store in analysis artifacts):
- `symbolicName`: `module.json.name` -> manifest `Bundle-SymbolicName` -> `<groupId>/<artifactId>`
- `version`: `module.json.version` -> `pom project.version` (or `parent.version`) -> manifest `Implementation-Version` / `Bundle-Version`

### 1.5A If source code is unavailable

When rule logic cannot be validated from workflow JSON alone:

1. Request module artifacts (ZIP/JAR) from the deployed build.
2. Extract `module.json` and map workflow rule names to Java class names.
3. Decompile to `accounts/<PROFILE>/SOURCE/backend/.decompiled/<artifact-name>/` and start with suspected rule classes first (avoid full artifact noise).
4. Confirm actual behavior (props read, queries/mutations/events executed, guards/status checks).
5. Keep confidence labels in notes: **confirmed by source/decompile** vs **inferred from workflow metadata**.

### 1.6 Query live entity state (if investigating a specific entity)

Use MCP `graphql.query`:

**Orders:**
```graphql
{ orders(ref: ["<REF>"], first: 1) { edges { node {
  id ref type status createdOn updatedOn
  attributes { name type value }
  fulfilmentChoice { id ref type status deliveryType }
  fulfilmentChoices { edges { node { id ref type status deliveryType } } }
  items { edges { node { ref quantity status fulfilmentChoice { id ref type status deliveryType } } } }
} } } }
```

Use `items[].fulfilmentChoiceRef` only on `createOrder` input. For schema-validated `ORDER::MULTI` input and readback patterns, see `content/knowledge/platform/create-order-reference.md`.

**Fulfilments:**
```graphql
{ fulfilments(ref: ["<REF>"], first: 1) { edges { node {
  id ref type status
  attributes { name type value }
  items { edges { node { ref status requestedQuantity filledQuantity } } }
  order { id ref status }
  fromLocation { ref name }
} } } }
```

### 1.7 Query event history (if investigating failures)

```
event.list({ "context.entityRef": "<REF>", "context.entityType": "<TYPE>", "count": 50 })
```

Filter failed events:
```
event.list({ "context.entityRef": "<REF>", "eventStatus": "FAILED", "count": 50 })
```

For each failed event, get details:
```
event.get({ "eventId": "<ID>" })
```

For event-model semantics, filter capabilities, and causality patterns (`context.sourceEvents`, root-entity tracing), use `/fluent-event-api` alongside this phase.

### 1.8 Check settings

```graphql
{ settings(first: 1, context: "RETAILER", contextId: <RETAILER_ID>, name: ["<SETTING_NAME>"]) {
  edges { node { id name value lobValue } }
} }
```

### 1.9 Connection topology and dependency mapping

Run `/fluent-connection-analysis` on the target workflow(s) to map:
- Internal, cross-entity, and cross-workflow event edges
- Orphaned rulesets and missing SendEvent targets
- Process flow classification (CREATE, SCHEDULED, CROSS_ENTITY, USER_ACTION, INTERNAL, INTEGRATION)
- Webhook and setting dependency inventory

If investigating a specific entity, use `--validate <entity-ref> --entity-type <TYPE>` to compare static expected paths against actual runtime events (static-vs-dynamic diff).

### 1.10 Retailer environment baseline

If environment setup is needed (new locations, networks, catalogues), use `/fluent-retailer-config` to create or verify infrastructure entities before testing.

### 1.11 Platform health check

For broad platform issues or intermittent failures, run `/fluent-system-monitoring` to check aggregate event metrics, error rate trends, and queue health.

### 1.12 Batch/job pipeline check

If the workflow involves batch ingestion or JOB entities, use `/fluent-job-batch` to trace job lifecycle and diagnose ingestion failures.

### Analysis output

After Phase 1, the agent should have:
- Current workflow structure (rulesets, states, transitions)
- Connection topology and dependency map (if connection-analysis was run)
- Registered rules and their source code (if local)
- Entity state and event history (if investigating)
- Settings relevant to the task
- Evidence quality notes (confirmed vs inferred behavior)
- Clear understanding of what exists vs. what needs to change

---

## Phase 1b: Explain (Feature Architecture Document)

**When the user asks to understand an existing feature** rather than change it, route here instead of Phase 1.5.

Invoke `/fluent-feature-explain` which orchestrates:
1. Workflow structure analysis (status machines, event chains, process flow classification)
2. Rule logic analysis — **tiered evidence approach**:
   - **Tier 1:** `plugin.list` descriptions and parameters (always available)
   - **Tier 2:** Source code analysis — original source (`accounts/<PROFILE>/SOURCE/backend/`) or decompiled JARs (`backend/.decompiled/`). Invokes `/fluent-custom-code` for JAR decompilation if needed.
   - **Tier 3:** Runtime evidence — auto-discovers existing entities via GraphQL before asking user
3. Connection topology (cross-entity flows, webhooks, settings dependencies)
4. Runtime evidence (adaptive — auto-discovers entities, escalates source depth when no runtime)

**Output:** A Feature Architecture Document saved to `accounts/<PROFILE>/features/<slug>/architecture.md` containing:
- Entity lifecycle state diagrams (Mermaid `stateDiagram-v2`)
- Cross-entity sequence diagrams (Mermaid `sequenceDiagram`)
- Event chain flowcharts (Mermaid `flowchart TD`)
- Input → Output data flow tables
- Rules & logic per ruleset (custom vs OOTB, source file paths)
- Settings dependencies with current values
- Integration points (webhooks, scheduled events, external systems)
- Runtime evidence timeline (when entity ref provided)
- **Analysis Confidence section** — per-rule evidence levels (HIGH/MEDIUM/LOW) with recommendations for higher confidence

**Terminates here.** No PLAN/IMPLEMENT phases needed — this is read-only documentation output.

---

## Phase 1.5: Plan & Approve (Check Gate)

**Mandatory gate.** After analysis, present a structured implementation plan and wait for user approval before any changes.

**Skip** for pure read-only tasks (tracing, monitoring, querying entity state).

### Plan structure

Present in this order:

1. **Business context** — What problem, why now
2. **Current state** — Specific workflow names, ruleset names, setting keys
3. **Proposed changes** — Workflow changes (with Mermaid before/after), settings changes, rule/plugin changes, entity/data changes, deployment sequence
4. **Flow visualization** — Mermaid `stateDiagram-v2` for state machines, `sequenceDiagram` for cross-entity flows
5. **Risk assessment** — Breaking existing flows, runtime exceptions, missing dependencies
6. **Test plan** — Happy path, new path, edge cases, regression
7. **Rollback plan** — How to revert if issues arise

### Approval protocol

1. **STOP** — Do not proceed to Phase 2
2. **Approved** → proceed to Phase 2
3. **Changes requested** → revise plan, re-present
4. **Rejected** → restart from Phase 1 with different approach
5. **Partially approved** → proceed with approved sections only

See `fluent-dev` agent's "Phase 2: Plan & Approve (CHECK GATE)" section for the full template.

---

## Phase 2: Implement Changes

Based on the approved plan, determine what type of change is needed and execute the appropriate path.

### Decision tree

```
What needs to change?
│
├─ Workflow structure (new rulesets, states, triggers)
│  └─ Go to 2.1: Edit Workflow
│
├─ Business logic (new/modified rule behavior)
│  └─ Go to 2.2: Create or Edit Rule
│
├─ Configuration (settings, data)
│  └─ Go to 2.3: Update Settings/Data
│
├─ Multiple of the above
│  └─ Execute each applicable section in order: 2.1 → 2.2 → 2.3
│
└─ Unknown (need more investigation)
   └─ Return to Phase 1 with more specific queries
```

### 2.1 Edit workflow

Read the current workflow JSON from `accounts/<PROFILE>/workflows/<RETAILER_REF>/` (or an explicitly provided local file after context check).

**Adding a new ruleset:**

Build the ruleset JSON following the structure:
```json
{
  "name": "<RulesetName>",
  "description": "[<ENTITY_TYPE>] What this ruleset does",
  "type": "<ENTITY_TYPE>",
  "eventType": "NORMAL",
  "rules": [
    {
      "name": "<ACCOUNT>.<MODULE>.<RuleName>",
      "props": { "key": "value" }
    }
  ],
  "triggers": [{ "status": "<STATUS>" }],
  "userActions": []
}
```

If triggers is empty `[]`, the ruleset fires when an event with matching name arrives.

**Validation — check ALL of these before proceeding:**
- [ ] Every `SetState` target status exists in the `statuses` array
- [ ] Every `SendEvent` target has a matching ruleset name
- [ ] Rule names follow `<ACCOUNT>.<MODULE>.<RuleName>` format
- [ ] No duplicate ruleset names
- [ ] Version is bumped from currently deployed version
- [ ] `versionComment` describes what changed

**Adding a new status:** Add to the `statuses` array:
```json
{ "name": "NEW_STATUS", "category": "FULFILMENT", "entityType": "ORDER" }
```

Categories: `BOOKING`, `FULFILMENT`, `DONE`, `PAYMENT`

**Adding a gate ruleset:** Gates check child entity statuses before advancing parent:
```json
{
  "name": "CheckAllFulfilmentsComplete",
  "rules": [{
    "name": "ACCT.core.SendEventOnVerifyingAllFcStatus",
    "props": { "eventName": "AdvanceOrder", "statuses": "DELIVERED,CANCELLED" }
  }],
  "triggers": [],
  "userActions": []
}
```

The `statuses` prop must include ALL terminal states for child entities.

### 2.2 Create or edit rule

**New rule — use scaffolding pattern:**

Determine:
- Rule name (PascalCase, descriptive)
- Target package (`common`, `order`, `fulfilment`, etc.)
- What props it needs (`@ParamString` annotations)
- What it does (query? mutate? send event? set attribute?)

Create the Java class at:
```
plugins/rules/<MODULE_NAME>/src/main/java/com/fluentcommerce/rule/<package>/<RuleName>.java
```

Must extend `BaseRule` and implement `run(ContextWrapper context)`.

Create the test class at:
```
plugins/rules/<MODULE_NAME>/src/test/java/com/fluentcommerce/rule/<package>/<RuleName>Test.java
```

Wire into `resources/module.json` — add rule name to the `rules` array.

**Editing an existing rule:**

Find the rule class:
```
Grep: @RuleInfo(name = "<RuleName>" across plugins/rules/**/src/main/java/
```

Make changes. Run the unit test for that specific rule to verify:
```bash
cd plugins && mvn test -pl rules/<module-alias> -Dtest="<RuleName>Test"
```

**Gotchas to avoid:**
- `@ParamString` names are CASE-SENSITIVE
- `context.action().mutation()` only QUEUES — mutation executes AFTER rule returns
- `DynamicMutation.buildMutationDocument` appends `!` — never include `!` in type names
- `updateFulfilmentItem` does NOT exist — use `updateFulfilment` with nested `items`
- Implement `run(ContextWrapper context)`, not `run(Context context)`

### 2.3 Update settings or data

**Settings** — via GraphQL mutation:
```
graphql.query({
  query: "mutation($input: UpdateSettingInput!) { updateSetting(input: $input) { id ref } }",
  variables: { "input": { "id": "<ID>", "lobValue": "<JSON_STRING>" } }
})
```

**Bulk data** — via batch mutations:
```
graphql.batchMutate({
  mutation: "updateOrder",
  inputs: [{ "id": "1", "status": "NEW_STATUS" }, ...],
  returnFields: ["id", "ref", "status"]
})
```

---

## Phase 2.5: Validate Module Structure

Before building, run `/fluent-module-validate` to catch structural issues early.

The validator uses a **content hash** to skip re-validation when module files are unchanged. Any edit to `.java`, `.json`, `.xml`, `.sh`, or `.ps1` files produces a new hash and triggers a fresh validation.

```
/fluent-module-validate accounts/<PROFILE>/SOURCE/backend/<repo>/<module-root>
```

If the report exists and hash matches, it prints "Module unchanged" and stops immediately. Otherwise it runs all 9 checks and writes:
- `accounts/<PROFILE>/reports/module-validate/<name>.report.json`
- `accounts/<PROFILE>/reports/module-validate/<name>.hash`

**Gate rule**: Do not proceed to Phase 3 if `summary.status === "NEEDS_FIXES"`. Fix FAILs first.

After applying fixes (e.g., new rule class, version bump), the hash will change automatically and the next `/fluent-module-validate` invocation re-runs validation.

---

## Phase 3: Build and Package

Only needed if Java code changed. Skip to Phase 4 if only workflow/settings changed.

### 3.1 Bump version

Fluent ignores re-uploads of the same module version. Update ALL of these:

| File | Field |
|------|-------|
| `plugins/pom.xml` | parent `<version>` |
| `plugins/rules/<MODULE_NAME>/pom.xml` | parent + module `<version>` |
| `plugins/types/<MODULE_NAME>/pom.xml` | parent + module `<version>` |
| `plugins/util/<MODULE_NAME>/pom.xml` | parent + module `<version>` |
| `resources/module.json` | `"version"` |

Read current version from `resources/module.json`, increment patch, update all files.

### 3.2 Compile

```bash
cd plugins && mvn clean install
```

**If compilation fails:**

| Error | Fix |
|-------|-----|
| `cannot find symbol` | Check imports, verify changed class references |
| `dependency not found` | Run from `plugins/` with `-am` flag |
| Test failures | Update test fixtures/expected values, or run `-DskipTests` to defer |

Fix and retry until clean build.

### 3.3 Package

```bash
./scripts/build-module.sh
# or on Windows:
powershell ./scripts/build-module.ps1
```

Verify output: `dist/<MODULE_ARTIFACT_NAME>-<VERSION>.zip`

---

## Phase 4: Deploy

### Decision tree

```
What changed?
│
├─ Java rules (+ possibly workflow)
│  └─ Deploy full module ZIP
│     fluent module install dist/<module>.zip \
│       --retailer <RETAILER_REF> --profile <PROFILE>
│
├─ Workflow JSON only (no code changes)
│  └─ Upload workflow directly via REST API:
│     curl -X PUT "$BASE_URL/api/v4.1/workflow" \
│       -H "Authorization: Bearer $TOKEN" \
│       -d @workflow.json
│     NOTE: Requires retailer-scoped token, not account-level.
│
├─ Settings/data only
│  └─ Already applied via GraphQL mutations in Phase 2.3. No deploy needed.
│
└─ Module + workflow with different workflow version
   └─ Deploy module with --exclude workflows, then upload workflow separately
```

### Post-deploy verification

After deploy, verify:
```bash
fluent module list -p <PROFILE>           # Module version matches
fluent workflow list -p <PROFILE> -r <RETAILER_REF>  # Workflow version matches
```

---

## Phase 5: Test End-to-End

Run E2E test sequences to verify the deployed changes work.

### 5.1 Choose scenario

| Scenario | When to use |
|----------|------------|
| ORDER HD | Testing home delivery flow changes |
| ORDER CC | Testing click & collect flow changes |
| Cancel Order | Testing cancellation handling |
| Short Pick | Testing partial fulfilment handling |
| Custom | When change affects a specific path not covered above |

### 5.2 Execute test sequence

Each test follows this pattern:

```
For each step in the scenario:
  1. SEND event via event.send (mode: "async")
  2. WAIT (initial delay: 3s for simple events, 15s after ConfirmValidation cascade)
  3. QUERY entity status via graphql.query
  4. COMPARE actual status to expected status
  5. If match → PASS, continue to next step
  6. If no match → RETRY (wait 5s, query again, up to 6 retries = 30s)
  7. If still no match after retries → FAIL, go to Phase 6
```

**Dynamic test sequence option:** Instead of hardcoded steps, use `workflow.transitions` at each
state to discover the next available action:

```
1. Create entity
2. workflow.transitions → discover actions at current status
3. Pick the expected action from userActions[]
4. event.send with eventName and required attributes from response
5. Poll entity status until transition completes
6. workflow.transitions → discover next actions
7. Repeat until no more userActions (terminal state)
```

This approach adapts automatically when workflows change and validates that expected
user actions are available at each step.

### 5.3 Create test order

**Run `/fluent-test-data` discovery first** to obtain all refs from the live environment. Never hardcode product SKUs, location refs, addresses, or prefixes — they differ per retailer.

The discovery sequence queries: retailer context → locations → networks → product catalogues → products with inventory → customers → settings (consignment prefix).

Once discovery is complete, build the `createOrder` mutation using discovered values:

```
graphql.query({
  query: "mutation($input: CreateOrderInput!) { createOrder(input: $input) { id ref status } }",
  variables: { input: {
    ref: "E2E_HD_<TIMESTAMP>",
    type: "MULTI",
    retailer: { id: "<discovered.retailerId>" },
    customer: { id: "<discovered.customerId>" },
    items: [{ ref: "<discovered.productRef>", quantity: 1, productRef: "<discovered.productRef>",
              productCatalogueRef: "<discovered.catalogueRef>",
              fulfilmentChoiceRef: "E2E_HD_<TIMESTAMP>-FC-HD" }],
    fulfilmentChoice: {
      ref: "E2E_HD_<TIMESTAMP>-FC-HD", type: "HD", deliveryType: "STANDARD",
      deliveryAddress: { ref: "E2E_HD_<TIMESTAMP>-ADDR",
                         name: "<discovered.location.primaryAddress.name or 'Test Delivery'>",
                         street: "<discovered.location.primaryAddress.street>",
                         city: "<discovered.location.primaryAddress.city>",
                         postcode: "<discovered.location.primaryAddress.postcode>",
                         country: "<discovered.location.primaryAddress.country>" },
      attributes: [
        { name: "sourcingLocationRef", type: "STRING", value: "<discovered.warehouseRef>" },
        { name: "consignmentPrefix", type: "STRING", value: "<discovered.consignmentPrefix or 'A_'>" }
      ]
    }
  }}
})
```

See `/fluent-test-data` for the full discovery flow and entity creation templates (HD, CC, customer).

### 5.4 Fire events and assert

**ORDER HD full lifecycle:**

| Step | Event | Entity | Expected Status | Wait |
|------|-------|--------|----------------|------|
| 1 | *(auto on create)* | ORDER | CREATED → ON_VALIDATION | 3s |
| 2 | `ConfirmValidation` | ORDER | IN_PROGRESS + Fulfilment CREATED | **15s** (async cascade) |
| 3 | `ConfirmAllocation` | FULFILMENT | RECEIVED | 5s |
| 4 | `CreateInvoice` | FULFILMENT | INVOICED | 5s |
| 5 | `ConfirmPick` | FULFILMENT | PICKPACK | 5s |
| 6 | `ConfirmShipment` | FULFILMENT | SHIPPED | 5s |
| 7 | `ConfirmDelivery` | FULFILMENT | DELIVERED | 5s |

After step 2, query fulfilments to get the generated fulfilment ref (pattern: `<consignmentPrefix><FC-ref>-<locationRef>`). All subsequent events target this ref.

**Event attributes required per step:**

| Event | Attributes |
|-------|-----------|
| `ConfirmPick` | `pickedAt` (ISO datetime), `pickedItems` (JSON array) |
| `ConfirmShipment` | `trackingNumber`, `carrierRef`, `shippedAt` (ISO datetime) |
| `ConfirmDelivery` | `deliveredAt` (ISO datetime) |

### 5.5 Record results

Track each step: event sent, expected status, actual status, pass/fail, duration. If all steps pass, the change is verified. Report results and stop.

If any step fails → proceed to Phase 6.

---

## Phase 5b: Browser UI Verification (Optional)

**When to use:** After deploying a Mystique manifest change, verify that the UI renders correctly in the browser. This phase is optional and requires Chrome DevTools MCP to be configured in `.mcp.json`.

**Skip** when: No manifest changes were deployed, Chrome DevTools MCP is not available, or backend-only changes.

### 5b.1 Pre-flight

1. Verify Chrome DevTools MCP is connected (search for `navigate_page` tool availability)
2. Determine target app URL: `https://<account>.<env>.apps.engineering.fluentcommerce.com/<appName>` — where `<appName>` is `oms` (OMS App), `store` (Store App), or `servicepoint` (Store App legacy URL alias)
3. If credentials are not configured, ask the user for login details

### 5b.2 Execute browser test

```
1. navigate_page → target app URL
2. Handle login if required (fill username/password, submit)
3. navigate_page → specific page/route being tested
4. take_snapshot → DOM snapshot (verify page structure, component rendering)
5. list_console_messages → check for React errors, GraphQL failures, uncaught exceptions
6. take_screenshot → visual evidence
```

### 5b.3 Verify

Check the following against expected behavior:
- Page loads without errors (no blank pages, no error boundaries)
- Key components render with data (lists have rows, forms have fields)
- Navigation works (routes resolve, breadcrumbs correct)
- User actions appear for the current workflow status (if applicable)
- No console errors or GraphQL failures

### 5b.4 Report

Produce a pass/fail report with:
- Checks performed (login, page load, data load, component rendering)
- Screenshot evidence (file path)
- Issues found with severity (CRITICAL for page errors, MEDIUM for missing components, LOW for cosmetic)
- Remediation steps for any failures

If issues are found → route back to Phase 2 (manifest editing) or Phase 4 (redeploy).

---

## Phase 6: Diagnose and Fix

### 6.1 Identify failure point

From the test results, identify:
- Which step failed
- What entity ref and type
- What was the expected vs actual status
- Was the event processed (SUCCESS/FAILED/PENDING)?

### 6.2 Trace the failure

Query event history for the entity:
```
event.list({ "context.entityRef": "<REF>", "context.entityType": "<TYPE>", "eventStatus": "FAILED", "count": 50 })
```

For failed events, get details:
```
event.get({ "eventId": "<ID>" })
```

For deep causality analysis (parent -> child event chains, cross-entity timelines, source pattern interpretation), route to `/fluent-event-api`. `/fluent-trace` remains the owner of the root-cause decision tree.

### 6.3 Decision tree

```
What happened?
│
├─ Event FAILED with error message
│  ├─ "Rule exception" → Rule code bug. Read the rule source, check props, fix code.
│  ├─ "No matching ruleset" → Event name doesn't match any ruleset. Fix workflow.
│  ├─ "Entity not found" → Wrong entityRef. Fix the test or check entity creation.
│  └─ "Permission denied" → Check retailerId scope (account-level users get retailerId=0).
│
├─ Event SUCCESS but wrong status
│  ├─ Gate not met → Query all child entities, check if they're in expected terminal states.
│  ├─ Wrong ruleset fired → Check trigger status conflicts in workflow.
│  └─ Rule ran but did something unexpected → Read rule code, check props.
│     If rule logic is unclear from available files → request source or decompile JAR/ZIP.
│
├─ Event PENDING (stuck)
│  └─ Wait 15-30s and retry. If still pending, async queue may be backlogged.
│
├─ No event found
│  └─ Event was never sent, or sent to wrong entityRef/entityType. Check test logic.
│
└─ Entity in unexpected intermediate state
   └─ Async cascade still running. Wait and re-query.
      If stuck > 60s: check if a gate condition is blocking. Query child entities.
```

### 6.4 Apply fix

Based on diagnosis, apply the fix:

| Root cause | Fix action | Next phase |
|-----------|------------|------------|
| Rule code bug | Edit Java source, fix logic | → Phase 3 (Build) |
| Rule behavior unclear from workflow metadata | Request source/JAR, decompile targeted classes, confirm actual logic | → Phase 1 (Analyze) |
| Missing/wrong workflow ruleset | Edit workflow JSON | → Phase 4 (Deploy) |
| Wrong props in ruleset | Edit workflow JSON | → Phase 4 (Deploy) |
| Missing status in workflow | Add to `statuses` array | → Phase 4 (Deploy) |
| Gate statuses incomplete | Update gate ruleset props | → Phase 4 (Deploy) |
| Setting value wrong | Update via GraphQL mutation | → Phase 5 (Test) |
| Test data issue | Fix test inputs | → Phase 5 (Test) |
| New rule needed | Create rule + update workflow | → Phase 2 (Implement) |

After fixing, loop back to the indicated phase and continue through to Phase 5 (Test) again.

### 6.5 Loop termination

The loop terminates when:
- **All E2E test steps pass** → Report success with entity refs, event IDs, versions deployed
- **Unresolvable blocker** → Report what was tried, what failed, what needs human intervention
- **Requirements unclear** → Report what was analyzed, what options exist, ask for clarification

---

## Cross-Skill Handoff Protocol

When orchestrating across skills, use these handoff patterns:

| From | To | Handoff data |
|------|----|-------------|
| Analyze (Phase 1) | Implement (Phase 2) | Workflow JSON, rule list, entity state, identified gaps |
| Implement (Phase 2) | Validate (Phase 2.5) | Changed files list, new rule names, updated module.json |
| Validate (Phase 2.5) | Build (Phase 3) | Validation report (READY_FOR_BUILD / NEEDS_FIXES), content hash |
| Build (Phase 3) | Deploy (Phase 4) | ZIP path, new version number, what changed (code/workflow/both) |
| Deploy (Phase 4) | Test (Phase 5) | Deployed version, retailer, profile, entity type affected |
| Test (Phase 5) | Diagnose (Phase 6) | Failed step, entity ref, event name, expected vs actual status |
| Diagnose (Phase 6) | Fix (Phase 2/3/4) | Root cause, specific file/ruleset/prop to change |

## MCP Tool Quick Reference

| Operation | Tool | Server |
|-----------|------|--------|
| Verify connectivity | `config.validate`, `health.ping`, `connection.test` | fluent-mcp-extn |
| Query entities | `graphql.query` | fluent-mcp-extn |
| Query all (paginated) | `graphql.queryAll` | fluent-mcp-extn |
| Create/update entities | `graphql.query` (with mutation) | fluent-mcp-extn |
| Bulk update | `graphql.batchMutate` | fluent-mcp-extn |
| Discover schema | `graphql.introspect` | fluent-mcp-extn |
| Send event | `event.send` | fluent-mcp-extn |
| Check event result | `event.list`, `event.get` | fluent-mcp-extn |
| Build event payload | `event.build` | fluent-mcp-extn |
| Discover transitions | `workflow.transitions` | fluent-mcp-extn |
| List workflows | CLI: `fluent workflow list` | fluent-mcp (official) |
| Download workflow | CLI: `fluent workflow download` | fluent-mcp (official) |
| Upload workflow | REST: `PUT /api/v4.1/workflow` | Direct API call |
| Deploy module | CLI: `fluent module install` | Direct CLI |
| Navigate browser | `navigate_page` | chrome-devtools |
| Page snapshot | `take_snapshot` | chrome-devtools |
| Screenshot | `take_screenshot` | chrome-devtools |
| Console errors | `list_console_messages` | chrome-devtools |
| Click element | `click` | chrome-devtools |
| Type text | `type_text` | chrome-devtools |

## Related

- [Operational Reference](fluent-ai-skills-reference.md) — architecture, MCP tools, feature lifecycle, deployment runbook, CLI reference
- [Capability Map](capability-map.md) — which skill owns what capability
- [Chrome DevTools MCP](chrome-devtools-mcp-reference.md) — browser automation and UI testing reference
- [Use Cases](use-cases.md) — 21 scenario-based walkthroughs with exact prompts
