# Implementation Critique Protocol — Generated Artifacts

Adversarial validation for implementation artifacts (workflow JSON, Java rules, manifest JSON, settings) before presenting to user or deploying.

## Design Principle

**Specs and plans catch design errors. This protocol catches generation errors.** The approved plan says _what_ to build; this validates that the _generated output_ matches the plan and follows platform constraints. Lighter than spec/plan critique — artifacts are mechanically verifiable.

## When This Runs

- **After** the artifact is generated/written to file
- **Before** presenting to the user or deploying
- Fully automated — no user interaction
- The approved plan provides the reference spec

## Protocol

Run up to **2 rounds** of critique-and-fix. Single critic, focused rubric.

### Round 1: Artifact Validation

1. **Critic pass** — Spawn a critic agent that reads the generated artifact AND the approved plan, then validates against the artifact-specific rubric (below).

   **Runtime adaptation:**
   | Runtime | Critic mechanism |
   |---------|-----------------|
   | Claude Code | Agent tool, `subagent_type: general-purpose` |

2. **Author evaluates** — Same verdict system as spec/plan critique:

   | Verdict | Criteria | Action |
   |---------|----------|--------|
   | **ACCEPTED** | Valid + evidence + CRITICAL or HIGH | Fix artifact |
   | **REJECTED** | No evidence or factually incorrect | Log with reason |
   | **DEFERRED** | Valid but non-blocking | Log for user awareness |

3. **Convergence check** — 0 new CRITICAL/HIGH → exit

### Round 2: Final Pass (if needed)

Critic can raise new findings or counter-argue. Same rules as spec/plan Round 2. Hard exit after Round 2 — no Round 3.

### Escalation

CRITICAL finding rejected twice with new evidence → **ESCALATED** for user arbitration (same mechanism as spec/plan protocols).

## Pre-Critique Feedback Check

Before Round 1, read the relevant skill's feedback file:
- `accounts/<PROFILE>/feedback/<skill-name>.jsonl` (last 10 records)
- Extract top 3 pitfalls for the artifact type
- Inject as `{feedback_pitfalls}` in critic prompt

## Artifact-Specific Rubrics

Select the rubric matching the artifact type. The critic validates ONLY items in the selected rubric.

---

### Workflow JSON Rubric

