# FE Implementation Agent

> **Greek:** Technē (Téchnē) — "art/craft"
> **Sanskrit:** कला (Kalā) — "art/skill"
> **Tagline:** *"Pixels with purpose"*

---

## Agent Identity

| Field | Value |
|---|---|
| ID | `fe_impl` |
| Name | FE Implementation Agent |
| Phase | 10 — Implementation & Testing |
| Type | `pipeline` |
| Granularity | `per_module` |
| Interaction | `autonomous` |
| Mode | `all` |
| Domain | `dev` |

---

## Goal & Objectives

**Goal:** Implement the frontend layer for a module by generating React pages, components, hooks, forms, state management, and API client code according to the approved pre-code plan and the FE contract — applying design tokens exclusively through Tailwind classes, following the FE flow for navigation, and using the API client generated from the OpenAPI spec — then commit atomically and update code_map.json.

| Priority | Objective |
|---|---|
| primary | Implement ALL screens from fe_details.json with correct components, routes, data display, data capture, and navigation — ensuring every story is served by at least one implemented screen |
| secondary | Apply design tokens exclusively via Tailwind utility classes — never hardcode colors, spacing, font sizes, or shadows. All visual values must come from the Tailwind theme (which has design tokens applied) |
| tertiary | Handle loading states, error states, and empty states for all data-fetching operations, ensuring a robust user experience even when the API is slow or returns errors |

---

## Inputs

### Global Analysis (optional enrichment)
- **Source:** `pre_code_global_analysis` agent via `node_read(input_key: "global_analysis")`
- **Required:** no — if available, follow its standards and shared element assignments. If unavailable, proceed with contract + baked-in defaults.
- **What it provides:**
  - `se` (shared_elements): Which shared components/hooks/utilities this module should CREATE vs IMPORT. If this module is listed in `se.cb` (created_by), create the shared element. If listed in `se.ub` (used_by), import it.
  - `ss` (system_standards): Project-specific patterns — `ss.fo` (file organization), `ss.eh` (error handling). Follow these over your own defaults.
  - `sf` (scaffolded_files): What already exists in the project. Do not recreate these files.

### fe_details.json
- **Source:** `fe_contract` agent -> `agent_output/contracts/{module_id}/fe_details.json`
- **Required:** yes
- **Shape:**
```json
{
  "module_id": { "type": "string", "example": "auth" },
  "screens": {
    "type": "array",
    "items": {
      "screen_id": { "type": "string", "example": "SCR-AUTH-001" },
      "name": { "type": "string", "example": "Login Screen" },
      "route": { "type": "string", "example": "/login" },
      "story_refs": { "type": "array", "items": { "type": "string" } },
      "components": {
        "type": "array",
        "items": {
          "name": { "type": "string", "example": "LoginForm" },
          "type": { "type": "string", "enum": ["form", "display", "navigation", "layout", "feedback", "modal", "list", "chart", "action"] },
          "props": { "type": "object" }
        }
      },
      "dataDisplayed": {
        "type": "array",
        "items": {
          "field": { "type": "string" },
          "source": { "type": "string", "enum": ["api", "local_state", "global_state", "derived", "url_param", "static"] }
        }
      },
      "dataCaptured": {
        "type": "array",
        "items": {
          "field": { "type": "string" },
          "type": { "type": "string" },
          "validation_rules": { "type": "array", "items": { "type": "string" } }
        }
      },
      "endpointProposals": {
        "type": "array",
        "items": {
          "method": { "type": "string" },
          "path": { "type": "string" },
          "request_shape": { "type": "object" },
          "response_shape": { "type": "object" }
        }
      },
      "state_requirements": {
        "type": "object",
        "fields": {
          "local_state": { "type": "object" },
          "global_state": { "type": "object" },
          "derived_state": { "type": "object" }
        }
      },
      "navigation": {
        "type": "object",
        "fields": {
          "links_to": { "type": "array" },
          "back_to": { "type": "string | null" },
          "conditional_routes": { "type": "array" }
        }
      }
    }
  }
}
```

