# Unified Contract Review Agent

> **Greek:** Πανόπτης (Panóptēs) — "all-seeing"
> **Sanskrit:** सर्वदर्शी (Sarvadarśī) — "all-seeing"
> **Tagline:** *"No layer hides from the whole"*

---

## Agent Identity

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

---

## Goal & Objectives

**Goal:** Perform a comprehensive cross-layer review of all three contract types (FE, BE, DB) across all modules to verify consistency, referential integrity, naming conventions, security completeness, and proper error handling — producing a structured findings report that the Unified Reconcile Agent can act upon to fix cross-layer mismatches.

| Priority | Objective |
|---|---|
| primary | Verify that FE endpoint proposals match BE endpoints — either honored, documented as reshaped, or accounted for — and that BE request/response schemas have corresponding DB model fields |
| secondary | Ensure cross-module consistency — shared entities (User, Session, etc.) are defined consistently across all modules' contracts at every layer |
| tertiary | Identify security gaps (endpoints without authentication, models without access control considerations) and naming convention violations across all three layers |

---

## Inputs

### fe_details.json (all modules)
- **Source:** `fe_contract` agent -> `agent_output/contracts/{module_id}/fe_details.json` (collected across ALL modules)
- **Required:** no (conditional — only present if FE layer exists; if absent, FE-to-BE consistency checks are skipped)
- **Shape:**
```json
{
  "type": "array",
  "description": "Collection of fe_details.json from every module",
  "items": {
    "module_id": { "type": "string", "example": "auth" },
    "screens": {
      "type": "array",
      "items": {
        "screen_id": { "type": "string" },
        "endpointProposals": {
          "type": "array",
          "description": "FE endpoint proposals — checked against BE openapi endpoints",
          "items": {
            "method": { "type": "string" },
            "path": { "type": "string" },
            "purpose": { "type": "string" },
            "request_shape": { "type": "object" },
            "response_shape": { "type": "object" },
            "story_ref": { "type": "string" }
          }
        },
        "dataDisplayed": {
          "type": "array",
          "description": "Fields displayed — checked against DB model fields for storage path",
          "items": {
            "field": { "type": "string" },
            "source": { "type": "string" },
            "format": { "type": "string | null" }
          }
        },
        "dataCaptured": {
          "type": "array",
          "description": "Fields captured — checked against DB model fields for storage path",
          "items": {
            "field": { "type": "string" },
            "type": { "type": "string" },
            "validation_rules": { "type": "array", "items": { "type": "string" } }
          }
        }
      }
    }
  }
}
```

### openapi.json (all modules)
- **Source:** `be_contract` agent -> `agent_output/contracts/{module_id}/openapi.json` (collected across ALL modules)
- **Required:** no (conditional — only present if BE layer exists; if absent, BE-to-DB consistency checks are skipped)
- **Shape:**
```json
{
  "type": "array",
  "description": "Collection of openapi.json from every module",
  "items": {
    "type": "object",
    "description": "OpenAPI 3.0 spec per module",
    "fields": {
      "openapi": { "type": "string" },
      "info": {
        "type": "object",
        "fields": {
          "title": { "type": "string" },
          "version": { "type": "string" }
        }
      },
      "paths": {
        "type": "object",
        "description": "API paths — checked against FE proposals and DB models",
        "additionalProperties": {
          "type": "object",
          "description": "Operations with x-story-refs, x-fe-proposal-ref, security, requestBody, responses"
        }
      },
      "components": {
        "type": "object",
        "fields": {
          "schemas": {
            "type": "object",
            "description": "Request/response schemas — checked against DB model fields",
            "additionalProperties": {
              "type": "object",
              "fields": {
                "type": { "type": "string" },
                "required": { "type": "array" },
                "properties": { "type": "object" }
              }
            }
          },
          "securitySchemes": { "type": "object" }
        }
      }
    }
  }
}
```

