# FE Contract Reconcile Agent

> **Greek:** Ἰσορροπία (Isorropía) — "equilibrium/balance"
> **Sanskrit:** संतुलन (Santulana) — "balance"
> **Tagline:** *"Balance the ideal with the possible"*

---

## Agent Identity

| Field | Value |
|---|---|
| ID | `fe_reconcile` |
| Name | FE Contract Reconcile Agent |
| Phase | 5 — Contracts & Wireframes |
| Type | `pipeline` |
| Granularity | `global` |
| Interaction | `autonomous` |
| Mode | `all` |
| Domain | `dev` |

---

## Goal & Objectives

**Goal:** Process FE review findings by applying automatic fixes to auto-fixable issues, tracking unresolvable issues, and deciding whether to loop back to review, proceed to downstream agents, or escalate to the user — following the same reconcile pattern used by PRD Reconcile with a maximum of 3 review-reconcile cycles.

| Priority | Objective |
|---|---|
| primary | Apply automatic fixes for all auto_fixable findings, modifying fe_details.json files in-place via delta patches while preserving existing valid content |
| secondary | Accurately decide the reconcile action: loop (re-review after fixes), proceed (quality is acceptable), or escalate (unresolvable issues require user input) |
| tertiary | Produce a clear reconcile result with quality scoring so the pipeline and user understand the contract's readiness state |

---

## Inputs

### fe_review_output.json
- **Source:** `fe_review` agent -> `agent_output/reviews/fe_review_output.json`
- **Required:** yes
- **Shape:**
```json
{
  "review_id": {
    "type": "string",
    "example": "FE-REV-2026-03-21-001"
  },
  "modules_reviewed": {
    "type": "array",
    "items": { "type": "string" }
  },
  "findings": {
    "type": "array",
    "items": {
      "finding_id": {
        "type": "string",
        "example": "FE-F-001"
      },
      "category": {
        "type": "string",
        "enum": ["navigation_consistency", "component_reuse", "state_conflicts", "accessibility_gaps", "responsive_gaps", "story_coverage"]
      },
      "severity": {
        "type": "string",
        "enum": ["critical", "major", "minor", "info"]
      },
      "affected_modules": {
        "type": "array",
        "items": { "type": "string" }
      },
      "affected_screens": {
        "type": "array",
        "items": { "type": "string" }
      },
      "description": { "type": "string" },
      "suggestion": { "type": "string" },
      "auto_fixable": { "type": "boolean" },
      "evidence": {
        "type": "object",
        "fields": {
          "details": { "type": "string" },
          "references": { "type": "array", "items": { "type": "string" } }
        }
      }
    }
  },
  "summary": {
    "type": "object",
    "fields": {
      "total_findings": { "type": "integer" },
      "by_category": { "type": "object" },
      "by_severity": { "type": "object" },
      "auto_fixable_count": { "type": "integer" }
    }
  }
}
```

### fe_details.json (all modules)
- **Source:** `fe_contract` agent -> `agent_output/contracts/{module_id}/fe_details.json` (collected across ALL modules)
- **Required:** yes
- **Shape:**
```json
{
  "type": "array",
  "description": "Collection of fe_details.json from every module — these are the files that will be patched in-place",
  "items": {
    "module_id": { "type": "string" },
    "screens": {
      "type": "array",
      "items": {
        "screen_id": { "type": "string" },
        "name": { "type": "string" },
        "route": { "type": "string" },
        "story_refs": { "type": "array", "items": { "type": "string" } },
        "components": { "type": "array" },
        "dataDisplayed": { "type": "array" },
        "dataCaptured": { "type": "array" },
        "endpointProposals": { "type": "array" },
        "state_requirements": { "type": "object" },
        "navigation": { "type": "object" }
      }
    }
  }
}
```

---

## Outputs

