@fluentcommerce/ai-skills 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +622 -0
  3. package/bin/cli.mjs +1973 -0
  4. package/content/cli/agents/fluent-cli/agent.json +149 -0
  5. package/content/cli/agents/fluent-cli.md +132 -0
  6. package/content/cli/skills/fluent-bootstrap/SKILL.md +181 -0
  7. package/content/cli/skills/fluent-cli-index/SKILL.md +63 -0
  8. package/content/cli/skills/fluent-cli-mcp-cicd/SKILL.md +77 -0
  9. package/content/cli/skills/fluent-cli-reference/SKILL.md +1031 -0
  10. package/content/cli/skills/fluent-cli-retailer/SKILL.md +85 -0
  11. package/content/cli/skills/fluent-cli-settings/SKILL.md +106 -0
  12. package/content/cli/skills/fluent-connect/SKILL.md +886 -0
  13. package/content/cli/skills/fluent-module-deploy/SKILL.md +349 -0
  14. package/content/cli/skills/fluent-profile/SKILL.md +180 -0
  15. package/content/cli/skills/fluent-workflow/SKILL.md +310 -0
  16. package/content/dev/agents/fluent-dev/agent.json +88 -0
  17. package/content/dev/agents/fluent-dev.md +525 -0
  18. package/content/dev/reference-modules/catalog.json +4754 -0
  19. package/content/dev/skills/fluent-build/SKILL.md +192 -0
  20. package/content/dev/skills/fluent-connection-analysis/SKILL.md +386 -0
  21. package/content/dev/skills/fluent-custom-code/SKILL.md +895 -0
  22. package/content/dev/skills/fluent-data-module-scaffold/SKILL.md +714 -0
  23. package/content/dev/skills/fluent-e2e-test/SKILL.md +394 -0
  24. package/content/dev/skills/fluent-event-api/SKILL.md +945 -0
  25. package/content/dev/skills/fluent-feature-explain/SKILL.md +603 -0
  26. package/content/dev/skills/fluent-feature-plan/PLAN_TEMPLATE.md +695 -0
  27. package/content/dev/skills/fluent-feature-plan/SKILL.md +227 -0
  28. package/content/dev/skills/fluent-job-batch/SKILL.md +138 -0
  29. package/content/dev/skills/fluent-mermaid-validate/SKILL.md +86 -0
  30. package/content/dev/skills/fluent-module-scaffold/SKILL.md +1928 -0
  31. package/content/dev/skills/fluent-module-validate/SKILL.md +775 -0
  32. package/content/dev/skills/fluent-pre-deploy-check/SKILL.md +1108 -0
  33. package/content/dev/skills/fluent-retailer-config/SKILL.md +1111 -0
  34. package/content/dev/skills/fluent-rule-scaffold/SKILL.md +385 -0
  35. package/content/dev/skills/fluent-scope-decompose/SKILL.md +1021 -0
  36. package/content/dev/skills/fluent-session-audit-export/SKILL.md +632 -0
  37. package/content/dev/skills/fluent-session-summary/SKILL.md +195 -0
  38. package/content/dev/skills/fluent-settings/SKILL.md +1058 -0
  39. package/content/dev/skills/fluent-source-onboard/SKILL.md +632 -0
  40. package/content/dev/skills/fluent-system-monitoring/SKILL.md +767 -0
  41. package/content/dev/skills/fluent-test-data/SKILL.md +513 -0
  42. package/content/dev/skills/fluent-trace/SKILL.md +1143 -0
  43. package/content/dev/skills/fluent-transition-api/SKILL.md +346 -0
  44. package/content/dev/skills/fluent-version-manage/SKILL.md +744 -0
  45. package/content/dev/skills/fluent-workflow-analyzer/SKILL.md +959 -0
  46. package/content/dev/skills/fluent-workflow-builder/SKILL.md +319 -0
  47. package/content/dev/skills/fluent-workflow-deploy/SKILL.md +267 -0
  48. package/content/mcp-extn/agents/fluent-mcp.md +69 -0
  49. package/content/mcp-extn/skills/fluent-mcp-tools/SKILL.md +461 -0
  50. package/content/mcp-official/agents/fluent-mcp-core.md +91 -0
  51. package/content/mcp-official/skills/fluent-mcp-core/SKILL.md +94 -0
  52. package/content/rfl/agents/fluent-rfl.md +56 -0
  53. package/content/rfl/skills/fluent-rfl-assess/SKILL.md +172 -0
  54. package/docs/CAPABILITY_MAP.md +77 -0
  55. package/docs/CLI_COVERAGE.md +47 -0
  56. package/docs/DEV_WORKFLOW.md +802 -0
  57. package/docs/FLOW_RUN.md +142 -0
  58. package/docs/USE_CASES.md +404 -0
  59. package/metadata.json +156 -0
  60. package/package.json +51 -0
