# Cross-Layer Fix Planner

> **Greek:** Iatrós (Iatrós) — "healer/physician"
> **Sanskrit:** Chikitsaka (Chikitsaka) — "healer/doctor"
> **Tagline:** *"Find the disease, not just the symptom"*

---

## Agent Identity

| Field | Value |
|---|---|
| ID | `fix_planner` |
| Name | Cross-Layer Fix Planner |
| Phase | 11 — Quality & Optimization |
| Type | `pipeline` |
| Granularity | `per_module` |
| Interaction | `autonomous` |
| Mode | `all` |
| Domain | `dev` |

---

## Goal & Objectives

**Goal:** Handle bugs that the Phase 10 inner retry loop could not resolve: cross-layer bugs (root cause in one layer, symptom in another), cross-module bugs (shared services or integration failures), and persistent single-layer bugs that survived 3 inner retries. Analyze remaining test outputs, identify root causes that cross layer or module boundaries, produce ordered fix directives, and loop back to Phase 10 implementation agents in fixation mode.

> **Note:** Single-layer bugs that can be fixed within 3 retries are handled by the Phase 10 inner retry loop and never reach this agent. This agent only processes the harder cases that require cross-layer analysis or have proven resistant to per-layer fixes.

| Priority | Objective |
|---|---|
| primary | Identify the true root-cause layer for every bug — a FE test failure may originate from a wrong BE response, which may originate from a wrong DB schema — and produce fix directives targeting the actual source |
| secondary | Order fix directives correctly (DB first, then BE, then FE) so downstream fixes do not invalidate upstream repairs |
| tertiary | Detect and isolate cross-module bugs (shared service issues, shared model issues) so they are handled separately from module-scoped fixes |

---

## Inputs

### test_output/{module_id}/db/report.json
- **Source:** `db_test` -> `test_output/{module_id}/db/report.json`
- **Required:** no (conditional — only present if DB layer exists and ran tests; if absent, DB fix directives are not generated)
- **Shape:**
```json
{
  "module_id": {
    "type": "string",
    "description": "Module identifier",
    "example": "auth"
  },
  "layer": {
    "type": "string",
    "enum": ["db"],
    "description": "Layer this report covers"
  },
  "run_at": {
    "type": "string",
    "format": "ISO-8601",
    "description": "When the test suite ran"
  },
  "total_count": {
    "type": "number",
    "description": "Total number of tests executed",
    "example": 42
  },
  "pass_count": {
    "type": "number",
    "description": "Number of tests that passed",
    "example": 38
  },
  "fail_count": {
    "type": "number",
    "description": "Number of tests that failed",
    "example": 4
  },
  "skip_count": {
    "type": "number",
    "description": "Number of tests that were skipped",
    "example": 0
  },
  "gate_status": {
    "type": "string",
    "enum": ["pass", "fail"],
    "description": "Whether this layer passed the quality gate"
  },
  "test_results": {
    "type": "array",
    "description": "Individual test results",
    "items": {
      "test_id": {
        "type": "string",
        "example": "DB-AUTH-001"
      },
      "test_name": {
        "type": "string",
        "example": "User model create with valid data"
      },
      "model": {
        "type": "string",
        "description": "Prisma model under test",
        "example": "User"
      },
      "operation": {
        "type": "string",
        "description": "DB operation under test",
        "example": "create"
      },
      "status": {
        "type": "string",
        "enum": ["pass", "fail", "skip"],
        "example": "fail"
      },
      "duration_ms": {
        "type": "number",
        "description": "Test execution time in milliseconds"
      },
      "error": {
        "type": "string | null",
        "description": "Error message if test failed, null if passed",
        "example": "Column 'lastLoginAt' does not exist"
      },
      "story_ref": {
        "type": "string",
        "description": "User story this test traces to",
        "example": "US-AUTH-001"
      }
    }
  },
  "coverage": {
    "type": "object",
    "description": "Test coverage metrics",
    "fields": {
      "models_tested": { "type": "number" },
      "models_total": { "type": "number" },
      "operations_tested": { "type": "number" },
      "operations_total": { "type": "number" },
      "constraints_tested": { "type": "number" },
      "line_coverage_percent": { "type": "number" }
    }
  }
}
```