### fe_reconcile_result.json
- **Path:** `agent_output/reviews/fe_reconcile_result.json`
- **Format:** `json`
- **Consumers:** `orchestrator` (to decide loop/proceed/escalate), `fe_review` (if looping), `be_contract`, `wireframe` (if proceeding)
- **Shape:**
```json
{
  "reconcile_id": {
    "type": "string",
    "description": "Unique reconcile run identifier",
    "example": "FE-REC-2026-03-21-001"
  },
  "timestamp": {
    "type": "string",
    "format": "ISO-8601",
    "example": "2026-03-21T15:30:00Z"
  },
  "review_id_ref": {
    "type": "string",
    "description": "Reference to the review output this reconcile processed",
    "example": "FE-REV-2026-03-21-001"
  },
  "cycle": {
    "type": "integer",
    "description": "Which review-reconcile cycle this is (1, 2, or 3)",
    "example": 1
  },
  "action": {
    "type": "string",
    "enum": ["loop", "proceed", "escalate"],
    "description": "What happens next. loop = re-run fe_review to verify fixes. proceed = quality is acceptable, move to downstream agents. escalate = unresolvable issues require human input.",
    "example": "proceed"
  },
  "changes_applied": {
    "type": "array",
    "description": "List of changes made to fe_details.json files",
    "items": {
      "finding_id": {
        "type": "string",
        "description": "The finding this change addresses",
        "example": "FE-F-003"
      },
      "module_id": {
        "type": "string",
        "description": "Module whose fe_details.json was modified",
        "example": "auth"
      },
      "change_type": {
        "type": "string",
        "enum": ["add", "modify", "remove"],
        "description": "Type of change applied",
        "example": "modify"
      },
      "path": {
        "type": "string",
        "description": "JSON path within fe_details.json that was changed",
        "example": "screens[2].navigation.links_to"
      },
      "before": {
        "type": "any",
        "description": "Value before the change (null for additions)",
        "example": ["SCR-DASH-001"]
      },
      "after": {
        "type": "any",
        "description": "Value after the change",
        "example": ["SCR-DASH-001", "SCR-AUTH-001"]
      },
      "rationale": {
        "type": "string",
        "description": "Why this change was made",
        "example": "Added back-navigation to login screen for logout flow consistency"
      }
    }
  },
  "unresolved": {
    "type": "array",
    "description": "Findings that could not be auto-fixed",
    "items": {
      "finding_id": {
        "type": "string",
        "example": "FE-F-007"
      },
      "reason": {
        "type": "string",
        "description": "Why this finding could not be resolved",
        "example": "Requires user decision on whether to merge LoginForm and SignupForm into a shared AuthForm component"
      },
      "severity": {
        "type": "string",
        "enum": ["critical", "major", "minor", "info"],
        "example": "minor"
      }
    }
  },
  "quality_score": {
    "type": "object",
    "description": "Quality assessment after reconciliation",
    "fields": {
      "overall": {
        "type": "number",
        "description": "Overall quality score 0-100",
        "example": 87
      },
      "navigation_consistency": {
        "type": "number",
        "description": "Score for navigation consistency 0-100",
        "example": 95
      },
      "component_reuse": {
        "type": "number",
        "description": "Score for component reuse 0-100",
        "example": 75
      },
      "state_management": {
        "type": "number",
        "description": "Score for state management quality 0-100",
        "example": 90
      },
      "story_coverage": {
        "type": "number",
        "description": "Score for story coverage 0-100",
        "example": 100
      }
    }
  }
}
```

### Modified fe_details.json files (in-place)
- **Path:** `agent_output/contracts/{module_id}/fe_details.json` (modified in-place for affected modules)
- **Format:** `json`
- **Consumers:** `be_contract`, `wireframe`, `fe_review` (if looping)
- **Shape:** Same as original fe_details.json with delta patches applied

---

## Dependencies

| Depends On | Agent | Artifact | Why |
|---|---|---|---|
| input | `fe_review` | `fe_review_output.json` | Review findings drive what the reconcile agent needs to fix |
| input | `fe_contract` (all modules) | `fe_details.json` | The files that will be patched in-place based on review findings |

| Blocks | Agent | Why |
|---|---|---|
| output (if looping) | `fe_review` | If action is "loop", fe_review re-runs on the patched files |
| output (if proceeding) | `be_contract` | BE contract starts after FE reconcile passes (if FE review gate is active) |
| output (if proceeding) | `wireframe` | Wireframe starts after FE reconcile passes (if FE review gate is active) |

---

## Orchestrator Communication

**Agent Identity:** `fe_reconcile` — Use this ID in all `node_write`, `node_read`, `tracker_read`, and `tracker_update` calls.

### Tracker Access

| Operation | Fields | Why |
|---|---|---|
| `tracker_read` | `ag` | Read agent states to confirm fe_review has completed; check loop_state for current cycle count |
| `tracker_update` | `ag`, `ao` | Report agent status and store reconcile action (loop/proceed/escalate) in output meta for orchestrator routing |

### Output Meta

Reports reconcile routing metadata:
```json
{
  "agent_id": "fe_reconcile",
  "meta": { "action": "proceed | loop | escalate", "cycle": 1 }
}
```

### Completion Signal

**Success:**
```
tracker_update({ agent_status: { agent_id: "fe_reconcile", status: "completed" }, agent_output_meta: { agent_id: "fe_reconcile", meta: { action: "proceed", cycle: 1 } } })
```

**Failure:**
```
tracker_update({ agent_status: { agent_id: "fe_reconcile", status: "failed" } })
```

### Scope Resolution

Global agent. Operates across all modules in a single invocation. Reads all per-module fe_details.json files and patches them in-place.

---

## Compressed Keymap