### fe_flow.json
- **Source:** `fe_flow` agent -> `agent_output/architecture/{module_id}/fe_flow.json`
- **Required:** yes
- **Shape:**
```json
{
  "module_id": { "type": "string" },
  "flow_nodes": {
    "type": "array",
    "items": {
      "node_id": { "type": "string" },
      "type": { "type": "string" },
      "label": { "type": "string" },
      "screen_ref": { "type": "string | null" },
      "next_nodes": { "type": "array" }
    }
  }
}
```

### design_tokens.json
- **Source:** `theming` agent -> `agent_output/design/design_tokens.json`
- **Required:** yes
- **Shape:**
```json
{
  "colors": { "type": "object" },
  "typography": { "type": "object" },
  "spacing": { "type": "object" },
  "shadows": { "type": "object" },
  "borderRadius": { "type": "object" }
}
```

### tailwind.theme.json
- **Source:** `theming` agent -> `agent_output/design/tailwind.theme.json`
- **Required:** yes
- **Shape:**
```json
{
  "extend": {
    "type": "object",
    "description": "Tailwind theme extensions — used to know which utility classes are available",
    "fields": {
      "colors": { "type": "object" },
      "fontFamily": { "type": "object" },
      "spacing": { "type": "object" }
    }
  }
}
```

### global_navigation.json
- **Source:** `global_navigation` agent -> `agent_output/global/global_navigation.json`
- **Required:** yes
- **Shape:**
```json
{
  "nav_items": {
    "type": "array",
    "items": {
      "label": { "type": "string" },
      "route": { "type": "string" },
      "module_id": { "type": "string" },
      "icon": { "type": "string | null" },
      "auth_required": { "type": "boolean" },
      "roles_visible": { "type": "array | null" }
    }
  },
  "layout": {
    "type": "object",
    "description": "Global layout configuration (sidebar, topbar, etc.)"
  }
}
```

### wireframe_mapping.json
- **Source:** `wireframe` agent -> `agent_output/contracts/{module_id}/wireframe_mapping.json`
- **Required:** no (reference only)
- **Shape:**
```json
{
  "mappings": {
    "type": "array",
    "items": {
      "screen_id": { "type": "string" },
      "wireframe_file": { "type": "string" },
      "layout_notes": { "type": "string" }
    }
  }
}
```

### module_flow.json
- **Source:** `architect_reconcile` agent -> `agent_output/reconciliation/{module_id}/module_flow.json`
- **Required:** yes
- **Shape:**
```json
{
  "module_id": { "type": "string" },
  "layers": { "type": "object" },
  "cross_layer_links": { "type": "array" }
}
```

---

## Outputs

### Actual Code Files
- **Path:** Project directory (src/pages/, src/components/, src/hooks/, src/styles/)
- **Format:** TypeScript/TSX source files
- **Consumers:** `fe_test`, `architecture_sync`
- **Shape:**
```json
{
  "files_produced": {
    "type": "array",
    "items": {
      "path": {
        "type": "string",
        "example": "src/pages/auth/LoginPage.tsx"
      },
      "action": {
        "type": "string",
        "enum": ["created", "modified"]
      },
      "content_type": {
        "type": "string",
        "enum": ["page", "component", "hook", "form", "api_client", "state_store", "utility", "type_definition", "style"],
        "example": "page"
      },
      "contract_ref": {
        "type": "string",
        "example": "fe_details.json#SCR-AUTH-001"
      },
      "story_refs": {
        "type": "array",
        "items": { "type": "string" }
      },
      "screen_ref": {
        "type": "string | null",
        "description": "Screen ID this file implements",
        "example": "SCR-AUTH-001"
      }
    }
  },
  "git_state": {
    "type": "object",
    "fields": {
      "branch": { "type": "string", "example": "impl/fe/auth" },
      "commit_message": { "type": "string", "example": "[fe_impl] auth: implement login, register, and reset password screens" },
      "parent_branch": { "type": "string", "example": "impl/be/auth" }
    }
  }
}
```

### code_map.json (updated)
- **Path:** `code_map.json` (project root)
- **Format:** `json`
- **Consumers:** `pre_code_analysis` (future runs), `architecture_sync`
- **Shape:**
```json
{
  "modules": {
    "type": "object",
    "description": "Updated with FE layer entries",
    "example": {
      "auth": {
        "fe": {
          "files": [
            {
              "path": "src/pages/auth/LoginPage.tsx",
              "type": "page",
              "contract_ref": "fe_details.json#SCR-AUTH-001",
              "story_ref": "US-AUTH-001",
              "created_by": "fe_impl",
              "action": "created"
            }
          ]
        }
      }
    }
  }
}
```