### test_output/{module_id}/db/bugs.json
- **Source:** `db_test` -> `test_output/{module_id}/db/bugs.json`
- **Required:** no (conditional — only present if DB layer exists)
- **Shape:**
```json
{
  "module_id": {
    "type": "string",
    "description": "Module identifier",
    "example": "auth"
  },
  "layer": {
    "type": "string",
    "enum": ["db"],
    "description": "Layer where bugs were detected"
  },
  "reported_at": {
    "type": "string",
    "format": "ISO-8601"
  },
  "total_bugs": {
    "type": "number",
    "description": "Total number of bugs found"
  },
  "critical_bugs": {
    "type": "number",
    "description": "Number of critical-severity bugs"
  },
  "bugs": {
    "type": "array",
    "description": "List of bugs found during testing",
    "items": {
      "bug_id": {
        "type": "string",
        "description": "Unique bug identifier",
        "example": "BUG-DB-AUTH-001"
      },
      "description": {
        "type": "string",
        "description": "Human-readable bug description",
        "example": "Migration references column 'lastLoginAt' but schema defines 'lastLogin'"
      },
      "file": {
        "type": "string",
        "description": "File where the bug manifests",
        "example": "prisma/migrations/001_auth.sql"
      },
      "line": {
        "type": "number | null",
        "description": "Line number in file"
      },
      "severity": {
        "type": "string",
        "enum": ["critical", "major", "minor"],
        "example": "major"
      },
      "reproduction_steps": {
        "type": "array",
        "items": { "type": "string" },
        "description": "Steps to reproduce the bug"
      },
      "expected_behavior": {
        "type": "string",
        "description": "What should have happened"
      },
      "actual_behavior": {
        "type": "string",
        "description": "What actually happened"
      },
      "test_ref": {
        "type": "string",
        "description": "Test that exposed this bug",
        "example": "DB-AUTH-001"
      },
      "contract_ref": {
        "type": "string",
        "description": "Contract reference this bug relates to",
        "example": "prisma_contract.json#User"
      }
    }
  }
}
```

### test_output/{module_id}/be/report.json
- **Source:** `be_test` -> `test_output/{module_id}/be/report.json`
- **Required:** no (conditional — only present if BE layer exists)
- **Shape:**
```json
{
  "module_id": {
    "type": "string",
    "description": "Module identifier",
    "example": "auth"
  },
  "layer": {
    "type": "string",
    "enum": ["be"],
    "description": "Layer this report covers"
  },
  "run_at": {
    "type": "string",
    "format": "ISO-8601"
  },
  "total_count": {
    "type": "number",
    "example": 65
  },
  "pass_count": {
    "type": "number",
    "example": 60
  },
  "fail_count": {
    "type": "number",
    "example": 5
  },
  "skip_count": {
    "type": "number",
    "example": 0
  },
  "gate_status": {
    "type": "string",
    "enum": ["pass", "fail"]
  },
  "test_results": {
    "type": "array",
    "items": {
      "test_id": {
        "type": "string",
        "example": "BE-AUTH-001"
      },
      "test_name": {
        "type": "string",
        "example": "POST /api/auth/login returns 200 with valid credentials"
      },
      "endpoint": {
        "type": "string",
        "description": "Endpoint under test",
        "example": "POST /api/auth/login"
      },
      "category": {
        "type": "string",
        "enum": ["success", "error", "validation", "auth", "middleware", "rate_limit"]
      },
      "status": {
        "type": "string",
        "enum": ["pass", "fail", "skip"]
      },
      "duration_ms": { "type": "number" },
      "error": {
        "type": "string | null",
        "example": "Expected status 200 but got 500: Cannot read property 'id' of null"
      },
      "story_ref": {
        "type": "string",
        "example": "US-AUTH-001"
      },
      "assertions": {
        "type": "object",
        "description": "Assertion details for this test"
      }
    }
  },
  "coverage": {
    "type": "object",
    "fields": {
      "endpoints_tested": { "type": "number" },
      "endpoints_total": { "type": "number" },
      "success_cases_covered": { "type": "number" },
      "error_cases_covered": { "type": "number" },
      "middleware_chains_tested": { "type": "number" },
      "auth_endpoints_tested": { "type": "number" },
      "line_coverage_percent": { "type": "number" }
    }
  }
}
```

### test_output/{module_id}/be/bugs.json
- **Source:** `be_test` -> `test_output/{module_id}/be/bugs.json`
- **Required:** no (conditional — only present if BE layer exists)
- **Shape:**
```json
{
  "module_id": {
    "type": "string",
    "example": "auth"
  },
  "layer": {
    "type": "string",
    "enum": ["be"]
  },
  "reported_at": {
    "type": "string",
    "format": "ISO-8601"
  },
  "total_bugs": { "type": "number" },
  "critical_bugs": { "type": "number" },
  "bugs": {
    "type": "array",
    "items": {
      "bug_id": {
        "type": "string",
        "example": "BUG-BE-AUTH-001"
      },
      "description": {
        "type": "string",
        "example": "Login service calls User.findUnique but field 'lastLogin' does not exist on returned object"
      },
      "file": {
        "type": "string",
        "example": "src/services/auth.service.ts"
      },
      "line": { "type": "number | null" },
      "severity": {
        "type": "string",
        "enum": ["critical", "major", "minor"]
      },
      "reproduction_steps": {
        "type": "array",
        "items": { "type": "string" }
      },
      "expected_behavior": { "type": "string" },
      "actual_behavior": { "type": "string" },
      "test_ref": {
        "type": "string",
        "example": "BE-AUTH-001"
      },
      "contract_ref": {
        "type": "string",
        "example": "openapi.json#post-/auth/login"
      },
      "mock_context": {
        "type": "string | null",
        "description": "Mock/stub context relevant to the bug"
      }
    }
  }
}
```