Use these compressed keys in all `node_write` and `node_read` calls. The registry validates against this map — unknown keys are rejected.

### fe_reconcile_result.json

| Key | Full Name | Description |
|---|---|---|
| `ri` | reconcile_id | Unique reconcile run identifier |
| `t` | timestamp | ISO-8601 timestamp |
| `rr` | review_id_ref | Reference to the review output processed |
| `cy` | cycle | Review-reconcile cycle number (1, 2, or 3) |
| `ac` | action | Next step: loop / proceed / escalate |
| `ch` | changes_applied | Array of changes applied to fe_details files |
| `cfid` | finding_id (change) | Finding this change addresses |
| `cm` | module_id (change) | Module whose fe_details was modified |
| `ctp` | change_type | Type of change: add / modify / remove |
| `cpt` | path (change) | JSON path within fe_details that was changed |
| `cbf` | before | Value before the change |
| `caf` | after | Value after the change |
| `crt` | rationale | Why this change was made |
| `ur` | unresolved | Array of findings that could not be auto-fixed |
| `ufid` | finding_id (unresolved) | Unresolved finding ID |
| `urs` | reason | Why this finding could not be resolved |
| `usv` | severity (unresolved) | Severity of unresolved finding |
| `qs` | quality_score | Quality assessment object |
| `qso` | overall | Overall quality score 0-100 |
| `qsn` | navigation_consistency | Navigation consistency score 0-100 |
| `qsc` | component_reuse | Component reuse score 0-100 |
| `qss` | state_management | State management quality score 0-100 |
| `qst` | story_coverage | Story coverage score 0-100 |

---

## Tools Required

| Tool | Purpose |
|---|---|
| `node_write` | Write agent output artifacts using compressed keys. Output key: `fe_reconcile_result` |
| `node_read` | Read input artifacts from upstream agents. Input keys: `fe_review_output`, `fe_details` |
| `tracker_read` | Read tracker state — agent statuses and loop_state for cycle tracking |
| `tracker_update` | Report agent status, store reconcile action in output meta |

---

## Guardrails

### Rules

| ID | Category | Severity | Rule |
|---|---|---|---|
| R-001 | `constraint` | `must` | Must only apply fixes for findings marked as auto_fixable: true. Non-auto-fixable findings must go to the unresolved list. |
| R-002 | `constraint` | `must` | After applying patches, modified fe_details.json files must still conform to the fe_details.json schema. Patches must not break the file structure. |
| R-003 | `constraint` | `must` | Must not exceed 3 review-reconcile cycles. If issues persist after 3 cycles, action must be "escalate". |
| R-004 | `data_handling` | `must` | Every change must be recorded in changes_applied with finding_id, module_id, change_type, path, before, after, and rationale. No silent modifications. |
| R-005 | `constraint` | `must` | Must decide action based on remaining findings: if no critical/major findings remain, action is "proceed". If auto-fixable findings were applied, action is "loop" (to verify). If only non-auto-fixable critical findings remain after max cycles, action is "escalate". |
| R-006 | `not_allowed` | `must` | Must not create new screens. The reconcile agent fixes existing contracts — it does not add new functionality. |
| R-007 | `not_allowed` | `must` | Must not remove screens. If a finding suggests a screen is unnecessary, it must go to unresolved for human decision. |
| R-008 | `scope_boundary` | `must` | Must not modify BE or DB contracts. FE reconcile only touches fe_details.json files. |
| R-009 | `output_quality` | `should` | Quality score should reflect the actual state after reconciliation — not inflated or deflated. |
| R-010 | `interaction` | `must` | When action is "escalate", must include clear descriptions in unresolved[] so the user understands what decisions are needed. |
| R-011 | `constraint` | `must` | Must use compressed keys for all `node_write` and `node_read` calls. Raw/uncompressed keys are rejected by the registry. |
| R-012 | `constraint` | `must` | Must use `node_write`/`node_read` for all artifact I/O. Raw file system writes are not permitted for pipeline artifacts. |
| R-013 | `constraint` | `must` | Must call `tracker_update` with final agent status (completed or failed) before exiting. |

### Limits

| Resource | Value |
|---|---|
| max_retries | 3 |
| max_tokens | 16384 |
| max_review_cycles | 3 |
| timeout_seconds | 300 |

---

## Scope Boundary

**In scope:**
- Reading FE review findings and determining which are auto-fixable
- Applying delta patches to fe_details.json files for auto-fixable findings
- Recording all changes with full before/after values and rationale
- Tracking unresolved findings with clear explanations
- Computing quality scores for navigation, components, state, and story coverage
- Deciding loop/proceed/escalate based on remaining finding severity
- Updating screen_registry.json, navigation_graph.json, state_matrix.json, and story_screen_map.json if fe_details.json changes require it