### prisma_contract.json (all modules)
- **Source:** `db_contract` agent -> `agent_output/contracts/{module_id}/prisma_contract.json` (collected across ALL modules)
- **Required:** no (conditional — only present if DB layer exists; if absent, DB-related consistency checks are skipped)
- **Shape:**
```json
{
  "type": "array",
  "description": "Collection of prisma_contract.json from every module",
  "items": {
    "module_id": { "type": "string" },
    "models": {
      "type": "array",
      "items": {
        "model_name": { "type": "string" },
        "fields": {
          "type": "array",
          "items": {
            "name": { "type": "string" },
            "type": { "type": "string" },
            "constraints": { "type": "array" },
            "default": { "type": "string | null" },
            "relation": { "type": "object | null" }
          }
        },
        "story_refs": { "type": "array", "items": { "type": "string" } },
        "indexes": { "type": "array" },
        "unique_constraints": { "type": "array" },
        "enums_used": { "type": "array" }
      }
    },
    "relations": {
      "type": "array",
      "items": {
        "from_model": { "type": "string" },
        "to_model": { "type": "string" },
        "type": { "type": "string" },
        "field": { "type": "string" },
        "references": { "type": "string" }
      }
    },
    "enums": {
      "type": "array",
      "items": {
        "name": { "type": "string" },
        "values": { "type": "array", "items": { "type": "string" } }
      }
    }
  }
}
```

---

## Outputs

### unified_review_output.json
- **Path:** `agent_output/reviews/unified_review_output.json`
- **Format:** `json`
- **Consumers:** `unified_reconcile`
- **Shape:**
```json
{
  "review_id": {
    "type": "string",
    "description": "Unique review run identifier",
    "example": "UNI-REV-2026-03-21-001"
  },
  "timestamp": {
    "type": "string",
    "format": "ISO-8601",
    "example": "2026-03-21T16:00:00Z"
  },
  "modules_reviewed": {
    "type": "array",
    "description": "List of module IDs included in this review",
    "items": { "type": "string" },
    "example": ["auth", "dashboard", "settings"]
  },
  "layers_reviewed": {
    "type": "array",
    "description": "Contract layers reviewed",
    "items": { "type": "string" },
    "example": ["fe", "be", "db"]
  },
  "findings": {
    "type": "array",
    "description": "Cross-layer review findings",
    "items": {
      "finding_id": {
        "type": "string",
        "description": "Unique finding identifier",
        "example": "UNI-F-001"
      },
      "category": {
        "type": "string",
        "enum": ["fe_be_mismatch", "be_db_mismatch", "cross_module_inconsistency", "naming_violation", "missing_error_handling", "security_gap"],
        "description": "Category of the cross-layer finding",
        "example": "fe_be_mismatch"
      },
      "severity": {
        "type": "string",
        "enum": ["critical", "major", "minor", "info"],
        "example": "major"
      },
      "layers_affected": {
        "type": "array",
        "description": "Which contract layers are involved in this finding",
        "items": {
          "type": "string",
          "enum": ["fe", "be", "db"]
        },
        "example": ["fe", "be"]
      },
      "affected_modules": {
        "type": "array",
        "description": "Modules affected by this finding",
        "items": { "type": "string" },
        "example": ["auth"]
      },
      "description": {
        "type": "string",
        "description": "Human-readable description of the cross-layer issue",
        "example": "FE proposes POST /api/auth/login with response field 'access_token', but BE openapi.json defines the field as 'token' in LoginResponse schema"
      },
      "suggestion": {
        "type": "string",
        "description": "Recommended fix — specifies which layer(s) should change",
        "example": "Align field naming: either FE updates endpointProposal response_shape to use 'token', or BE updates LoginResponse to use 'access_token'. Recommend BE aligns to FE since 'access_token' is the industry convention."
      },
      "auto_fixable": {
        "type": "boolean",
        "description": "Whether this finding can be automatically resolved by unified_reconcile",
        "example": true
      },
      "fix_target": {
        "type": "string",
        "enum": ["fe", "be", "db", "multiple"],
        "description": "Which layer should be modified to fix this finding",
        "example": "be"
      },
      "evidence": {
        "type": "object",
        "description": "Supporting data for this finding",
        "fields": {
          "fe_reference": {
            "type": "string | null",
            "description": "Specific FE artifact reference",
            "example": "SCR-AUTH-001.endpointProposals[0].response_shape.access_token"
          },
          "be_reference": {
            "type": "string | null",
            "description": "Specific BE artifact reference",
            "example": "paths./api/auth/login.post.responses.200 -> LoginResponse.token"
          },
          "db_reference": {
            "type": "string | null",
            "description": "Specific DB artifact reference",
            "example": null
          }
        }
      }
    }
  },
  "summary": {
    "type": "object",
    "description": "Aggregate summary of findings",
    "fields": {
      "total_findings": {
        "type": "integer",
        "example": 15
      },
      "by_category": {
        "type": "object",
        "example": {
          "fe_be_mismatch": 5,
          "be_db_mismatch": 4,
          "cross_module_inconsistency": 2,
          "naming_violation": 2,
          "missing_error_handling": 1,
          "security_gap": 1
        }
      },
      "by_severity": {
        "type": "object",
        "example": {
          "critical": 1,
          "major": 6,
          "minor": 5,
          "info": 3
        }
      },
      "by_layer": {
        "type": "object",
        "description": "Count of findings affecting each layer",
        "example": {
          "fe": 7,
          "be": 10,
          "db": 6
        }
      },
      "auto_fixable_count": {
        "type": "integer",
        "example": 9
      }
    }
  }
}
```

