6.3 KiB
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
- Maximize what the user can see — load valid nodes/edges even if some are broken
- Clearly communicate generation issues — amber warnings (not red errors) with copy-paste-friendly messages
- 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
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 === truewithresult.issues.length > 0: showWarningBannerwith issues, load graph normally - On
result.fatal: show existing red banner with fatal message console.warnfor auto-corrected items,console.errorfor dropped items
Test Coverage
All in packages/core/src/__tests__/schema.test.ts:
- Tier 1:
nulloptional fields silently becomeundefined - Tier 2: Missing
complexity/tags/weight/direction/summaryget defaults; issues tracked - Tier 2: String
weightcoerced; complexity/direction aliases mapped - Tier 3: Dangling edge references dropped; nodes missing
iddropped; 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
KnowledgeGraphobjects) - Existing node/edge type alias maps (preserved, extended around)