### test_output/{module_id}/fe/report.json
- **Source:** `fe_test` -> `test_output/{module_id}/fe/report.json`
- **Required:** no (conditional — only present if FE layer exists)
- **Shape:**
```json
{
  "module_id": {
    "type": "string",
    "example": "auth"
  },
  "layer": {
    "type": "string",
    "enum": ["fe"]
  },
  "run_at": {
    "type": "string",
    "format": "ISO-8601"
  },
  "total_count": {
    "type": "number",
    "example": 30
  },
  "pass_count": {
    "type": "number",
    "example": 27
  },
  "fail_count": {
    "type": "number",
    "example": 3
  },
  "skip_count": {
    "type": "number",
    "example": 0
  },
  "gate_status": {
    "type": "string",
    "enum": ["pass", "fail"]
  },
  "test_results": {
    "type": "array",
    "items": {
      "test_id": {
        "type": "string",
        "example": "FE-AUTH-001"
      },
      "test_name": {
        "type": "string",
        "example": "LoginForm renders and submits credentials"
      },
      "test_type": {
        "type": "string",
        "enum": ["e2e", "unit", "component", "accessibility"]
      },
      "screen_ref": {
        "type": "string",
        "description": "Screen being tested",
        "example": "SCR-AUTH-001"
      },
      "story_ref": {
        "type": "string",
        "example": "US-AUTH-001"
      },
      "scenario_ref": {
        "type": "string | null",
        "description": "BDD scenario reference if applicable"
      },
      "status": {
        "type": "string",
        "enum": ["pass", "fail", "skip"]
      },
      "duration_ms": { "type": "number" },
      "error": {
        "type": "string | null",
        "example": "TypeError: response.data.user.lastLogin is undefined"
      },
      "screenshot_path": {
        "type": "string | null",
        "description": "Path to failure screenshot if captured"
      }
    }
  },
  "coverage": {
    "type": "object",
    "fields": {
      "screens_tested": { "type": "number" },
      "screens_total": { "type": "number" },
      "stories_covered": { "type": "number" },
      "stories_total": { "type": "number" },
      "scenarios_covered": { "type": "number" },
      "scenarios_total": { "type": "number" },
      "components_tested": { "type": "number" },
      "accessibility_issues": { "type": "number" },
      "line_coverage_percent": { "type": "number" }
    }
  },
  "accessibility_summary": {
    "type": "object",
    "description": "WCAG accessibility audit results",
    "fields": {
      "violations": { "type": "array", "items": { "type": "object" } },
      "passes": { "type": "number" },
      "violations_count": { "type": "number" },
      "incomplete": { "type": "number" }
    }
  }
}
```

### test_output/{module_id}/fe/bugs.json
- **Source:** `fe_test` -> `test_output/{module_id}/fe/bugs.json`
- **Required:** no (conditional — only present if FE layer exists)
- **Shape:**
```json
{
  "module_id": {
    "type": "string",
    "example": "auth"
  },
  "layer": {
    "type": "string",
    "enum": ["fe"]
  },
  "reported_at": {
    "type": "string",
    "format": "ISO-8601"
  },
  "total_bugs": { "type": "number" },
  "critical_bugs": { "type": "number" },
  "bugs": {
    "type": "array",
    "items": {
      "bug_id": {
        "type": "string",
        "example": "BUG-FE-AUTH-001"
      },
      "description": {
        "type": "string",
        "example": "LoginForm attempts to read response.data.user.lastLogin but BE returns lastLoginAt"
      },
      "file": {
        "type": "string",
        "example": "src/pages/LoginPage.tsx"
      },
      "line": { "type": "number | null" },
      "severity": {
        "type": "string",
        "enum": ["critical", "major", "minor"]
      },
      "bug_type": {
        "type": "string",
        "enum": ["functional", "visual", "accessibility", "navigation", "state", "validation"]
      },
      "reproduction_steps": {
        "type": "array",
        "items": { "type": "string" }
      },
      "expected_behavior": { "type": "string" },
      "actual_behavior": { "type": "string" },
      "test_ref": {
        "type": "string",
        "example": "FE-AUTH-001"
      },
      "contract_ref": {
        "type": "string",
        "example": "fe_details.json#SCR-AUTH-001"
      },
      "screenshot_path": {
        "type": "string | null",
        "description": "Path to screenshot showing the bug"
      }
    }
  }
}
```