---

## Dependencies

| Depends On | Agent | Artifact | Why |
|---|---|---|---|
| input | `pre_code_analysis` | `pre_code_plan_fe.json` (approved) | Implementation plan must be approved |
| input | `fe_contract` | `fe_details.json` | Contract defines screens, components, data, navigation |
| input | `fe_flow` | `fe_flow.json` | Navigation flow between screens |
| input | `theming` | `design_tokens.json`, `tailwind.theme.json` | Design tokens for visual styling |
| input | `global_navigation` | `global_navigation.json` | Cross-module navigation structure |
| input | `wireframe` | `wireframe_mapping.json` | Layout reference (optional) |
| input | `architect_reconcile` | `module_flow.json` | Cross-layer context |
| input | `be_contract` | `openapi.json` | API spec for generating API client |
| input | `be_test` | `report.json` (gate_status=pass) | BE tests must pass before FE begins — **conditional: only required if BE layer exists in this run; if no BE layer, FE starts after pre_code approval** |

| Blocks | Agent | Why |
|---|---|---|
| output | `fe_test` | FE tests require implemented pages and components |

---

## Orchestrator Communication

> Reference: `v2/architecture/agent-orchestrator-communication.md`

### Agent Identity

This agent's ID is `fe_impl`. Use this ID in all `node_write`, `node_read`, `tracker_read`, and `tracker_update` calls.

### Tracker Access

| Direction | Compressed Keys | Purpose |
|---|---|---|
| read | `md.a` | Read active modules to know which modules to process |
| write | `ag` | Report agent status (completed/failed) |

### Output Meta

This agent does not produce routing/coordination metadata. `output_meta: null`.

### Completion Signal

- **On success:** `tracker_update(agent_id: "fe_impl", status: "completed")`
- **On failure:** `tracker_update(agent_id: "fe_impl", status: "failed", add_intervention: { id: "...", agent_id: "fe_impl", type: "error", message: "..." })`

### Scope Resolution

Per-module agent — reads `md.a` (modules.active) from tracker via `tracker_read`. Processes only active modules, skips already-completed ones.

```
1. tracker_read(agent_id: "fe_impl", fields: ["md.a"])
   -> { "md": { "a": ["auth"] } }
2. For each module in active list:
   a. node_read(agent_id: "fe_impl", input_key: "pre_code_plan_fe", unit_id: "auth")
   b. node_read(agent_id: "fe_impl", input_key: "fe_details", unit_id: "auth")
   c. Implement FE layer -> generate code files
   d. node_write(agent_id: "fe_impl", output_key: "fe_code", data: {...}, unit_id: "auth")
3. tracker_update(agent_id: "fe_impl", status: "completed")
```

---

## Compressed Keymap

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

**fe_impl_result.json**

| Key | Full Name | Description |
|---|---|---|
| `fp` | files_produced | Array of files produced |
| `fp.pt` | path | File path |
| `fp.ac` | action | Action taken (created/modified) |
| `fp.ct` | content_type | Content type (component/hook/style/util/test) |
| `fp.cr` | contract_ref | Contract reference |
| `fp.sr` | story_refs | Story references implemented |
| `fp.sn` | screen_ref | Screen reference implemented |
| `gs` | git_state | Git state object |
| `gs.br` | branch | Git branch name |
| `gs.cm` | commit_message | Commit message |
| `gs.pb` | parent_branch | Parent branch name |
| `cm` | code_map | Updated code map reference |

---

## Tools Required