@@ -0,0 +1,802 @@
1
+ # Autonomous Development Workflow
2
+
3
+ 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.
4
+
5
+ ## Overview
6
+
7
+ ```
8
+ WORKSPACE CHECK → ANALYZE → EXPLAIN (if requested) or PLAN → [USER APPROVAL] → IMPLEMENT → VALIDATE → BUILD → DEPLOY → TEST → DIAGNOSE → FIX → (loop back)
9
+ ```
10
+
11
+ 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>/analysis/features/`) and terminates — no PLAN/IMPLEMENT needed.
12
+
13
+ Event API documentation is incorporated using selective extraction (operational, tool-anchored guidance only), not full-text mirroring.
14
+
15
+ ---
16
+
17
+ ## Phase 0: Workspace Check
18
+
19
+ Before analyzing, ensure the workspace is initialized for the target profile.
20
+
21
+ 1. Check if `accounts/<PROFILE>/workspace-state.json` exists.
22
+ 2. If it exists, compute the content hash and compare with the stored `contentHash`.
23
+ 3. If hashes match: workspace is current. Print summary and proceed to Phase 1.
24
+ 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.
25
+ 5. After connect completes, proceed to Phase 1 with all artifacts available.
26
+
27
+ 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.
28
+
29
+ ---
30
+
31
+ ## Phase 1: Analyze Existing State
32
+
33
+ Before making any changes, build a full picture of the current implementation.
34
+
35
+ ### 1.0 Account workspace intake
36
+
37
+ Use one account-scoped workspace:
38
+
39
+ - `accounts/<PROFILE>/SOURCE/` — source repos and/or module artifacts (`*.jar`, `*.zip`) — account-level, shared across retailers
40
+ - `accounts/<PROFILE>/workflows/<RETAILER_REF>/` — downloaded workflow JSON — retailer-scoped
41
+ - `accounts/<PROFILE>/analysis/` — generated reusable artifacts
42
+
43
+ Rules:
44
+
45
+ 1. Prefer local evidence first (source + artifacts already under `SOURCE/`).
46
+ 2. If artifacts exist, decompile into `accounts/<PROFILE>/SOURCE/.decompiled/<artifact-name>/` and include in analysis.
47
+ 3. Treat JAR/ZIP and decompiled output as read-only evidence.
48
+ 4. Recommend source-level implementation options; if only artifacts are present, request source onboarding before code changes.
49
+
50
+ Always keep workflow context explicit for safety:
51
+
52
+ 5. Download and edit workflows only under `accounts/<PROFILE>/workflows/<RETAILER_REF>/`.
53
+ 6. Persist `workflow-context.json` in that folder and verify it before merge/upload.
54
+
55
+ ### 1.1 Verify connectivity
56
+
57
+ Call these MCP tools in sequence — stop if any fails:
58
+
59
+ ```
60
+ config.validate → must return ok: true
61
+ health.ping → must return ok: true
62
+ connection.test → must return ok: true (also reveals retailerId, user context)
63
+ ```
64
+
65
+ If `config.validate` fails: environment variables are missing or wrong. Report and stop.
66
+ If `connection.test` fails: auth or network issue. Report and stop.
67
+
68
+ ### 1.2 Discover deployed workflows
69
+
70
+ ```
71
+ fluent workflow list -p <PROFILE> -r <RETAILER_REF>
72
+ ```
73
+
74
+ Parse the output to get all workflow names, entity types, and versions. Store this as the baseline.
75
+
76
+ ### 1.3 Reusable custom-code artifacts
77
+
78
+ If `accounts/<PROFILE>/analysis/custom-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.
79
+
80
+ | File | Purpose |
81
+ |------|---------|
82
+ | `source-map.json` | Maps rule names to source file paths |
83
+ | `workflow-rule-map.json` | Maps workflow rulesets/rules to implementing classes |
84
+ | `constraints.json` | Extracted constraints and invariants |
85
+ | `behavior-map.md` | Human-readable behavior summary |
86
+ | `extension-plan.md` | Suggested extension points and changes |
87
+ | `fingerprint.json` | Input fingerprint/hash manifest used to decide reuse vs regenerate |
88
+
89
+ Use incremental refresh by default:
90
+ - Rule source changed -> refresh `source-map.json` + impacted rows in `workflow-rule-map.json` + relevant `constraints.json` risks.
91
+ - Workflow JSON changed -> refresh `workflow-rule-map.json` + `behavior-map.md`.
92
+ - Test-only change -> refresh test metadata in `source-map.json` only.
93
+ - Structure/module metadata change -> full regenerate.
94
+
95
+ ### 1.4 Download relevant workflows
96
+
97
+ For each workflow relevant to the task:
98
+
99
+ ```
100
+ fluent workflow download -p <PROFILE> -r <RETAILER_REF> -w all -o accounts/<PROFILE>/workflows/<RETAILER_REF>/
101
+ ```
102
+
103
+ Write/update retailer context at:
104
+
105
+ `accounts/<PROFILE>/workflows/<RETAILER_REF>/workflow-context.json`
106
+
107
+ ```json
108
+ {
109
+ "profile": "<PROFILE>",
110
+ "retailerRef": "<RETAILER_REF>",
111
+ "retailerId": "<RETAILER_ID>",
112
+ "baseUrl": "<FLUENT_BASE_URL>",
113
+ "downloadedAt": "<ISO-8601>"
114
+ }
115
+ ```
116
+
117
+ Before merge/upload, verify the command target (`-p`, `-r`) matches this context file.
118
+
119
+ Read the downloaded JSON. Extract:
120
+ - All rulesets (name, triggers, rules with props)
121
+ - All statuses (name, category)
122
+ - The state machine: which events transition between which statuses
123
+ - Gate rulesets: which rulesets check child entity statuses before advancing
124
+
125
+ ### 1.4A Query live transitions
126
+
127
+ Use `workflow.transitions` to complement workflow JSON analysis with runtime-confirmed transitions:
128
+
129
+ ```
130
+ workflow.transitions({
131
+ "triggers": [{
132
+ "type": "ORDER",
133
+ "subtype": "HD",
134
+ "status": "CREATED",
135
+ "retailerId": "<RETAILER_ID>",
136
+ "flexType": "ORDER::HD"
137
+ }]
138
+ })
139
+ ```
140
+
141
+ This reveals:
142
+ - Which user actions are available at each status (runtime truth vs. workflow JSON definition)
143
+ - Required attributes for each action (avoids missing-attribute errors during testing)
144
+ - UI context (button labels, modules, confirmation dialogs)
145
+
146
+ ### 1.5 Discover deployed modules and rules
147
+
148
+ ```
149
+ fluent module list -p <PROFILE>
150
+ ```
151
+
152
+ If the project has local source code, scan it:
153
+
154
+ ```
155
+ Glob: plugins/rules/**/src/main/java/**/*.java
156
+ Grep: @RuleInfo in those files → extract rule names
157
+ Read: resources/module.json → extract registered rules and version
158
+ Read: pom.xml (and parent pom) → extract groupId/artifactId/version when module.json is missing or incomplete
159
+ ```
160
+
161
+ If JAR/ZIP artifacts are already under `accounts/<PROFILE>/SOURCE/`, decompile to:
162
+
163
+ `accounts/<PROFILE>/SOURCE/.decompiled/<artifact-name>/`
164
+
165
+ Then include that decompiled tree in rule mapping before asking for more inputs.
166
+
167
+ Module identity precedence (store in analysis artifacts):
168
+ - `symbolicName`: `module.json.name` -> manifest `Bundle-SymbolicName` -> `<groupId>/<artifactId>`
169
+ - `version`: `module.json.version` -> `pom project.version` (or `parent.version`) -> manifest `Implementation-Version` / `Bundle-Version`
170
+
171
+ ### 1.5A If source code is unavailable
172
+
173
+ When rule logic cannot be validated from workflow JSON alone:
174
+
175
+ 1. Request module artifacts (ZIP/JAR) from the deployed build.
176
+ 2. Extract `module.json` and map workflow rule names to Java class names.
177
+ 3. Decompile to `accounts/<PROFILE>/SOURCE/.decompiled/<artifact-name>/` and start with suspected rule classes first (avoid full artifact noise).
178
+ 4. Confirm actual behavior (props read, queries/mutations/events executed, guards/status checks).
179
+ 5. Keep confidence labels in notes: **confirmed by source/decompile** vs **inferred from workflow metadata**.
180
+
181
+ ### 1.6 Query live entity state (if investigating a specific entity)
182
+
183
+ Use MCP `graphql.query`:
184
+
185
+ **Orders:**
186
+ ```graphql
187
+ { orders(ref: ["<REF>"], first: 1) { edges { node {
188
+ id ref type status createdOn updatedOn
189
+ attributes { name type value }
190
+ fulfilmentChoice { edges { node { id ref type status deliveryType } } }
191
+ items { edges { node { ref quantity status fulfilmentChoiceRef } } }
192
+ } } } }
193
+ ```
194
+
195
+ **Fulfilments:**
196
+ ```graphql
197
+ { fulfilments(ref: ["<REF>"], first: 1) { edges { node {
198
+ id ref type status
199
+ attributes { name type value }
200
+ items { edges { node { ref status requestedQuantity filledQuantity } } }
201
+ order { id ref status }
202
+ fromLocation { ref name }
203
+ } } } }
204
+ ```
205
+
206
+ ### 1.7 Query event history (if investigating failures)
207
+
208
+ ```
209
+ event.list({ "context.entityRef": "<REF>", "context.entityType": "<TYPE>", "count": 50 })
210
+ ```
211
+
212
+ Filter failed events:
213
+ ```
214
+ event.list({ "context.entityRef": "<REF>", "eventStatus": "FAILED", "count": 50 })
215
+ ```
216
+
217
+ For each failed event, get details:
218
+ ```
219
+ event.get({ "eventId": "<ID>" })
220
+ ```
221
+
222
+ For event-model semantics, filter capabilities, and causality patterns (`context.sourceEvents`, root-entity tracing), use `/fluent-event-api` alongside this phase.
223
+
224
+ ### 1.8 Check settings
225
+
226
+ ```graphql
227
+ { settings(first: 1, context: "RETAILER", contextId: <RETAILER_ID>, name: ["<SETTING_NAME>"]) {
228
+ edges { node { id name value lobValue } }
229
+ } }
230
+ ```
231
+
232
+ ### 1.9 Connection topology and dependency mapping
233
+
234
+ Run `/fluent-connection-analysis` on the target workflow(s) to map:
235
+ - Internal, cross-entity, and cross-workflow event edges
236
+ - Orphaned rulesets and missing SendEvent targets
237
+ - Process flow classification (CREATE, SCHEDULED, CROSS_ENTITY, USER_ACTION, INTERNAL, INTEGRATION)
238
+ - Webhook and setting dependency inventory
239
+
240
+ 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).
241
+
242
+ ### 1.10 Retailer environment baseline
243
+
244
+ If environment setup is needed (new locations, networks, catalogues), use `/fluent-retailer-config` to create or verify infrastructure entities before testing.
245
+
246
+ ### 1.11 Platform health check
247
+
248
+ For broad platform issues or intermittent failures, run `/fluent-system-monitoring` to check aggregate event metrics, error rate trends, and queue health.
249
+
250
+ ### 1.12 Batch/job pipeline check
251
+
252
+ If the workflow involves batch ingestion or JOB entities, use `/fluent-job-batch` to trace job lifecycle and diagnose ingestion failures.
253
+
254
+ ### Analysis output
255
+
256
+ After Phase 1, the agent should have:
257
+ - Current workflow structure (rulesets, states, transitions)
258
+ - Connection topology and dependency map (if connection-analysis was run)
259
+ - Registered rules and their source code (if local)
260
+ - Entity state and event history (if investigating)
261
+ - Settings relevant to the task
262
+ - Evidence quality notes (confirmed vs inferred behavior)
263
+ - Clear understanding of what exists vs. what needs to change
264
+
265
+ ---
266
+
267
+ ## Phase 1b: Explain (Feature Architecture Document)
268
+
269
+ **When the user asks to understand an existing feature** rather than change it, route here instead of Phase 1.5.
270
+
271
+ Invoke `/fluent-feature-explain` which orchestrates:
272
+ 1. Workflow structure analysis (status machines, event chains, process flow classification)
273
+ 2. Rule logic analysis — **tiered evidence approach**:
274
+ - **Tier 1:** `plugin.list` descriptions and parameters (always available)
275
+ - **Tier 2:** Source code analysis — original source (`accounts/<PROFILE>/SOURCE/`) or decompiled JARs (`.decompiled/`). Invokes `/fluent-custom-code` for JAR decompilation if needed.
276
+ - **Tier 3:** Runtime evidence — auto-discovers existing entities via GraphQL before asking user
277
+ 3. Connection topology (cross-entity flows, webhooks, settings dependencies)
278
+ 4. Runtime evidence (adaptive — auto-discovers entities, escalates source depth when no runtime)
279
+
280
+ **Output:** A Feature Architecture Document saved to `accounts/<PROFILE>/analysis/features/<FEATURE_NAME>.md` containing:
281
+ - Entity lifecycle state diagrams (Mermaid `stateDiagram-v2`)
282
+ - Cross-entity sequence diagrams (Mermaid `sequenceDiagram`)
283
+ - Event chain flowcharts (Mermaid `flowchart TD`)
284
+ - Input → Output data flow tables
285
+ - Rules & logic per ruleset (custom vs OOTB, source file paths)
286
+ - Settings dependencies with current values
287
+ - Integration points (webhooks, scheduled events, external systems)
288
+ - Runtime evidence timeline (when entity ref provided)
289
+ - **Analysis Confidence section** — per-rule evidence levels (HIGH/MEDIUM/LOW) with recommendations for higher confidence
290
+
291
+ **Terminates here.** No PLAN/IMPLEMENT phases needed — this is read-only documentation output.
292
+
293
+ ---
294
+
295
+ ## Phase 1.5: Plan & Approve (Check Gate)
296
+
297
+ **Mandatory gate.** After analysis, present a structured implementation plan and wait for user approval before any changes.
298
+
299
+ **Skip** for pure read-only tasks (tracing, monitoring, querying entity state).
300
+
301
+ ### Plan structure
302
+
303
+ Present in this order:
304
+
305
+ 1. **Business context** — What problem, why now
306
+ 2. **Current state** — Specific workflow names, ruleset names, setting keys
307
+ 3. **Proposed changes** — Workflow changes (with Mermaid before/after), settings changes, rule/plugin changes, entity/data changes, deployment sequence
308
+ 4. **Flow visualization** — Mermaid `stateDiagram-v2` for state machines, `sequenceDiagram` for cross-entity flows
309
+ 5. **Risk assessment** — Breaking existing flows, runtime exceptions, missing dependencies
310
+ 6. **Test plan** — Happy path, new path, edge cases, regression
311
+ 7. **Rollback plan** — How to revert if issues arise
312
+
313
+ ### Approval protocol
314
+
315
+ 1. **STOP** — Do not proceed to Phase 2
316
+ 2. **Approved** → proceed to Phase 2
317
+ 3. **Changes requested** → revise plan, re-present
318
+ 4. **Rejected** → restart from Phase 1 with different approach
319
+ 5. **Partially approved** → proceed with approved sections only
320
+
321
+ See `fluent-dev` agent's "Phase 2: Plan & Approve (CHECK GATE)" section for the full template.
322
+
323
+ ---
324
+
325
+ ## Phase 2: Implement Changes
326
+
327
+ Based on the approved plan, determine what type of change is needed and execute the appropriate path.
328
+
329
+ ### Decision tree
330
+
331
+ ```
332
+ What needs to change?
333
+
334
+ ├─ Workflow structure (new rulesets, states, triggers)
335
+ │ └─ Go to 2.1: Edit Workflow
336
+
337
+ ├─ Business logic (new/modified rule behavior)
338
+ │ └─ Go to 2.2: Create or Edit Rule
339
+
340
+ ├─ Configuration (settings, data)
341
+ │ └─ Go to 2.3: Update Settings/Data
342
+
343
+ ├─ Multiple of the above
344
+ │ └─ Execute each applicable section in order: 2.1 → 2.2 → 2.3
345
+
346
+ └─ Unknown (need more investigation)
347
+ └─ Return to Phase 1 with more specific queries
348
+ ```
349
+
350
+ ### 2.1 Edit workflow
351
+
352
+ Read the current workflow JSON from `accounts/<PROFILE>/workflows/<RETAILER_REF>/` (or an explicitly provided local file after context check).
353
+
354
+ **Adding a new ruleset:**
355
+
356
+ Build the ruleset JSON following the structure:
357
+ ```json
358
+ {
359
+ "name": "<RulesetName>",
360
+ "description": "[<ENTITY_TYPE>] What this ruleset does",
361
+ "type": "<ENTITY_TYPE>",
362
+ "eventType": "NORMAL",
363
+ "rules": [
364
+ {
365
+ "name": "<ACCOUNT>.<MODULE>.<RuleName>",
366
+ "props": { "key": "value" }
367
+ }
368
+ ],
369
+ "triggers": [{ "status": "<STATUS>" }],
370
+ "userActions": []
371
+ }
372
+ ```
373
+
374
+ If triggers is empty `[]`, the ruleset fires when an event with matching name arrives.
375
+
376
+ **Validation — check ALL of these before proceeding:**
377
+ - [ ] Every `SetState` target status exists in the `statuses` array
378
+ - [ ] Every `SendEvent` target has a matching ruleset name
379
+ - [ ] Rule names follow `<ACCOUNT>.<MODULE>.<RuleName>` format
380
+ - [ ] No duplicate ruleset names
381
+ - [ ] Version is bumped from currently deployed version
382
+ - [ ] `versionComment` describes what changed
383
+
384
+ **Adding a new status:** Add to the `statuses` array:
385
+ ```json
386
+ { "name": "NEW_STATUS", "category": "FULFILMENT", "entityType": "ORDER" }
387
+ ```
388
+
389
+ Categories: `BOOKING`, `FULFILMENT`, `DONE`, `PAYMENT`
390
+
391
+ **Adding a gate ruleset:** Gates check child entity statuses before advancing parent:
392
+ ```json
393
+ {
394
+ "name": "CheckAllFulfilmentsComplete",
395
+ "rules": [{
396
+ "name": "ACCT.core.SendEventOnVerifyingAllFcStatus",
397
+ "props": { "eventName": "AdvanceOrder", "statuses": "DELIVERED,CANCELLED" }
398
+ }],
399
+ "triggers": [],
400
+ "userActions": []
401
+ }
402
+ ```
403
+
404
+ The `statuses` prop must include ALL terminal states for child entities.
405
+
406
+ ### 2.2 Create or edit rule
407
+
408
+ **New rule — use scaffolding pattern:**
409
+
410
+ Determine:
411
+ - Rule name (PascalCase, descriptive)
412
+ - Target package (`common`, `order`, `fulfilment`, etc.)
413
+ - What props it needs (`@ParamString` annotations)
414
+ - What it does (query? mutate? send event? set attribute?)
415
+
416
+ Create the Java class at:
417
+ ```
418
+ plugins/rules/<MODULE_NAME>/src/main/java/com/fluentcommerce/rule/<package>/<RuleName>.java
419
+ ```
420
+
421
+ Must extend `BaseRule` and implement `run(ContextWrapper context)`.
422
+
423
+ Create the test class at:
424
+ ```
425
+ plugins/rules/<MODULE_NAME>/src/test/java/com/fluentcommerce/rule/<package>/<RuleName>Test.java
426
+ ```
427
+
428
+ Wire into `resources/module.json` — add rule name to the `rules` array.
429
+
430
+ **Editing an existing rule:**
431
+
432
+ Find the rule class:
433
+ ```
434
+ Grep: @RuleInfo(name = "<RuleName>" across plugins/rules/**/src/main/java/
435
+ ```
436
+
437
+ Make changes. Run the unit test for that specific rule to verify:
438
+ ```bash
439
+ cd plugins && mvn test -pl rules/<module-alias> -Dtest="<RuleName>Test"
440
+ ```
441
+
442
+ **Gotchas to avoid:**
443
+ - `@ParamString` names are CASE-SENSITIVE
444
+ - `context.action().mutation()` only QUEUES — mutation executes AFTER rule returns
445
+ - `DynamicMutation.buildMutationDocument` appends `!` — never include `!` in type names
446
+ - `updateFulfilmentItem` does NOT exist — use `updateFulfilment` with nested `items`
447
+ - Implement `run(ContextWrapper context)`, not `run(Context context)`
448
+
449
+ ### 2.3 Update settings or data
450
+
451
+ **Settings** — via GraphQL mutation:
452
+ ```
453
+ graphql.query({
454
+ query: "mutation($input: UpdateSettingInput!) { updateSetting(input: $input) { id ref } }",
455
+ variables: { "input": { "id": "<ID>", "lobValue": "<JSON_STRING>" } }
456
+ })
457
+ ```
458
+
459
+ **Bulk data** — via batch mutations:
460
+ ```
461
+ graphql.batchMutate({
462
+ mutation: "updateOrder",
463
+ inputs: [{ "id": "1", "status": "NEW_STATUS" }, ...],
464
+ returnFields: ["id", "ref", "status"]
465
+ })
466
+ ```
467
+
468
+ ---
469
+
470
+ ## Phase 2.5: Validate Module Structure
471
+
472
+ Before building, run `/fluent-module-validate` to catch structural issues early.
473
+
474
+ 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.
475
+
476
+ ```
477
+ /fluent-module-validate accounts/<PROFILE>/SOURCE/<repo>/<module-root>
478
+ ```
479
+
480
+ If the report exists and hash matches, it prints "Module unchanged" and stops immediately. Otherwise it runs all 9 checks and writes:
481
+ - `accounts/<PROFILE>/analysis/module-validate/<name>.report.json`
482
+ - `accounts/<PROFILE>/analysis/module-validate/<name>.hash`
483
+
484
+ **Gate rule**: Do not proceed to Phase 3 if `summary.status === "NEEDS_FIXES"`. Fix FAILs first.
485
+
486
+ 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.
487
+
488
+ ---
489
+
490
+ ## Phase 3: Build and Package
491
+
492
+ Only needed if Java code changed. Skip to Phase 4 if only workflow/settings changed.
493
+
494
+ ### 3.1 Bump version
495
+
496
+ Fluent ignores re-uploads of the same module version. Update ALL of these:
497
+
498
+ | File | Field |
499
+ |------|-------|
500
+ | `plugins/pom.xml` | parent `<version>` |
501
+ | `plugins/rules/<MODULE_NAME>/pom.xml` | parent + module `<version>` |
502
+ | `plugins/types/<MODULE_NAME>/pom.xml` | parent + module `<version>` |
503
+ | `plugins/util/<MODULE_NAME>/pom.xml` | parent + module `<version>` |
504
+ | `resources/module.json` | `"version"` |
505
+
506
+ Read current version from `resources/module.json`, increment patch, update all files.
507
+
508
+ ### 3.2 Compile
509
+
510
+ ```bash
511
+ cd plugins && mvn clean install
512
+ ```
513
+
514
+ **If compilation fails:**
515
+
516
+ | Error | Fix |
517
+ |-------|-----|
518
+ | `cannot find symbol` | Check imports, verify changed class references |
519
+ | `dependency not found` | Run from `plugins/` with `-am` flag |
520
+ | Test failures | Update test fixtures/expected values, or run `-DskipTests` to defer |
521
+
522
+ Fix and retry until clean build.
523
+
524
+ ### 3.3 Package
525
+
526
+ ```bash
527
+ ./scripts/build-module.sh
528
+ # or on Windows:
529
+ powershell ./scripts/build-module.ps1
530
+ ```
531
+
532
+ Verify output: `dist/<MODULE_ARTIFACT_NAME>-<VERSION>.zip`
533
+
534
+ ---
535
+
536
+ ## Phase 4: Deploy
537
+
538
+ ### Decision tree
539
+
540
+ ```
541
+ What changed?
542
+
543
+ ├─ Java rules (+ possibly workflow)
544
+ │ └─ Deploy full module ZIP
545
+ │ fluent module install dist/<module>.zip \
546
+ │ --retailer <RETAILER_REF> --profile <PROFILE>
547
+
548
+ ├─ Workflow JSON only (no code changes)
549
+ │ └─ Upload workflow directly via REST API:
550
+ │ curl -X PUT "$BASE_URL/api/v4.1/workflow" \
551
+ │ -H "Authorization: Bearer $TOKEN" \
552
+ │ -d @workflow.json
553
+ │ NOTE: Requires retailer-scoped token, not account-level.
554
+
555
+ ├─ Settings/data only
556
+ │ └─ Already applied via GraphQL mutations in Phase 2.3. No deploy needed.
557
+
558
+ └─ Module + workflow with different workflow version
559
+ └─ Deploy module with --exclude workflows, then upload workflow separately
560
+ ```
561
+
562
+ ### Post-deploy verification
563
+
564
+ After deploy, verify:
565
+ ```bash
566
+ fluent module list -p <PROFILE> # Module version matches
567
+ fluent workflow list -p <PROFILE> -r <RETAILER_REF> # Workflow version matches
568
+ ```
569
+
570
+ ---
571
+
572
+ ## Phase 5: Test End-to-End
573
+
574
+ Run E2E test sequences to verify the deployed changes work.
575
+
576
+ ### 5.1 Choose scenario
577
+
578
+ | Scenario | When to use |
579
+ |----------|------------|
580
+ | ORDER HD | Testing home delivery flow changes |
581
+ | ORDER CC | Testing click & collect flow changes |
582
+ | Cancel Order | Testing cancellation handling |
583
+ | Short Pick | Testing partial fulfilment handling |
584
+ | Custom | When change affects a specific path not covered above |
585
+
586
+ ### 5.2 Execute test sequence
587
+
588
+ Each test follows this pattern:
589
+
590
+ ```
591
+ For each step in the scenario:
592
+ 1. SEND event via event.send (mode: "async")
593
+ 2. WAIT (initial delay: 3s for simple events, 15s after ConfirmValidation cascade)
594
+ 3. QUERY entity status via graphql.query
595
+ 4. COMPARE actual status to expected status
596
+ 5. If match → PASS, continue to next step
597
+ 6. If no match → RETRY (wait 5s, query again, up to 6 retries = 30s)
598
+ 7. If still no match after retries → FAIL, go to Phase 6
599
+ ```
600
+
601
+ **Dynamic test sequence option:** Instead of hardcoded steps, use `workflow.transitions` at each
602
+ state to discover the next available action:
603
+
604
+ ```
605
+ 1. Create entity
606
+ 2. workflow.transitions → discover actions at current status
607
+ 3. Pick the expected action from userActions[]
608
+ 4. event.send with eventName and required attributes from response
609
+ 5. Poll entity status until transition completes
610
+ 6. workflow.transitions → discover next actions
611
+ 7. Repeat until no more userActions (terminal state)
612
+ ```
613
+
614
+ This approach adapts automatically when workflows change and validates that expected
615
+ user actions are available at each step.
616
+
617
+ ### 5.3 Create test order
618
+
619
+ **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.
620
+
621
+ The discovery sequence queries: retailer context → locations → networks → product catalogues → products with inventory → customers → settings (consignment prefix).
622
+
623
+ Once discovery is complete, build the `createOrder` mutation using discovered values:
624
+
625
+ ```
626
+ graphql.query({
627
+ query: "mutation($input: CreateOrderInput!) { createOrder(input: $input) { id ref status } }",
628
+ variables: { input: {
629
+ ref: "E2E_HD_<TIMESTAMP>",
630
+ type: "MULTI",
631
+ retailer: { id: "<discovered.retailerId>" },
632
+ customer: { id: "<discovered.customerId>" },
633
+ items: [{ ref: "<discovered.productRef>", quantity: 1, productRef: "<discovered.productRef>",
634
+ productCatalogueRef: "<discovered.catalogueRef>",
635
+ fulfilmentChoiceRef: "E2E_HD_<TIMESTAMP>-FC-HD" }],
636
+ fulfilmentChoice: {
637
+ ref: "E2E_HD_<TIMESTAMP>-FC-HD", type: "HD", deliveryType: "STANDARD",
638
+ deliveryAddress: { ref: "E2E_HD_<TIMESTAMP>-ADDR",
639
+ name: "<discovered.location.primaryAddress.name or 'Test Delivery'>",
640
+ street: "<discovered.location.primaryAddress.street>",
641
+ city: "<discovered.location.primaryAddress.city>",
642
+ postcode: "<discovered.location.primaryAddress.postcode>",
643
+ country: "<discovered.location.primaryAddress.country>" },
644
+ attributes: [
645
+ { name: "sourcingLocationRef", type: "STRING", value: "<discovered.warehouseRef>" },
646
+ { name: "consignmentPrefix", type: "STRING", value: "<discovered.consignmentPrefix or 'A_'>" }
647
+ ]
648
+ }
649
+ }}
650
+ })
651
+ ```
652
+
653
+ See `/fluent-test-data` for the full discovery flow and entity creation templates (HD, CC, customer).
654
+
655
+ ### 5.4 Fire events and assert
656
+
657
+ **ORDER HD full lifecycle:**
658
+
659
+ | Step | Event | Entity | Expected Status | Wait |
660
+ |------|-------|--------|----------------|------|
661
+ | 1 | *(auto on create)* | ORDER | CREATED → ON_VALIDATION | 3s |
662
+ | 2 | `ConfirmValidation` | ORDER | IN_PROGRESS + Fulfilment CREATED | **15s** (async cascade) |
663
+ | 3 | `ConfirmAllocation` | FULFILMENT | RECEIVED | 5s |
664
+ | 4 | `CreateInvoice` | FULFILMENT | INVOICED | 5s |
665
+ | 5 | `ConfirmPick` | FULFILMENT | PICKPACK | 5s |
666
+ | 6 | `ConfirmShipment` | FULFILMENT | SHIPPED | 5s |
667
+ | 7 | `ConfirmDelivery` | FULFILMENT | DELIVERED | 5s |
668
+
669
+ After step 2, query fulfilments to get the generated fulfilment ref (pattern: `<consignmentPrefix><FC-ref>-<locationRef>`). All subsequent events target this ref.
670
+
671
+ **Event attributes required per step:**
672
+
673
+ | Event | Attributes |
674
+ |-------|-----------|
675
+ | `ConfirmPick` | `pickedAt` (ISO datetime), `pickedItems` (JSON array) |
676
+ | `ConfirmShipment` | `trackingNumber`, `carrierRef`, `shippedAt` (ISO datetime) |
677
+ | `ConfirmDelivery` | `deliveredAt` (ISO datetime) |
678
+
679
+ ### 5.5 Record results
680
+
681
+ Track each step: event sent, expected status, actual status, pass/fail, duration. If all steps pass, the change is verified. Report results and stop.
682
+
683
+ If any step fails → proceed to Phase 6.
684
+
685
+ ---
686
+
687
+ ## Phase 6: Diagnose and Fix
688
+
689
+ ### 6.1 Identify failure point
690
+
691
+ From the test results, identify:
692
+ - Which step failed
693
+ - What entity ref and type
694
+ - What was the expected vs actual status
695
+ - Was the event processed (SUCCESS/FAILED/PENDING)?
696
+
697
+ ### 6.2 Trace the failure
698
+
699
+ Query event history for the entity:
700
+ ```
701
+ event.list({ "context.entityRef": "<REF>", "context.entityType": "<TYPE>", "eventStatus": "FAILED", "count": 50 })
702
+ ```
703
+
704
+ For failed events, get details:
705
+ ```
706
+ event.get({ "eventId": "<ID>" })
707
+ ```
708
+
709
+ 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.
710
+
711
+ ### 6.3 Decision tree
712
+
713
+ ```
714
+ What happened?
715
+
716
+ ├─ Event FAILED with error message
717
+ │ ├─ "Rule exception" → Rule code bug. Read the rule source, check props, fix code.
718
+ │ ├─ "No matching ruleset" → Event name doesn't match any ruleset. Fix workflow.
719
+ │ ├─ "Entity not found" → Wrong entityRef. Fix the test or check entity creation.
720
+ │ └─ "Permission denied" → Check retailerId scope (account-level users get retailerId=0).
721
+
722
+ ├─ Event SUCCESS but wrong status
723
+ │ ├─ Gate not met → Query all child entities, check if they're in expected terminal states.
724
+ │ ├─ Wrong ruleset fired → Check trigger status conflicts in workflow.
725
+ │ └─ Rule ran but did something unexpected → Read rule code, check props.
726
+ │ If rule logic is unclear from available files → request source or decompile JAR/ZIP.
727
+
728
+ ├─ Event PENDING (stuck)
729
+ │ └─ Wait 15-30s and retry. If still pending, async queue may be backlogged.
730
+
731
+ ├─ No event found
732
+ │ └─ Event was never sent, or sent to wrong entityRef/entityType. Check test logic.
733
+
734
+ └─ Entity in unexpected intermediate state
735
+ └─ Async cascade still running. Wait and re-query.
736
+ If stuck > 60s: check if a gate condition is blocking. Query child entities.
737
+ ```
738
+
739
+ ### 6.4 Apply fix
740
+
741
+ Based on diagnosis, apply the fix:
742
+
743
+ | Root cause | Fix action | Next phase |
744
+ |-----------|------------|------------|
745
+ | Rule code bug | Edit Java source, fix logic | → Phase 3 (Build) |
746
+ | Rule behavior unclear from workflow metadata | Request source/JAR, decompile targeted classes, confirm actual logic | → Phase 1 (Analyze) |
747
+ | Missing/wrong workflow ruleset | Edit workflow JSON | → Phase 4 (Deploy) |
748
+ | Wrong props in ruleset | Edit workflow JSON | → Phase 4 (Deploy) |
749
+ | Missing status in workflow | Add to `statuses` array | → Phase 4 (Deploy) |
750
+ | Gate statuses incomplete | Update gate ruleset props | → Phase 4 (Deploy) |
751
+ | Setting value wrong | Update via GraphQL mutation | → Phase 5 (Test) |
752
+ | Test data issue | Fix test inputs | → Phase 5 (Test) |
753
+ | New rule needed | Create rule + update workflow | → Phase 2 (Implement) |
754
+
755
+ After fixing, loop back to the indicated phase and continue through to Phase 5 (Test) again.
756
+
757
+ ### 6.5 Loop termination
758
+
759
+ The loop terminates when:
760
+ - **All E2E test steps pass** → Report success with entity refs, event IDs, versions deployed
761
+ - **Unresolvable blocker** → Report what was tried, what failed, what needs human intervention
762
+ - **Requirements unclear** → Report what was analyzed, what options exist, ask for clarification
763
+
764
+ ---
765
+
766
+ ## Cross-Skill Handoff Protocol
767
+
768
+ When orchestrating across skills, use these handoff patterns:
769
+
770
+ | From | To | Handoff data |
771
+ |------|----|-------------|
772
+ | Analyze (Phase 1) | Implement (Phase 2) | Workflow JSON, rule list, entity state, identified gaps |
773
+ | Implement (Phase 2) | Validate (Phase 2.5) | Changed files list, new rule names, updated module.json |
774
+ | Validate (Phase 2.5) | Build (Phase 3) | Validation report (READY_FOR_BUILD / NEEDS_FIXES), content hash |
775
+ | Build (Phase 3) | Deploy (Phase 4) | ZIP path, new version number, what changed (code/workflow/both) |
776
+ | Deploy (Phase 4) | Test (Phase 5) | Deployed version, retailer, profile, entity type affected |
777
+ | Test (Phase 5) | Diagnose (Phase 6) | Failed step, entity ref, event name, expected vs actual status |
778
+ | Diagnose (Phase 6) | Fix (Phase 2/3/4) | Root cause, specific file/ruleset/prop to change |
779
+
780
+ ## MCP Tool Quick Reference
781
+
782
+ | Operation | Tool | Server |
783
+ |-----------|------|--------|
784
+ | Verify connectivity | `config.validate`, `health.ping`, `connection.test` | fluent-mcp-extn |
785
+ | Query entities | `graphql.query` | fluent-mcp-extn |
786
+ | Query all (paginated) | `graphql.queryAll` | fluent-mcp-extn |
787
+ | Create/update entities | `graphql.query` (with mutation) | fluent-mcp-extn |
788
+ | Bulk update | `graphql.batchMutate` | fluent-mcp-extn |
789
+ | Discover schema | `graphql.introspect` | fluent-mcp-extn |
790
+ | Send event | `event.send` | fluent-mcp-extn |
791
+ | Check event result | `event.list`, `event.get` | fluent-mcp-extn |
792
+ | Build event payload | `event.build` | fluent-mcp-extn |
793
+ | Discover transitions | `workflow.transitions` | fluent-mcp-extn |
794
+ | List workflows | CLI: `fluent workflow list` | fluent-mcp (official) |
795
+ | Download workflow | CLI: `fluent workflow download` | fluent-mcp (official) |
796
+ | Upload workflow | REST: `PUT /api/v4.1/workflow` | Direct API call |
797
+ | Deploy module | CLI: `fluent module install` | Direct CLI |
798
+
799
+ ## Related
800
+
801
+ - [Capability Ownership Map](CAPABILITY_MAP.md) — which skill owns what
802
+ - [flow-run Reference](FLOW_RUN.md) — automated diagnostics and deploy