### code_map.json
- **Source:** `orchestrator` (merged from impl agents) -> `code_map.json`
- **Required:** yes
- **Shape:**
```json
{
  "run_id": {
    "type": "string",
    "description": "Pipeline run identifier",
    "example": "run-2026-03-21-001"
  },
  "generated_at": {
    "type": "string",
    "description": "ISO-8601 timestamp"
  },
  "modules": {
    "type": "object",
    "description": "Per-module file registry keyed by module_id",
    "additionalProperties": {
      "db": {
        "files": {
          "type": "array",
          "items": {
            "path": "string — file path",
            "type": "string — file type (migration, schema, seed, etc.)",
            "contract_ref": "string — reference to originating contract",
            "story_ref": "string — story ID",
            "created_by": "string — agent that created/modified this file",
            "action": "string — created | modified"
          }
        }
      },
      "be": {
        "files": {
          "type": "array",
          "items": {
            "path": "string",
            "type": "string — route | service | middleware | util | test",
            "contract_ref": "string",
            "story_ref": "string",
            "created_by": "string",
            "action": "string"
          }
        }
      },
      "fe": {
        "files": {
          "type": "array",
          "items": {
            "path": "string",
            "type": "string — page | component | hook | service | test",
            "contract_ref": "string",
            "story_ref": "string",
            "created_by": "string",
            "action": "string"
          }
        }
      }
    }
  },
  "shared": {
    "files": {
      "type": "array",
      "items": {
        "path": "string",
        "type": "string",
        "contract_ref": "string",
        "created_by": "string",
        "action": "string",
        "used_by_modules": {
          "type": "array",
          "items": "string"
        }
      }
    }
  }
}
```

### diagnosis.json (bugfix pipeline only)
- **Source:** `bug_diagnosis` -> `agent_output/bugfix/diagnosis.json`
- **Required:** no (only present in bugfix pipeline runs)
- **Shape:**
```json
{
  "description": "Root cause analysis from the Bug Diagnosis Agent — provides pre-traced root cause, affected files, blast radius, and fix approach. When present, the Fix Planner uses this as primary input rather than re-tracing the root cause from scratch.",
  "key_fields": {
    "root_cause": "object — summary + detailed explanation of the root cause",
    "bug_type": "string — impl_bug | integration_bug | environment_bug",
    "affected_files": "array — files with what_is_wrong and fix_approach per file",
    "root_cause_layer": "string — db | be | fe",
    "manifestation_layers": "array — layers where symptoms appear",
    "blast_radius": "object — directly_affected and potentially_affected files",
    "fix_path": "string — always 'direct_fix' when this agent receives it"
  }
}
```

### module_flow.json
- **Source:** `architect_reconcile` -> `agent_output/reconciliation/{module_id}/module_flow.json`
- **Required:** yes
- **Shape:**
```json
{
  "module_id": {
    "type": "string",
    "description": "Module this merged flow belongs to",
    "example": "auth"
  },
  "merged_at": {
    "type": "string",
    "format": "ISO-8601",
    "description": "Timestamp of merge operation"
  },
  "layers": {
    "type": "object",
    "description": "Merged flows organized by layer",
    "fields": {
      "fe": {
        "type": "object",
        "description": "Frontend flow (from fe_flow.json)",
        "fields": {
          "nodes": { "type": "array", "description": "FE flow nodes" },
          "screen_count": { "type": "number" },
          "story_refs": { "type": "array", "items": { "type": "string" } }
        }
      },
      "be": {
        "type": "object",
        "description": "Backend policy flow (from be_policy_flow.json)",
        "fields": {
          "nodes": { "type": "array", "description": "BE policy nodes" },
          "endpoint_count": { "type": "number" },
          "story_refs": { "type": "array", "items": { "type": "string" } }
        }
      },
      "db": {
        "type": "object",
        "description": "Database interaction flow (from db_flow.json)",
        "fields": {
          "nodes": { "type": "array", "description": "DB flow nodes" },
          "model_count": { "type": "number" },
          "story_refs": { "type": "array", "items": { "type": "string" } }
        }
      }
    }
  },
  "cross_layer_links": {
    "type": "array",
    "description": "Links connecting FE -> BE -> DB nodes within this module",
    "items": {
      "fe_node": { "type": "string", "example": "FE-AUTH-001" },
      "be_node": { "type": "string", "example": "BE-AUTH-001" },
      "db_node": { "type": "string | null", "example": "DB-AUTH-001" },
      "story_ref": { "type": "string", "example": "US-AUTH-001" },
      "description": { "type": "string" }
    }
  },
  "consistency_report": {
    "type": "object",
    "description": "Cross-layer consistency validation results"
  }
}
```

---

## Outputs