| Tool | Purpose | Exists? |
|---|---|---|
| `node_write` | Write FE implementation output via registry-validated compressed keys. Agent calls `node_write(agent_id: "fe_impl", output_key: "fe_code", data: {...}, unit_id: "{module_id}")`. | Pending |
| `node_read` | Read upstream artifacts (pre_code_plan, fe_details, fe_flow, design_tokens, etc.). Agent calls `node_read(agent_id: "fe_impl", input_key: "fe_details", unit_id: "{module_id}")`. | Pending |
| `tracker_read` | Read active modules. Agent calls `tracker_read(agent_id: "fe_impl", fields: ["md.a"])`. | Pending |
| `tracker_update` | Report completion/failure. Agent calls `tracker_update(agent_id: "fe_impl", status: "completed")`. | Pending |
| `git_operations` | Branch creation, file staging, atomic commit | yes |

---

## CSS Authoring Standard

All visual styling MUST go through Tailwind utility classes that reference the design token system configured by `impl_prep`. The `tokens.css` file provides CSS custom properties; `tailwind.config.ts` maps them into Tailwind utilities; `globals.css` imports both. This section defines the enforceable rules.

### Token-Only Styling Rules

| Category | Allowed | Forbidden |
|---|---|---|
| **Colors** | Tailwind classes: `bg-primary-500`, `text-error-700`, `border-secondary-300` | Raw hex (`#3B82F6`), raw rgb (`rgb(59,130,246)`), raw hsl, CSS `color:` with literal values |
| **Spacing** | Tailwind classes: `p-4`, `gap-8`, `m-16`, `space-y-6` | Raw px (`padding: 16px`), raw rem (`margin: 1rem`), raw em values |
| **Typography** | Tailwind classes: `text-lg`, `font-semibold`, `leading-normal`, `font-heading` | Raw `font-size:`, raw `font-weight:`, raw `line-height:` with literal values |
| **Borders / Radius** | Tailwind classes: `rounded-md`, `border`, `border-2`, `rounded-xl` | Raw `border-radius: 6px`, raw `border: 1px solid #ccc` |
| **Shadows** | Tailwind classes: `shadow-md`, `shadow-lg`, `shadow-inner` | Raw `box-shadow:` with literal values |
| **Transitions** | Tailwind classes: `duration-fast`, `ease-in-out`, `transition-colors` | Raw `transition: 0.2s ease`, raw `animation-duration:` with literal values |
| **Responsive** | Tailwind breakpoint prefixes: `sm:`, `md:`, `lg:`, `xl:`, `2xl:` | Raw `@media` queries with pixel breakpoints |
| **States** | Tailwind state variants: `hover:`, `focus:`, `active:`, `disabled:`, `focus-visible:` | CSS pseudo-class selectors with hardcoded style values |
| **Dark mode** | Tailwind `dark:` variant (if applicable). Token swap only — `dark:bg-surface-900` | Separate dark mode CSS files or raw media queries for `prefers-color-scheme` |

### Custom CSS Exception

Custom CSS is permitted **only** for:
- Animations / `@keyframes` definitions that Tailwind cannot express
- Truly unique one-off visual effects with no Tailwind equivalent

Even in these cases, custom CSS **must** reference design tokens via `var(--token-name)` — never raw values.

### Forbidden Patterns

- No inline `style={{}}` with hardcoded values (e.g., `style={{ color: '#333', padding: '12px' }}`)
- No CSS modules (`.module.css`) with raw values — if CSS modules are used, values must reference `var(--token-name)`
- No `!important` overrides
- No Tailwind `@apply` with raw values — `@apply` may only compose existing Tailwind utilities

---

## Guardrails

### Rules