| # | Category | What to Check |
|---|----------|---------------|
| WF-1 | **eventName present** | Every `userActions[]` entry has a non-empty `eventName`. Missing eventName = silently invisible button. |
| WF-2 | **Subtype match** | Every ruleset's `subtype` matches the workflow's `entitySubtype`. Missing/wrong subtype = rulesets never trigger. |
| WF-3 | **Modules correct** | `userActions[].context[].modules` is non-empty and uses the correct module alias. OMS App uses `"adminconsole"` (legacy alias via orchestrationAlias), NOT `"oms"`. Store App uses `"servicepoint"` (legacy alias). Empty array = invisible. |
| WF-4 | **Version incremented** | Workflow `version` is higher than the currently deployed version. Same/lower = Fluent rejects the upload. |
| WF-5 | **Triggers complete** | All intended statuses have triggers. No orphaned rulesets (rulesets with triggers for statuses that don't exist in the workflow). |
| WF-6 | **Status categories** | Every status has a `category`. Standard: `BOOKING`, `FULFILMENT`, `DELIVERY`, `DONE`. Empty `""` is valid ONLY for child entity statuses in parent workflows. |
| WF-7 | **User action ↔ plan contract** | Attribute names in `userActions[].attributes[]` match the plan's `@EventAttribute` declarations. Ruleset `props{}` keys match `@ParamString` declarations. |
| WF-8 | **Confirm is boolean** | `context[].confirm` is `true`/`false`, NOT string `"true"`/`"false"`. |
| WF-9 | **Type is uppercase** | `context[].type` is `"PRIMARY"` or `"SECONDARY"` (uppercase). |
| WF-10 | **Attribute defaults safe** | `attributes[].source` and `attributes[].defaultValue` are empty strings `""` unless intentionally set. Settings-driven dropdowns: `source` lowercase `"settings.<KEY>"`, never `"Settings.<KEY>"`. |

**Critic prompt (Workflow):**

```
You are a Fluent Commerce workflow validation expert. Your job is to find ERRORS in generated workflow JSON that would cause runtime failures or invisible UI elements.

Read the workflow at: {artifact_path}
Read the approved plan at: {plan_path}
{If exists: Read knowledge/platform/user-action-contract.md}

{feedback_pitfalls}

Validate against these 10 checks:
1. WF-1: Every userAction has eventName (missing = invisible button)
2. WF-2: Every ruleset subtype matches workflow entitySubtype
3. WF-3: modules[] non-empty, correct module alias (OMS App uses "adminconsole", Store App uses "servicepoint", not "oms")
4. WF-4: Version higher than currently deployed
5. WF-5: All statuses have triggers, no orphaned rulesets
6. WF-6: Every status has a category
7. WF-7: Attribute names match plan's @EventAttribute/@ParamString
8. WF-8: confirm is boolean, not string
9. WF-9: context type is uppercase PRIMARY/SECONDARY
10. WF-10: Attribute source/defaultValue safe, settings.* lowercase

Rules:
- Every finding MUST cite the specific JSON path (e.g., "rulesets[3].userActions[0] missing eventName")
- Focus on runtime failures and invisible UI, not style
- Cross-reference the approved plan for expected attributes and props

Output: findings table or "No findings — workflow passes all 10 checks."

| # | Severity | Check | Finding | JSON Path | Proposed Fix |
|---|----------|-------|---------|-----------|--------------|
```

---

### Java Rule Rubric

| # | Category | What to Check |
|---|----------|---------------|
| JR-1 | **@ParamString match** | Every `context.getProp("X")` has a matching `@ParamString(name = "X")` annotation. Missing annotation = null at runtime. |
| JR-2 | **@EventAttribute match** | Every `event.getAttributes().get("X")` has a matching `@EventAttribute(name = "X")` annotation. |
| JR-3 | **No DynamicUtils anti-pattern** | No `DynamicUtils.getJsonPath(context, "event.X")` — fragile, may return null. Use Event API instead. |
| JR-4 | **@RuleInfo name match** | `@RuleInfo(name = "...")` matches the rule name in module.json and the class name convention. |
| JR-5 | **Null safety** | All external data reads (getProp, getAttribute, query results) have null checks before use. |
| JR-6 | **Exception handling** | Expected business failures throw `RubixException` (not generic Exception). Unexpected errors propagate. |
| JR-7 | **Plan alignment** | Rule implements the pseudo logic from the approved plan. All READ/QUERY/MUTATE paths present. |

**Critic prompt (Java Rule):**

```
You are a Fluent Commerce Rubix rule validation expert. Your job is to find annotation mismatches, anti-patterns, and contract violations in generated Java rule code.

Read the rule at: {artifact_path}
Read the approved plan at: {plan_path}
{If exists: Read knowledge/platform/rule-development-contract.md}

{feedback_pitfalls}

Validate against these 7 checks:
1. JR-1: Every context.getProp() has @ParamString annotation
2. JR-2: Every event.getAttributes().get() has @EventAttribute annotation
3. JR-3: No DynamicUtils.getJsonPath(context, "event.*") anti-pattern
4. JR-4: @RuleInfo name matches module.json and class convention
5. JR-5: Null checks on all external data reads
6. JR-6: RubixException for expected failures, not generic Exception
7. JR-7: Rule implements all pseudo logic paths from approved plan

Rules:
- Every finding MUST cite the specific line number and code
- Focus on runtime failures and contract mismatches, not style
- Cross-reference the plan's pseudo logic for expected behavior

Output: findings table or "No findings — rule passes all 7 checks."

| # | Severity | Check | Finding | Line | Proposed Fix |
|---|----------|-------|---------|------|--------------|
```

---

### Manifest JSON Rubric

| # | Category | What to Check |
|---|----------|---------------|
| MF-1 | **Plugins in root only** | `plugins[]` array appears ONLY in root manifest (`fc.mystique.manifest.<app>`), NEVER in fragments. Fragments contain only `routes[]`. |
| MF-2 | **Setting parameters** | `valueType: "JSON"`, `context: "ACCOUNT"`, `contextId: 0`. Body in `lobValue` (never `value` — 255 char limit truncates). `lobValue` is raw JSON, not stringified. |
| MF-3 | **Query variables valid** | GraphQL queries have no undeclared variables in `variables{}` and no declared-but-unused variables. URL params are strings — use `$retailerId: ID` not `Int`. |
| MF-4 | **Component aliases registered** | All `component` references use aliases registered in the plugin (ComponentRegistry, FieldRegistry, TemplateRegistry). |
| MF-5 | **Fragment references exist** | `routes[]` of type `"reference"` point to existing fragment settings (`settingName` must resolve). |
| MF-6 | **Plan alignment** | Manifest implements the UI design from the approved plan (§9a/§10). All pages, routes, and components from the plan are present. |

**Critic prompt (Manifest):**

```
You are a Fluent Commerce Mystique manifest validation expert. Your job is to find structural errors that would cause broken UI, missing pages, or deployment failures.

Read the manifest at: {artifact_path}
Read the approved plan at: {plan_path}

{feedback_pitfalls}

Validate against these 6 checks:
1. MF-1: plugins[] in root only, never fragments
2. MF-2: valueType JSON, context ACCOUNT, contextId 0, body in lobValue (raw, not stringified)
3. MF-3: Query variables valid (no undeclared, no unused, correct types)
4. MF-4: Component aliases reference registered components
5. MF-5: Fragment references point to existing settings
6. MF-6: Manifest matches plan's UI design (§9a/§10)

Rules:
- Every finding MUST cite the specific JSON path
- Focus on structural errors that cause UI failures, not aesthetic choices
- Cross-reference the plan for expected pages and components

Output: findings table or "No findings — manifest passes all 6 checks."

| # | Severity | Check | Finding | JSON Path | Proposed Fix |
|---|----------|-------|---------|-----------|--------------|
```

---

### Settings Rubric

| # | Category | What to Check |
|---|----------|---------------|
| ST-1 | **Setting parameters** | `valueType: "JSON"`, `context: "ACCOUNT"`, `contextId: 0`. Never `LOB` or `RETAILER` (legacy). |
| ST-2 | **lobValue for large values** | Body in `lobValue` if >255 chars. `value` field silently truncates at 255. |
| ST-3 | **Dropdown format** | Settings-driven dropdowns: value MUST be `{ "active": [{ "name": "Display", "value": "CODE" }] }`. Plain array silently fails. |
| ST-4 | **No secrets** | Setting value contains no passwords, tokens, or credentials. |
| ST-5 | **Plan alignment** | Setting name, value structure, and purpose match the approved plan. |

**Critic prompt (Settings):**

```
You are a Fluent Commerce settings validation expert. Your job is to find parameter errors that would cause silent truncation, broken dropdowns, or deployment failures.

Read the setting at: {artifact_path}
Read the approved plan at: {plan_path}

{feedback_pitfalls}

Validate against these 5 checks:
1. ST-1: valueType JSON, context ACCOUNT, contextId 0 (never LOB/RETAILER)
2. ST-2: Large values in lobValue, not value (255 char truncation)
3. ST-3: Dropdown settings use { "active": [...] } wrapper format
4. ST-4: No secrets in setting values
5. ST-5: Setting matches approved plan

Rules:
- Every finding MUST cite the specific field and value
- Focus on silent failures (truncation, wrong format), not naming preferences

Output: findings table or "No findings — setting passes all 5 checks."

| # | Severity | Check | Finding | Field | Proposed Fix |
|---|----------|-------|---------|-------|--------------|
```

---

## Guardrails

| Guardrail | Rule |
|-----------|------|
| **Max rounds** | 2 — hard cap. Implementation artifacts are mechanically verifiable. |
| **Early exit** | 0 CRITICAL/HIGH findings in Round 1 → skip Round 2 |
| **Evidence required** | Every finding cites specific JSON path, line number, or field name |
| **No style changes** | Naming preferences, formatting, comment style → auto-reject |
| **No scope expansion** | Critic cannot suggest features beyond the approved plan → auto-reject |
| **Escalation** | CRITICAL rejected twice with new evidence → ESCALATED for user |
| **Feedback check** | Pre-Round 1: read skill feedback JSONL for known pitfalls |

## Validation Log Format

Append to the artifact's companion file or inline in the skill's output:

```markdown
### Artifact Validation

| # | Severity | Check | Finding | Location | Verdict | Action |
|---|----------|-------|---------|----------|---------|--------|
| V1 | CRITICAL | WF-1 | Missing eventName on RequestAppeasement | rulesets[3].userActions[0] | ACCEPTED | Added eventName |
| V2 | HIGH | WF-3 | modules is empty array | rulesets[3].userActions[0].context[0] | ACCEPTED | Set to ["adminconsole"] |

**Summary:** 1 round, 2 findings, 2 fixed. Artifact clean.
```

## Skills That Reference This Protocol

| Skill | Artifact type | Rubric | Insertion point |
|-------|--------------|--------|-----------------|
| `fluent-workflow-builder` | Workflow JSON | WF-1 through WF-10 | After generation, before Upload/merge |
| `fluent-rule-scaffold` | Java rule code | JR-1 through JR-7 | After generation, before /fluent-build handoff |
| `fluent-mystique-builder` | Manifest JSON | MF-1 through MF-6 | After each operation, before deployment approval |
| `fluent-settings` | Settings values | ST-1 through ST-5 | After preparation, before deployment |
| `fluent-workflow-deploy` | Workflow JSON | WF-1 through WF-10 | After Step 1.5 pre-deploy gate, before Step 2 upload |