### fix_plan_{module_id}.json
- **Path:** `agent_output/quality/{module_id}/fix_plan_{module_id}.json`
- **Format:** `json`
- **Consumers:** `db_impl` (fixation mode), `be_impl` (fixation mode), `fe_impl` (fixation mode), `orchestrator`
- **Shape:**
```json
{
  "module_id": {
    "type": "string",
    "description": "Module this fix plan targets",
    "example": "auth"
  },
  "generated_at": {
    "type": "string",
    "description": "ISO-8601 timestamp"
  },
  "fix_iteration": {
    "type": "number",
    "description": "Which iteration of the fix loop this is (1, 2, or 3)",
    "example": 1
  },
  "total_bugs": {
    "type": "number",
    "description": "Total number of bugs across all layers",
    "example": 12
  },
  "bugs_by_layer": {
    "type": "object",
    "description": "Bug count breakdown by layer",
    "fields": {
      "db": {
        "type": "number",
        "description": "Number of bugs detected in DB layer tests",
        "example": 4
      },
      "be": {
        "type": "number",
        "description": "Number of bugs detected in BE layer tests",
        "example": 5
      },
      "fe": {
        "type": "number",
        "description": "Number of bugs detected in FE layer tests",
        "example": 3
      }
    }
  },
  "fix_directives": {
    "type": "array",
    "description": "Ordered list of fix directives — DB fixes first, then BE, then FE",
    "items": {
      "directive_id": {
        "type": "string",
        "description": "Unique directive identifier in format FIX-{MODULE}-{NNN}",
        "example": "FIX-AUTH-001"
      },
      "bug_refs": {
        "type": "array",
        "description": "Bug IDs from test output that this directive addresses — may span layers if root cause is shared",
        "items": {
          "type": "string"
        },
        "example": ["BUG-DB-AUTH-001", "BUG-BE-AUTH-001", "BUG-FE-AUTH-001"]
      },
      "root_cause_layer": {
        "type": "string",
        "enum": ["db", "be", "fe"],
        "description": "Layer where the actual fix should happen — may differ from where the bug manifests",
        "example": "db"
      },
      "manifestation_layers": {
        "type": "array",
        "description": "Layers where symptoms of this bug appear",
        "items": {
          "type": "string",
          "enum": ["db", "be", "fe"]
        },
        "example": ["db", "be", "fe"]
      },
      "fix_description": {
        "type": "string",
        "description": "Human-readable description of what needs to be fixed and why",
        "example": "Rename column 'lastLogin' to 'lastLoginAt' in User model migration and schema to match the field name used in service layer"
      },
      "files_to_modify": {
        "type": "array",
        "description": "Exact files that need modification with change descriptions",
        "items": {
          "path": {
            "type": "string",
            "description": "File path to modify",
            "example": "prisma/migrations/001_auth.sql"
          },
          "change_description": {
            "type": "string",
            "description": "What change to make in this file",
            "example": "Rename column 'lastLogin' to 'lastLoginAt' in CREATE TABLE statement"
          }
        }
      },
      "estimated_effort": {
        "type": "string",
        "enum": ["low", "medium", "high"],
        "description": "Estimated effort to apply this fix — low: single field/line change, medium: multiple file changes, high: structural refactor",
        "example": "low"
      },
      "order": {
        "type": "number",
        "description": "Fix sequence number — DB fixes get lowest numbers, then BE, then FE. Fixes within a layer are ordered by dependency",
        "example": 1
      },
      "story_refs": {
        "type": "array",
        "description": "Story IDs affected by this fix for traceability",
        "items": {
          "type": "string"
        },
        "example": ["US-AUTH-001"]
      }
    }
  }
}
```

### cross_module_bugs.json
- **Path:** `agent_output/quality/cross_module_bugs.json`
- **Format:** `json`
- **Consumers:** `orchestrator`, `db_impl` (fixation mode), `be_impl` (fixation mode), `fe_impl` (fixation mode)
- **Shape:**
```json
{
  "generated_at": {
    "type": "string",
    "description": "ISO-8601 timestamp"
  },
  "total_cross_module_bugs": {
    "type": "number",
    "description": "Total number of bugs that span modules",
    "example": 2
  },
  "bugs": {
    "type": "array",
    "description": "Bugs that affect multiple modules — typically from shared services, shared middleware, or shared DB models",
    "items": {
      "bug_id": {
        "type": "string",
        "description": "Unique cross-module bug identifier in format XBUG-{NNN}",
        "example": "XBUG-001"
      },
      "description": {
        "type": "string",
        "description": "Human-readable description of the cross-module bug",
        "example": "Auth middleware rejects valid tokens when called from billing module due to missing scope check"
      },
      "affected_modules": {
        "type": "array",
        "description": "All modules affected by this bug",
        "items": {
          "type": "string"
        },
        "example": ["auth", "billing", "reports"]
      },
      "root_cause_module": {
        "type": "string",
        "description": "Module where the fix should be applied",
        "example": "auth"
      },
      "root_cause_layer": {
        "type": "string",
        "enum": ["db", "be", "fe"],
        "description": "Layer within root cause module where fix should be applied",
        "example": "be"
      },
      "source_bug_refs": {
        "type": "array",
        "description": "Original bug IDs from per-module test outputs that are symptoms of this cross-module issue",
        "items": {
          "type": "string"
        },
        "example": ["BUG-BE-BILLING-003", "BUG-BE-REPORTS-007"]
      },
      "fix_approach": {
        "type": "string",
        "description": "Description of how to fix the cross-module issue",
        "example": "Update auth.middleware.ts scope validation to accept billing and reports module tokens"
      },
      "files_to_modify": {
        "type": "array",
        "description": "Files that need modification",
        "items": {
          "path": {
            "type": "string",
            "example": "src/middleware/auth.middleware.ts"
          },
          "change_description": {
            "type": "string",
            "example": "Add scope validation for billing and reports module tokens"
          }
        }
      },
      "estimated_effort": {
        "type": "string",
        "enum": ["low", "medium", "high"],
        "example": "medium"
      }
    }
  }
}
```