---

## Dependencies

| Depends On | Agent | Artifact | Why |
|---|---|---|---|
| input | `fe_contract` (all modules) | `fe_details.json` | FE layer contracts — endpointProposals, dataDisplayed, dataCaptured |
| input | `be_contract` (all modules) | `openapi.json` | BE layer contracts — API endpoints, schemas, security |
| input | `db_contract` (all modules) | `prisma_contract.json` | DB layer contracts — models, fields, relations |

| Blocks | Agent | Why |
|---|---|---|
| output | `unified_reconcile` | Reconcile agent needs findings to determine what cross-layer fixes to apply |

---

## Orchestrator Communication

**Agent Identity:** `unified_review` — 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 all per-module contract agents (fe_contract, be_contract, db_contract) have completed |
| `tracker_update` | `ag` | Report agent status (in_progress, completed, failed) |

### Output Meta

`null` — This agent produces review findings only. No routing metadata for the orchestrator.

### Completion Signal

**Success:**
```
tracker_update({ agent_status: { agent_id: "unified_review", status: "completed" } })
```

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

### Scope Resolution

Global agent. Operates across all modules and all contract layers (FE, BE, DB) in a single invocation.

---

## Compressed Keymap

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

### unified_review_output.json

| Key | Full Name | Description |
|---|---|---|
| `ri` | review_id | Unique review run identifier |
| `t` | timestamp | ISO-8601 timestamp |
| `mr` | modules_reviewed | List of module IDs reviewed |
| `lr` | layers_reviewed | Contract layers reviewed (fe, be, db) |
| `fi` | findings | Array of cross-layer finding objects |
| `fid` | finding_id | Unique finding identifier |
| `ct` | category | Finding category (fe_be_mismatch, be_db_mismatch, cross_module_inconsistency, etc.) |
| `sv` | severity | Finding severity (critical, major, minor, info) |
| `la` | layers_affected | Contract layers involved (fe, be, db) |
| `am` | affected_modules | Modules affected by this finding |
| `ds` | description | Human-readable description of the cross-layer issue |
| `sg` | suggestion | Recommended fix specifying which layer(s) should change |
| `af` | auto_fixable | Whether unified_reconcile can auto-fix this |
| `ft` | fix_target | Which layer to modify: fe / be / db / multiple |
| `ev` | evidence | Supporting data object |
| `efr` | fe_reference | Specific FE artifact reference |
| `ebr` | be_reference | Specific BE artifact reference |
| `edr` | db_reference | Specific DB artifact reference |
| `sm` | summary | Aggregate summary object |
| `stf` | total_findings | Total number of findings |
| `sbc` | by_category | Findings count per category |
| `sbs` | by_severity | Findings count per severity |
| `sbl` | by_layer | Findings count per affected layer |
| `saf` | auto_fixable_count | Count of auto-fixable findings |

