# Design: Dashboard Robustness — Permissive Graph Loading ## Problem When the LLM agent produces a knowledge-graph.json that deviates from the strict Zod schema, the dashboard shows a blank screen with cryptic Zod error paths. Users don't know whether it's a system bug or an agent generation issue, and their only recourse is a full re-run of `/understand`. ## Goals 1. **Maximize what the user can see** — load valid nodes/edges even if some are broken 2. **Clearly communicate generation issues** — amber warnings (not red errors) with copy-paste-friendly messages 3. **Empower targeted fixes** — users can copy the issue report and ask their agent to fix specific problems instead of a full re-run ## Design ### Three-Layer Robustness Pipeline ``` Raw JSON → Sanitize (Tier 1) → Normalize + Auto-fix (Tier 2) → Validate per-item (Tier 3) → Fatal check (Tier 4) → Dashboard ``` ### Tier 1: Sanitize Silently Common LLM quirks that are pure noise — fix without reporting. | Issue | Fix | |-------|-----| | `null` on optional fields (`filePath`, `lineRange`, `description`, `languageNotes`) | Convert to `undefined` | | Mixed-case enum strings (`"Forward"`, `"SIMPLE"`) | Lowercase before matching | ### Tier 2: Auto-fix With Info Notice Recoverable issues — apply sensible defaults, track as `auto-corrected` issues. | Issue | Default | Notes | |-------|---------|-------| | Missing `complexity` | `"moderate"` | Most common LLM omission | | Missing `tags` | `[]` | Empty is valid | | Missing `weight` | `0.5` | Middle of 0–1 range | | `weight` as string | Coerce to number | e.g., `"0.8"` → `0.8` | | Missing `direction` | `"forward"` | Safe default | | Missing `summary` | Use node `name` | Better than empty | | `tour: null` / `layers: null` | `[]` | Null vs empty array | | Complexity aliases | `low/easy→simple`, `medium/intermediate→moderate`, `high/hard→complex` | | | Direction aliases | `to/outbound→forward`, `from/inbound→backward`, `both→bidirectional` | | | Existing node/edge type aliases | Already handled by `normalizeGraph` | No change needed | | Missing node `type` | `"file"` | Safe fallback | | Missing edge `type` | `"depends_on"` | Generic fallback | ### Tier 3: Drop With Warning Can't safely guess — remove the item, track as `dropped` issue. | Issue | Action | |-------|--------| | Edge references non-existent node ID | Drop edge | | Node missing `id` | Drop node | | Node missing `name` | Drop node | | Edge missing `source` or `target` | Drop edge | | Unrecognizable `type` value (not in canonical or alias list) | Drop item | | `weight` not coercible to number | Drop edge | ### Tier 4: Fatal Graph is unsalvageable — show red error banner. | Condition | Message | |-----------|---------| | 0 valid nodes after filtering | "No valid nodes found in knowledge graph" | | Missing `project` metadata entirely | "Missing project metadata" | | Input is not an object / not valid JSON | "Invalid input format" | ### Return Type ```typescript interface GraphIssue { level: 'auto-corrected' | 'dropped' | 'fatal'; category: string; // e.g., "missing-field", "invalid-reference", "type-coercion" message: string; // human-readable, copy-paste friendly path?: string; // e.g., "nodes[3].complexity" } interface ValidationResult { success: boolean; data?: KnowledgeGraph; issues: GraphIssue[]; fatal?: string; } ``` ### Dashboard UI: WarningBanner Component **New component** in `packages/dashboard/src/components/WarningBanner.tsx`. **Visual design:** - **Amber/gold theme** — `bg-amber-900/20`, `border-amber-700`, `text-amber-200` - Matches dashboard's gold accent aesthetic; signals "generation quality issue" not "system crash" - **Collapsed by default** — summary line: "Knowledge graph loaded with 5 auto-corrections and 2 dropped items" - **Expandable** — click to reveal categorized issue list - **Copy button** — one-click copies the full issue report as a pre-formatted message - **Actionable footer** — tells users to copy issues and ask their agent to fix them **Copy-paste output format:** ``` The following issues were found in your knowledge-graph.json. These are LLM generation errors — not a system bug. You can ask your agent to fix these specific issues in the knowledge-graph.json file: [Auto-corrected] nodes[3] ("AuthService"): missing "complexity" — defaulted to "moderate" [Auto-corrected] nodes[7] ("utils.ts"): missing "tags" — defaulted to [] [Auto-corrected] edges[12]: weight was string "0.8" — coerced to number [Dropped] edges[5]: target "file:src/nonexistent.ts" does not exist in nodes [Dropped] nodes[14]: missing required "id" field — cannot recover ``` **Fatal errors** stay red (`bg-red-900/30`) with message: "Knowledge graph is unsalvageable: [reason]. Please re-run `/understand` to generate a new one." **Existing red error banner** for network/JSON-parse errors stays as-is (those ARE system/infra issues). ### App.tsx Changes - On `result.success === true` with `result.issues.length > 0`: show `WarningBanner` with issues, load graph normally - On `result.fatal`: show existing red banner with fatal message - `console.warn` for auto-corrected items, `console.error` for dropped items ### Test Coverage All in `packages/core/src/__tests__/schema.test.ts`: - **Tier 1:** `null` optional fields silently become `undefined` - **Tier 2:** Missing `complexity`/`tags`/`weight`/`direction`/`summary` get defaults; issues tracked - **Tier 2:** String `weight` coerced; complexity/direction aliases mapped - **Tier 3:** Dangling edge references dropped; nodes missing `id` dropped; issues recorded - **Tier 4:** Empty graph after filtering → fatal; missing `project` → fatal - **Integration:** Graph with mixed good/bad nodes → loads with correct node count + correct issues list ### Files Changed | File | Change | |------|--------| | `packages/core/src/schema.ts` | Sanitize, expanded normalize, permissive validate, new types | | `packages/dashboard/src/components/WarningBanner.tsx` | New component | | `packages/dashboard/src/App.tsx` | Wire issues to WarningBanner | | `packages/core/src/__tests__/schema.test.ts` | Tests for all tiers | ### Files NOT Changed - Agent prompts (can be tightened later as a separate effort) - GraphView / store logic (they already handle valid `KnowledgeGraph` objects) - Existing node/edge type alias maps (preserved, extended around)