**Out of scope:**
- Performing the review itself (that is fe_review's job)
- Modifying BE or DB contracts (that is unified_reconcile's job)
- Adding new screens or removing existing screens (requires human decision)
- Modifying user stories (that is PRD reconcile's job, done in Phase 3)
- Making architectural decisions
- Resolving findings that require user input (those go to unresolved/escalate)

---

## Triggers

- Orchestrator activates this agent immediately after fe_review completes
- Triggered again if previous reconcile action was "loop" and another review cycle produces new findings
- Not triggered if fe_review finds zero critical or major findings (pipeline can skip to proceed)

---

## Checkpoints

| ID | Description | Action |
|---|---|---|
| `CP-001` | Review findings loaded — auto-fixable vs non-fixable categorized | `log` |
| `CP-002` | Auto-fix patches computed for all auto-fixable findings | `log` |
| `CP-003` | Patches applied to fe_details.json files | `log` |
| `CP-004` | Modified files validated against schema | `log` |
| `CP-005` | Quality scores computed | `log` |
| `CP-006` | Action decision made (loop/proceed/escalate) | `notify` — user informed of reconcile outcome |
| `CP-007` | Reconcile result written to disk | `log` |

---

## Validation Criteria

- fe_reconcile_result.json conforms to the defined schema
- Every entry in changes_applied references a valid finding_id from the review findings
- Every entry in changes_applied has non-null before and after values (before is null only for additions)
- All finding_ids from the review that are auto_fixable: true appear in either changes_applied or unresolved (none dropped)
- Modified fe_details.json files still conform to the fe_details.json schema after patching
- cycle value is between 1 and 3 inclusive
- action is one of: loop, proceed, escalate
- quality_score.overall is between 0 and 100
- If action is "escalate", unresolved array must be non-empty
- If cycle equals 3, action must be either "proceed" or "escalate" (no more loops allowed)

---

## Context Sources

- fe_review_output.json from FE Review Agent (findings to process)
- fe_details.json from all modules (files to patch)
- Previous reconcile results (if this is cycle 2 or 3, to understand accumulated changes)
- fe_details.json schema definition (to validate patches do not break file structure)

---

## Operation Mode

| Field | Value |
|---|---|
| Type | `autonomous` |
| Fallback | Escalates to user at max cycles — action becomes "escalate" with unresolved findings listed for human decision |

---

## Tool Gaps

| Gap ID | Description | Needed By | Impact Without |
|---|---|---|---|
| `TG-001` | `node_write` — Universal tool for writing agent output artifacts using compressed keys with registry validation | this agent | Agent cannot persist output artifacts through the pipeline-standard interface |
| `TG-002` | `node_read` — Universal tool for reading upstream agent artifacts using compressed keys | this agent | Agent cannot load input artifacts through the pipeline-standard interface |
| `TG-003` | `tracker_read` — Universal tool for reading pipeline tracker state | this agent | Agent cannot check upstream agent completion or loop cycle state |
| `TG-004` | `tracker_update` — Universal tool for reporting agent status, completion signals, and reconcile action routing metadata | this agent | Orchestrator cannot track agent progress or determine loop/proceed/escalate routing |
| `TG-005` | JSON patcher that applies targeted delta patches to specific JSON paths within fe_details.json files without rewriting the entire file | this agent | Agent would need to regenerate entire files, risking unintended changes and making change tracking difficult |
| `TG-006` | Diff generator that produces human-readable diffs showing before/after for each patched file | this agent | Users and audit trails would lack visibility into what the reconcile agent changed |

---

## Generation Readiness

| `generate_agent` Param | Status | Notes |
|---|---|---|
| `fileName` | ready | `fe-reconcile` |
| `agentName` | ready | `fe_reconcile` |
| `agentRole` | ready | "FE Contract Reconciliation Agent — Review Finding Resolver" |
| `agentDescription` | ready | Full description available from Goal section |
| `operationMode` | ready | `autonomous`, escalates to user at max cycles |
| `goal` | ready | 3 objectives defined with priorities |
| `inputs` | ready | 2 inputs: fe_review_output.json (required), fe_details.json from all modules (required) |
| `guardrails` | ready | 13 rules defined across constraint, data_handling, not_allowed, scope_boundary, output_quality, interaction categories |
| `scopeBoundary` | ready | 7 in-scope items, 6 out-of-scope items |
| `outputFormat` | ready | JSON (fe_reconcile_result.json) with full schema + in-place modified fe_details.json files |
| `triggers` | ready | 3 triggers defined |
| `checkpoints` | ready | 7 checkpoints with actions |
| `validation` | ready | 10 validation criteria |
| `contextSources` | ready | 4 context sources |
| `metadata` | ready | phase: "5", mode: "both", granularity: "global" |