---

## Tools Required

| Tool | Purpose |
|---|---|
| `node_write` | Write agent output artifacts using compressed keys. Output key: `unified_review_output` |
| `node_read` | Read input artifacts from upstream agents. Input keys: `fe_details`, `openapi`, `prisma_contract` |
| `tracker_read` | Read tracker state — agent statuses to confirm upstream completion |
| `tracker_update` | Report agent status and completion signal |

---

## Guardrails

### Rules

| ID | Category | Severity | Rule |
|---|---|---|---|
| R-001 | `constraint` | `must` | Must check all PRESENT contract layers together. If only 2 layers exist (e.g., BE+DB without FE), review those 2 for consistency. A review that ignores a present layer is incomplete, but a review must NOT fail because an absent layer is missing. |
| R-002 | `constraint` | `must` | Must verify that every FE endpointProposal either matches a BE endpoint (honored) or is documented as reshaped/rejected in the BE spec's x-fe-proposal-ref. |
| R-003 | `constraint` | `must` | Must verify that every BE request/response schema field has a corresponding DB model field, or is explicitly documented as computed/derived. |
| R-004 | `constraint` | `must` | Must verify referential integrity across layers — if FE references a data field, BE must expose it, and DB must store it. |
| R-005 | `constraint` | `must` | Must flag security gaps — endpoints without authentication requirements, models storing sensitive data without encryption markers, missing authorization checks. |
| R-006 | `output_quality` | `must` | Every finding must specify fix_target indicating which layer should be modified. Cross-layer fixes affecting multiple layers must use fix_target: "multiple". |
| R-007 | `constraint` | `should` | Should check cross-module consistency — if a "User" model exists in both auth and dashboard modules, the field definitions must be compatible. |
| R-008 | `output_quality` | `should` | Should check naming conventions across layers — consistent field naming (e.g., userId vs user_id vs UserId) should be enforced. |
| R-009 | `not_allowed` | `must` | Must not modify any contract files. The unified review agent produces findings — the unified reconcile agent applies fixes. |
| R-010 | `scope_boundary` | `must` | Must not re-review issues already covered by fe_review. Unified review focuses on cross-layer issues, not within-layer issues. |
| R-011 | `constraint` | `should` | Should verify that BE error response schemas are consistent across endpoints (same ErrorResponse structure). |
| R-012 | `output_quality` | `must` | Every finding must include evidence with specific artifact references (fe_reference, be_reference, db_reference) so the reconcile agent knows exactly what to fix. |
| R-013 | `constraint` | `must` | Must use compressed keys for all `node_write` and `node_read` calls. Raw/uncompressed keys are rejected by the registry. |
| R-014 | `constraint` | `must` | Must use `node_write`/`node_read` for all artifact I/O. Raw file system writes are not permitted for pipeline artifacts. |
| R-015 | `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_findings | 300 |
| timeout_seconds | 600 |

---

## Scope Boundary

**In scope:**
- FE-to-BE consistency checking (endpointProposals vs openapi paths)
- BE-to-DB consistency checking (API schemas vs Prisma model fields)
- FE-to-DB traceability checking (displayed/captured data has storage path through BE to DB)
- Cross-module entity consistency (shared models defined consistently)
- Naming convention validation across all three layers
- Security gap identification (auth, authorization, data protection)
- Error handling consistency across BE endpoints
- Referential integrity across all three contract layers

**Out of scope:**
- Within-layer FE review (that is fe_review's job)
- Visual review of wireframes (that is a human task)
- Performance analysis or optimization
- Code-level review (no code exists at this phase)
- Modifying any contract files (that is unified_reconcile's job)
- Infrastructure or deployment review
- API rate limiting or throttling design (that is Phase 7)
- Database query optimization (that is Phase 6 db_interaction)

---

## Triggers

- Orchestrator activates this agent when ALL modules have completed their db_contract (the last contract agent in the per-module flow)
- This is a mandatory review gate — the pipeline cannot proceed to Phase 6 without passing unified review
- In retrofit mode, activated for all modules that have any layer changes

---

## Checkpoints

| ID | Description | Action |
|---|---|---|
| `CP-001` | All FE contract files loaded across modules | `log` |
| `CP-002` | All BE contract files loaded across modules | `log` |
| `CP-003` | All DB contract files loaded across modules | `log` |
| `CP-004` | FE-to-BE consistency analysis complete | `log` |
| `CP-005` | BE-to-DB consistency analysis complete | `log` |
| `CP-006` | Cross-module entity consistency analysis complete | `log` |
| `CP-007` | Security gap analysis complete | `log` |
| `CP-008` | Naming convention analysis complete | `log` |
| `CP-009` | Review findings finalized and written | `notify` — findings are available for unified reconcile |

---

## Validation Criteria

- unified_review_output.json conforms to the defined schema
- Every finding has a non-empty finding_id, category, severity, description, suggestion, and fix_target
- finding_id values are unique across all findings
- layers_affected values are valid (fe, be, db only)
- affected_modules references exist in the modules_reviewed list
- All six categories are checked — empty categories should still appear in by_category with count 0
- by_layer counts accurately reflect the findings' layers_affected arrays
- Evidence fields (fe_reference, be_reference, db_reference) are populated for the relevant layers in each finding
- auto_fixable_count equals the count of findings with auto_fixable: true
- Summary totals match actual findings array contents

---

## Context Sources

- fe_details.json from all modules (FE Contract Agent output)
- openapi.json from all modules (BE Contract Agent output)
- prisma_contract.json from all modules (DB Contract Agent output)
- design_tokens.json from Theming Agent (for naming convention reference)
- user_stories from all modules (for traceability verification)
- OpenAPI 3.0 specification (for BE contract validation)
- Prisma documentation (for DB contract validation)

---

## Operation Mode

| Field | Value |
|---|---|
| Type | `autonomous` |
| Fallback | `none` — unified review is mandatory; if it fails, the pipeline stalls at Phase 5 |

---

## 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 status |
| `TG-004` | `tracker_update` — Universal tool for reporting agent status and completion signals | this agent | Orchestrator cannot track agent progress or route downstream agents |
| `TG-005` | Cross-layer consistency checker that compares FE endpointProposals against BE openapi paths, and BE schemas against DB model fields, identifying field name mismatches, type mismatches, and missing fields | this agent | Cross-layer mismatches would only be caught during implementation, causing expensive rework across all three layers |
| `TG-006` | OpenAPI-to-Prisma mapper that maps API schema properties to Prisma model fields, comparing types (string/String, integer/Int) and identifying unmapped fields | this agent | BE-to-DB field gaps would cause runtime errors when the API layer tries to read/write data that the DB layer does not support |
| `TG-007` | Naming convention validator that checks field naming across all three layers (camelCase for FE/BE, PascalCase for models, consistent casing for shared identifiers) | this agent | Inconsistent naming would cause confusion and potential field mapping errors in code generation |

---

## Generation Readiness

| `generate_agent` Param | Status | Notes |
|---|---|---|
| `fileName` | ready | `unified-review` |
| `agentName` | ready | `unified_review` |
| `agentRole` | ready | "Cross-Layer Contract Consistency Reviewer" |
| `agentDescription` | ready | Full description available from Goal section |
| `operationMode` | ready | `autonomous`, no fallback |
| `goal` | ready | 3 objectives defined with priorities |
| `inputs` | ready | 3 inputs: fe_details.json (all modules), openapi.json (all modules), prisma_contract.json (all modules) — all required |
| `guardrails` | ready | 15 rules defined across constraint, output_quality, not_allowed, scope_boundary categories |
| `scopeBoundary` | ready | 8 in-scope items, 8 out-of-scope items |
| `outputFormat` | ready | JSON (unified_review_output.json) with full schema including cross-layer evidence |
| `triggers` | ready | 3 triggers defined |
| `checkpoints` | ready | 9 checkpoints with actions |
| `validation` | ready | 10 validation criteria |
| `contextSources` | ready | 7 context sources |
| `metadata` | ready | phase: "5", mode: "both", granularity: "global" |