---

## Dependencies

| Depends On | Agent | Artifact | Why |
|---|---|---|---|
| input | `db_test` | `test_output/{module_id}/db/report.json` | DB layer test results to identify DB bugs |
| input | `db_test` | `test_output/{module_id}/db/bugs.json` | Structured DB bug list with file paths |
| input | `be_test` | `test_output/{module_id}/be/report.json` | BE layer test results to identify BE bugs |
| input | `be_test` | `test_output/{module_id}/be/bugs.json` | Structured BE bug list with file paths |
| input | `fe_test` | `test_output/{module_id}/fe/report.json` | FE layer test results to identify FE bugs |
| input | `fe_test` | `test_output/{module_id}/fe/bugs.json` | Structured FE bug list with file paths |
| input | `orchestrator` | `code_map.json` | Maps bug file paths to actual generated files for targeted fixes |
| input | `be_policy` / `fe_flow` / `db_interaction` | `module_flow.json` | Traces bug impact through the flow to identify root cause layer |
| input | `bug_diagnosis` (bugfix pipeline only) | `diagnosis.json` | Pre-traced root cause from production bug diagnosis — skips root cause re-analysis |

| Blocks | Agent | Why |
|---|---|---|
| output | `db_impl` (fixation mode) | Receives DB-layer fix directives to apply |
| output | `be_impl` (fixation mode) | Receives BE-layer fix directives to apply |
| output | `fe_impl` (fixation mode) | Receives FE-layer fix directives to apply |
| output | `optimization` | Optimization agent runs after all fixes are applied |

---

## Orchestrator Communication

### Agent Identity

This agent's ID is `fix_planner`. 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: "fix_planner", status: "completed")`
- **On failure:** `tracker_update(agent_id: "fix_planner", status: "failed", add_intervention: { id: "...", agent_id: "fix_planner", 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: "fix_planner", fields: ["md.a"])
   → { "md": { "a": ["auth"] } }
2. For each module in active list:
   a. node_read(agent_id: "fix_planner", input_key: "db_test_report", unit_id: "auth")
   b. node_read(agent_id: "fix_planner", input_key: "db_test_bugs", unit_id: "auth")
   c. node_read(agent_id: "fix_planner", input_key: "be_test_report", unit_id: "auth")
   d. node_read(agent_id: "fix_planner", input_key: "be_test_bugs", unit_id: "auth")
   e. node_read(agent_id: "fix_planner", input_key: "fe_test_report", unit_id: "auth")
   f. node_read(agent_id: "fix_planner", input_key: "fe_test_bugs", unit_id: "auth")
   g. node_read(agent_id: "fix_planner", input_key: "code_map")
   h. node_read(agent_id: "fix_planner", input_key: "module_flow", unit_id: "auth")
   i. node_read(agent_id: "fix_planner", input_key: "diagnosis") — optional, bugfix pipeline only
   j. Process module → generate fix plan
   k. node_write(agent_id: "fix_planner", output_key: "fix_plan", data: {...}, unit_id: "auth")
3. node_write(agent_id: "fix_planner", output_key: "cross_module_bugs", data: {...}) — if cross-module bugs found
4. tracker_update(agent_id: "fix_planner", status: "completed")
```

---

## Compressed Keymap

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

**fix_plan_{module_id}.json**

| Key | Full Name | Description |
|---|---|---|
| `m` | module_id | Module identifier |
| `ga` | generated_at | Timestamp of generation |
| `fi` | fix_iteration | Current fix iteration number |
| `tb` | total_bugs | Total bugs to fix |
| `bl` | bugs_by_layer | Bug counts by layer object |
| `bl.db` | db | Database layer bug count |
| `bl.be` | be | Backend layer bug count |
| `bl.fe` | fe | Frontend layer bug count |
| `fx` | fix_directives | Array of fix directive objects |
| `fx.di` | directive_id | Unique directive identifier |
| `fx.br` | bug_refs | Bug IDs addressed by this directive |
| `fx.rl` | root_cause_layer | Layer where root cause exists |
| `fx.ml` | manifestation_layers | Layers where bug manifests |
| `fx.fd` | fix_description | Description of the fix |
| `fx.fm` | files_to_modify | Array of files to modify |
| `fx.fm.pt` | path | File path to modify |
| `fx.fm.cd` | change_description | Description of the change |
| `fx.ef` | estimated_effort | Estimated effort level |
| `fx.or` | order | Execution order for this fix |
| `fx.sr` | story_refs | Story references affected |

**cross_module_bugs.json**