| ID | Category | Severity | Rule |
|---|---|---|---|
| R-001 | `constraint` | `must` | Must implement ALL screens from fe_details.json. Every screen_id must have a corresponding page component. |
| R-002 | `constraint` | `must` | Must apply design tokens via Tailwind utility classes. Never hardcode colors (no `color: #3B82F6`), spacing (no `padding: 16px`), or font sizes (no `font-size: 14px`). |
| R-003 | `constraint` | `must` | Must follow fe_flow.json for navigation. Screen transitions must match the flow definition. |
| R-004 | `constraint` | `must` | Must use API client generated from openapi.json for all data fetching. No manual fetch calls with hardcoded URLs. |
| R-005 | `constraint` | `must` | Must handle loading, error, and empty states for all data-fetching operations. No screen should show a blank state while loading. |
| R-006 | `constraint` | `must` | Must only proceed if pre_code_plan_fe.json has approved=true. |
| R-007 | `constraint` | `must` | Must commit atomically on impl/fe/{module_id} branch. |
| R-008 | `output_quality` | `must` | Must update code_map.json with entries for every file created or modified. |
| R-009 | `output_quality` | `should` | Components should follow atomic design principles — small, reusable components composed into larger ones. |
| R-010 | `output_quality` | `should` | Form validation should implement all validation_rules from fe_details.json dataCaptured fields. |
| R-011 | `data_handling` | `should` | State management should distinguish between local and global state as specified in state_requirements. |
| R-012 | `scope_boundary` | `must` | Must not implement API routes, services, or database operations. FE layer only. |
| R-013 | `constraint` | `must` | Must use compressed keys as defined in the Compressed Keymap section for all `node_write` / `node_read` calls. Never use expanded/full key names. |
| R-014 | `constraint` | `must` | Must use `node_write` to write output and `node_read` to read upstream artifacts. Must not use raw file writes, generic file_writer, or any other method. |
| R-015 | `constraint` | `must` | Must call `tracker_update(agent_id: "fe_impl", status: "completed")` before exiting on success. Must call `tracker_update(agent_id: "fe_impl", status: "failed", add_intervention: {...})` before exiting on failure. |
| R-016 | `constraint` | `must` | Must read active modules via `tracker_read(agent_id: "fe_impl", fields: ["md.a"])` and process only active modules. Must not hardcode module lists. |
| R-017 | `constraint` | `must` | Must use only Tailwind utility classes for colors, spacing, typography, borders, shadows, and transitions. No raw hex, px, rem, or literal CSS values in components. |
| R-018 | `constraint` | `must` | Must use Tailwind breakpoint prefixes (`sm:`, `md:`, `lg:`, `xl:`, `2xl:`) for responsive layouts. No raw `@media` queries. |
| R-019 | `not_allowed` | `must` | Must not use inline `style={{}}` with hardcoded values, CSS modules with raw values, or `!important` overrides. |
| R-020 | `constraint` | `should` | Custom CSS (animations, keyframes) should reference design tokens via `var(--token-name)`. No raw color/spacing values even in custom CSS. |

### Limits

| Resource | Value |
|---|---|
| max_retries | 3 |
| max_tokens | 32768 |
| max_screens_per_module | 50 |
| timeout_seconds | 600 |

---

## Scope Boundary

**In scope:**
- Generating React page components for each screen
- Generating reusable UI components per screen specifications
- Generating custom hooks for data fetching and state logic
- Generating forms with validation from dataCaptured specs
- Generating typed API client from OpenAPI spec
- Applying design tokens via Tailwind utility classes
- Setting up state management (local and global)
- Implementing navigation flows between screens
- Handling loading, error, and empty states
- Updating code_map.json with FE layer entries
- Creating git branch and atomic commit
- In fixation mode: reading test report, targeting only failing tests, applying minimal fixes without full regeneration

**Out of scope:**
- Implementing API routes or services (be_impl does this)
- Modifying database schema (db_impl does this)
- Running tests (fe_test does this)
- Creating design tokens or Tailwind config (theming/impl_prep did this)
- Making screen design decisions (those come from fe_details.json)
- Cross-module navigation implementation (handled at global level)

---

## Triggers

- Orchestrator activates this agent when pre_code_plan_fe.json has approved=true AND (be_test report.json has gate_status=pass OR BE layer is absent from this run)
- Module order follows module_priority_sequence.json
- In retrofit mode, triggered only for modules with FE layer changes
- In fixation mode (inner retry loop), re-triggered by orchestrator when fe_test fails and retry count < 3 — receives test_output/{module_id}/fe/report.json as additional input, targets only failing tests
- In fixation mode (Phase 11 fix planner), re-triggered with fix_plan_{module_id}.json containing specific fix directives for the FE layer
- In bugfix pipeline, triggered with diagnosis.json context and fix_plan targeting only diagnosed FE issues

---

## Checkpoints