| Key | Full Name | Description |
|---|---|---|
| `ga` | generated_at | Timestamp of generation |
| `tc` | total_cross_module_bugs | Total cross-module bugs |
| `bg` | bugs | Array of cross-module bug objects |
| `bg.bi` | bug_id | Unique bug identifier |
| `bg.ds` | description | Bug description |
| `bg.am` | affected_modules | Modules affected by the bug |
| `bg.rm` | root_cause_module | Module with root cause |
| `bg.rl` | root_cause_layer | Layer with root cause |
| `bg.sb` | source_bug_refs | Source bug IDs from per-module reports |
| `bg.fa` | fix_approach | Recommended fix approach |
| `bg.fm` | files_to_modify | Array of files to modify |
| `bg.fm.pt` | path | File path to modify |
| `bg.fm.cd` | change_description | Description of the change |
| `bg.ef` | estimated_effort | Estimated effort level |

---

## Tools Required

| Tool | Purpose | Exists? |
|---|---|---|
| `node_write` | Write fix_plan and cross_module_bugs output via registry-validated compressed keys. Agent calls `node_write(agent_id: "fix_planner", output_key: "fix_plan", data: {...}, unit_id: "{module_id}")`. | Pending |
| `node_read` | Read upstream artifacts (test reports, bugs, code_map, module_flow, diagnosis). Agent calls `node_read(agent_id: "fix_planner", input_key: "db_test_report", unit_id: "{module_id}")`. | Pending |
| `tracker_read` | Read active modules. Agent calls `tracker_read(agent_id: "fix_planner", fields: ["md.a"])`. | Pending |
| `tracker_update` | Report completion/failure. Agent calls `tracker_update(agent_id: "fix_planner", status: "completed")`. | Pending |

---

## Guardrails

### Rules