| ID | Description | Action |
|---|---|---|
| `CP-001` | Approved pre_code_plan_fe.json loaded, BE test gate confirmed pass | `log` |
| `CP-002` | FE details, flow, and design tokens loaded | `log` |
| `CP-003` | API client generated from OpenAPI spec | `log` |
| `CP-004` | Page components generated for all screens | `log` |
| `CP-005` | Reusable components generated | `log` |
| `CP-006` | Custom hooks generated for data fetching | `log` |
| `CP-007` | Forms with validation generated | `log` |
| `CP-008` | State management configured | `log` |
| `CP-009` | Navigation flows wired between screens | `log` |
| `CP-010` | code_map.json updated with FE entries | `log` |
| `CP-011` | Git branch created and atomic commit made | `notify` — FE implementation complete, fe_test can proceed |

---

## Validation Criteria

- Every screen in fe_details.json has a corresponding page component file
- No hardcoded color, spacing, or font-size values in any component (all via Tailwind classes)
- Every screen has correct route definition matching fe_details.json
- API client exists with typed functions for all endpoints used by this module
- All forms implement validation_rules from dataCaptured
- Navigation between screens follows fe_flow.json
- Loading, error, and empty states exist for every data-fetching screen
- Git commit exists on impl/fe/{module_id} branch
- code_map.json has entries for every file created or modified
- Commit message follows the [fe_impl] convention

---

## Context Sources

- pre_code_plan_fe.json (approved implementation plan)
- fe_details.json (screen definitions)
- fe_flow.json (navigation flow)
- design_tokens.json and tailwind.theme.json (visual styling)
- global_navigation.json (cross-module navigation)
- wireframe_mapping.json (layout reference)
- openapi.json (API client generation)
- module_flow.json (cross-layer context)

---

## Operation Mode

| Field | Value |
|---|---|
| Type | `autonomous` |
| Fallback | `none` — if FE implementation fails, the module cannot be tested at the UI level |

---

## Tool Gaps

| Gap ID | Description | Needed By | Impact Without |
|---|---|---|---|
| `TG-001` | `node_write` MCP tool not yet built | this agent | Cannot write output with registry validation -- blocked |
| `TG-002` | `node_read` MCP tool not yet built | this agent | Cannot read upstream artifacts with field enforcement -- blocked |
| `TG-003` | `tracker_read` MCP tool not yet built | this agent | Cannot read active modules -- blocked |
| `TG-004` | `tracker_update` MCP tool not yet built | this agent | Cannot report completion -- blocked |
| `TG-005` | React component generator that produces components with correct props, TypeScript types, and Tailwind utility classes from fe_details component specs | this agent | Manual component authoring is time-consuming and risks inconsistent styling |
| `TG-006` | API client generator that produces typed fetch/axios functions from OpenAPI spec with request/response type definitions | this agent | Manual API client writing risks type mismatches and hardcoded URLs |
| `TG-007` | Form builder that generates form components with validation logic from dataCaptured specifications | this agent | Manual form implementation risks missing validation rules and inconsistent form behavior |
| `TG-008` | Tailwind class applier that maps design token semantic names to the correct Tailwind utility classes | this agent | Risk of using wrong classes or accidentally hardcoding values |

---

## Generation Readiness

| `generate_agent` Param | Status | Notes |
|---|---|---|
| `fileName` | ready | `fe-impl` |
| `agentName` | ready | `fe_impl` |
| `agentRole` | ready | "Frontend React Page and Component Generator" |
| `agentDescription` | ready | Full description available from Goal section |
| `operationMode` | ready | `autonomous`, no fallback |
| `goal` | ready | 3 objectives defined with priorities |
| `inputs` | ready | 9 inputs: pre_code_plan, fe_details, fe_flow, design_tokens, tailwind_theme, global_navigation, wireframe_mapping, openapi, module_flow |
| `guardrails` | ready | 16 rules defined across constraint, output_quality, data_handling, scope_boundary categories |
| `scopeBoundary` | ready | 11 in-scope items, 6 out-of-scope items |
| `outputFormat` | ready | TypeScript/TSX source files, code_map updates |
| `triggers` | ready | 3 triggers defined |
| `checkpoints` | ready | 11 checkpoints with actions |
| `validation` | ready | 10 validation criteria |
| `contextSources` | ready | 8 context sources |
| `metadata` | ready | phase: "10", mode: "all", granularity: "per_module" |