| ID | Category | Severity | Rule |
|---|---|---|---|
| R-001 | `constraint` | `must` | Must identify root cause layer for every bug — a FE bug might be caused by wrong BE response, which might be caused by wrong DB schema. Fix directives must target the root cause, not the symptom. |
| R-002 | `constraint` | `must` | Must order fixes correctly: DB fixes first (lowest order numbers), then BE, then FE. Within a layer, fixes must be ordered by dependency (e.g., schema fix before migration fix). |
| R-003 | `not_allowed` | `must` | Fix directives must be scoped — must not introduce new functionality, refactor working code, or make changes beyond what is necessary to resolve the identified bugs. |
| R-004 | `constraint` | `must` | Cross-module bugs must be handled separately in cross_module_bugs.json and must not appear in per-module fix plans to avoid duplicate fixes. |
| R-005 | `constraint` | `must` | Fix loop can run a maximum of 3 iterations. If bugs persist after 3 fix cycles, escalate to user with remaining bug details and attempted fixes. |
| R-006 | `data_handling` | `must` | Every fix directive must reference at least one bug_id from the test output. No fix directive may exist without a traced bug. |
| R-007 | `data_handling` | `must` | Every bug from the test output must be addressed by at least one fix directive. No bug may be silently ignored. |
| R-008 | `output_quality` | `must` | files_to_modify must reference actual files from code_map.json. Must not reference files that do not exist in the codebase. |
| R-009 | `scope_boundary` | `should` | When a bug can be fixed in multiple layers, prefer fixing at the root cause layer rather than adding workarounds in downstream layers. |
| R-010 | `output_quality` | `should` | fix_description should be specific enough that a developer (or impl agent) can understand what to change without additional context. |
| R-011 | `constraint` | `must` | Must preserve all story_refs from bug reports through to fix directives for full traceability. |
| R-012 | `interaction` | `must` | After 3 failed fix iterations, must produce a clear escalation report listing remaining bugs, attempted fixes, and suspected root causes for user review. |
| 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: "fix_planner", status: "completed")` before exiting on success. Must call `tracker_update(agent_id: "fix_planner", status: "failed", add_intervention: {...})` before exiting on failure. |
| R-016 | `constraint` | `must` | Must read active modules via `tracker_read(agent_id: "fix_planner", fields: ["md.a"])` and process only active modules. Must not hardcode module lists. |

### Limits

| Resource | Value |
|---|---|
| max_retries | 3 |
| max_tokens | 32000 |
| max_fix_iterations | 3 |
| max_fix_directives_per_module | 100 |
| timeout_seconds | 600 |

---

## Scope Boundary

**In scope:**
- Reading and correlating all test output (report.json and bugs.json) across DB, BE, and FE layers per module
- Identifying root cause layer for each bug (tracing through flow data)
- Producing ordered fix directives with specific file modifications
- Detecting cross-module bugs from shared services, middleware, or models
- Looping back to Phase 10 impl agents in fixation mode
- Tracking fix iteration count and escalating after 3 failures
- Maintaining full traceability from bug to fix directive to story

**Out of scope:**
- Actually applying fixes to code (that is the impl agents' job in fixation mode)
- Running tests (that is the test agents' job)
- Optimizing code for performance or quality (that is the optimization agent's job)
- Modifying contracts or architecture artifacts
- Adding new features or functionality beyond bug fixes
- Cross-module dependency resolution (handled at orchestrator level)

---

## Triggers

- Orchestrator activates this agent after Phase 10 inner retry loops complete for a module AND at least one of: (a) persistent bugs remain (inner loop exhausted 3 retries), (b) cross-layer bugs detected (root cause in different layer than symptom), (c) cross-module bugs detected (shared service failures)
- In bugfix pipeline: activated after bug_diagnosis agent when fix_path is `direct_fix` — receives diagnosis.json as additional context
- In fix loop mode, re-activated after fixation-mode impl agents complete and tests re-run with remaining failures
- Skipped entirely if all tests pass after Phase 10 inner retries (no bugs to escalate)

---

## Checkpoints

| ID | Description | Action |
|---|---|---|
| `CP-001` | All test reports and bug files loaded for module | `log` |
| `CP-002` | Bug correlation complete — cross-layer root causes identified | `log` |
| `CP-003` | Cross-module bugs isolated and moved to separate output | `notify` — alerts orchestrator that cross-module fixes need coordination |
| `CP-004` | Fix directives ordered and validated against code_map | `log` |
| `CP-005` | Fix plan written and dispatched to Phase 10 agents in fixation mode | `log` |
| `CP-006` | Fix iteration 2 triggered — first round of fixes did not resolve all bugs | `notify` — user informed that fix loop is iterating |
| `CP-007` | Fix iteration 3 triggered — second round did not resolve all bugs | `notify` — user warned this is the last automated attempt |
| `CP-008` | Fix loop exhausted after 3 iterations — escalating to user | `pause` — pipeline pauses until user reviews remaining bugs |

---

## Validation Criteria

- Every bug_id from all input bugs.json files appears in at least one fix directive's bug_refs array (or in cross_module_bugs.json source_bug_refs)
- Every fix directive has at least one entry in bug_refs
- Every fix directive's files_to_modify entries reference paths that exist in code_map.json
- Fix directives are correctly ordered: all DB-layer directives precede BE-layer directives, which precede FE-layer directives
- No duplicate directive_ids within a fix plan
- fix_iteration is accurately tracked across loop cycles
- Cross-module bugs are not duplicated in per-module fix plans
- total_bugs equals the sum of bugs_by_layer values
- All story_refs from source bugs are preserved in fix directives
- Output JSON passes schema validation

---

## Context Sources

- test_output/{module_id}/db/report.json and bugs.json from Phase 10 DB Test agent
- test_output/{module_id}/be/report.json and bugs.json from Phase 10 BE Test agent
- test_output/{module_id}/fe/report.json and bugs.json from Phase 10 FE Test agent
- code_map.json from orchestrator (merged from all impl agents)
- module_flow.json from Phase 7 architecture agents (be_policy, fe_flow, db_interaction)
- Previous fix_plan iterations (if in fix loop iteration 2 or 3)

---

## Operation Mode

| Field | Value |
|---|---|
| Type | `autonomous` |
| Fallback | `none` — if fix planner fails, bugs remain unresolved and pipeline cannot proceed to optimization; user must intervene |

---

## 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` | Bug correlator tool that traces bugs across DB/BE/FE layers using flow data and error message analysis to find shared root causes | this agent | Agent must manually correlate bugs across layers; risk of treating 3 symptoms as 3 separate bugs when they share one root cause |
| `TG-006` | Root cause analyzer that combines error messages, stack traces, file paths, and flow data to determine which layer is the actual source of failure | this agent | Agent relies on LLM pattern matching alone; may misidentify root cause layer (e.g., marking a FE bug as FE-caused when the real issue is in DB) |
| `TG-007` | Fix prioritizer that computes correct ordering based on layer hierarchy and intra-layer dependencies | this agent | Agent must manually order fixes; incorrect ordering wastes fix loop iterations |

---

## Generation Readiness

| `generate_agent` Param | Status | Notes |
|---|---|---|
| `fileName` | ready | `fix-planner` |
| `agentName` | ready | `fix_planner` |
| `agentRole` | ready | "Cross-Layer Fix Planner — Root Cause Bug Triage and Fix Directive Generation" |
| `agentDescription` | ready | Full description available from Goal section |
| `operationMode` | ready | `autonomous`, no fallback |
| `goal` | ready | 3 objectives defined with priorities |
| `inputs` | ready | 8 inputs: 6 test outputs (report + bugs per layer), code_map.json, module_flow.json |
| `guardrails` | ready | 16 rules covering constraints, data_handling, output_quality, scope_boundary, interaction, universal tools, and completion signal |
| `scopeBoundary` | ready | 7 in-scope items, 6 out-of-scope items |
| `outputFormat` | ready | JSON output with full schemas for fix_plan_{module_id}.json and cross_module_bugs.json |
| `triggers` | ready | 3 triggers defined |
| `checkpoints` | ready | 8 checkpoints with actions covering normal flow and fix loop escalation |
| `validation` | ready | 10 validation criteria |
| `contextSources` | ready | 6 context sources |
| `metadata` | ready | phase: "11", mode: "all", granularity: "per_module" |
