# Chain Workbench - Findings Integration (Vorschlag) > **Status:** Vorschlag für zukünftige Implementierung > **Stand:** 2025-01-XX > **Zielgruppe:** Entwickler --- ## Problemstellung Die Chain Workbench (0.5.x) verwendet aktuell **nur** Template Matches aus Chain Inspector (0.4.x), nicht aber die **Findings** und **Gap-Heuristiken**, die aufwendig getestet wurden. **Verlorene Informationen:** - `dangling_target` - Target-Datei existiert nicht - `dangling_target_heading` - Target-Heading existiert nicht - `only_candidates` - Nur Candidate-Edges, keine expliziten - `missing_edges` - Section hat Content aber keine Edges - `no_causal_roles` - Section hat Edges aber keine kausalen Rollen - `one_sided_connectivity` - Nur incoming oder nur outgoing edges --- ## Lösungsvorschlag ### 1. Findings zu Todos konvertieren Erweitere `todoGenerator.ts` um eine Funktion `generateFindingsTodos()`: ```typescript /** * Generate todos from Chain Inspector findings. */ export function generateFindingsTodos( findings: Finding[], allEdges: IndexedEdge[], context: { file: string; heading: string | null } ): WorkbenchTodoUnion[] { const todos: WorkbenchTodoUnion[] = []; for (const finding of findings) { switch (finding.code) { case "dangling_target": // Find edge with dangling target const danglingEdge = allEdges.find( (e) => e.target.file === finding.evidence?.file ); if (danglingEdge) { todos.push({ type: "dangling_target", id: `dangling_target_${finding.evidence?.file}`, description: finding.message, priority: finding.severity === "error" ? "high" : "medium", targetFile: danglingEdge.target.file, targetHeading: danglingEdge.target.heading, sourceEdge: { file: "sectionHeading" in danglingEdge.source ? danglingEdge.source.file : danglingEdge.source.file, heading: "sectionHeading" in danglingEdge.source ? danglingEdge.source.sectionHeading : null, }, actions: ["create_missing_note", "retarget_link"], }); } break; case "dangling_target_heading": // Similar to dangling_target, but for headings todos.push({ type: "dangling_target_heading", id: `dangling_target_heading_${finding.evidence?.file}_${finding.evidence?.sectionHeading}`, description: finding.message, priority: finding.severity === "warn" ? "medium" : "low", targetFile: finding.evidence?.file || "", targetHeading: finding.evidence?.sectionHeading || null, actions: ["create_missing_heading", "retarget_to_existing_heading"], }); break; case "only_candidates": // Find all candidate edges in section const candidateEdges = allEdges.filter( (e) => e.scope === "candidate" && ("sectionHeading" in e.source ? e.source.sectionHeading === context.heading : false) ); if (candidateEdges.length > 0) { todos.push({ type: "only_candidates", id: `only_candidates_${context.file}_${context.heading}`, description: finding.message, priority: "medium", candidateEdges: candidateEdges.map((e) => ({ rawEdgeType: e.rawEdgeType, from: "sectionHeading" in e.source ? { file: e.source.file, heading: e.source.sectionHeading } : { file: e.source.file, heading: null }, to: e.target, })), actions: ["promote_all_candidates", "create_explicit_edges"], }); } break; case "missing_edges": todos.push({ type: "missing_edges", id: `missing_edges_${context.file}_${context.heading}`, description: finding.message, priority: "medium", section: { file: context.file, heading: context.heading, }, actions: ["add_edges_to_section"], }); break; case "no_causal_roles": // Find edges without causal roles const nonCausalEdges = allEdges.filter( (e) => e.scope === "section" && ("sectionHeading" in e.source ? e.source.sectionHeading === context.heading : false) ); todos.push({ type: "no_causal_roles", id: `no_causal_roles_${context.file}_${context.heading}`, description: finding.message, priority: "medium", edges: nonCausalEdges.map((e) => ({ rawEdgeType: e.rawEdgeType, from: "sectionHeading" in e.source ? { file: e.source.file, heading: e.source.sectionHeading } : { file: e.source.file, heading: null }, to: e.target, currentRole: null, // Would need to resolve via chain_roles suggestedRoles: ["causal", "influences", "enables_constraints"], })), actions: ["change_edge_type"], }); break; case "one_sided_connectivity": // Informational only todos.push({ type: "one_sided_connectivity", id: `one_sided_connectivity_${context.file}_${context.heading}`, description: finding.message, priority: "low", section: { file: context.file, heading: context.heading, }, actions: [], // No actions, informational only }); break; } } return todos; } ``` ### 2. Erweitere Todo-Types Füge neue Todo-Types zu `types.ts` hinzu: ```typescript export type TodoType = | "missing_slot" | "missing_link" | "weak_roles" | "candidate_cleanup" | "create_candidates_zone" | "create_note_links_zone" | "dangling_target" // NEU | "dangling_target_heading" // NEU | "only_candidates" // NEU | "missing_edges" // NEU | "no_causal_roles" // NEU | "one_sided_connectivity"; // NEU export interface DanglingTargetTodo extends WorkbenchTodo { type: "dangling_target"; targetFile: string; targetHeading: string | null; sourceEdge: { file: string; heading: string | null; }; actions: Array<"create_missing_note" | "retarget_link">; } export interface DanglingTargetHeadingTodo extends WorkbenchTodo { type: "dangling_target_heading"; targetFile: string; targetHeading: string | null; actions: Array<"create_missing_heading" | "retarget_to_existing_heading">; } export interface OnlyCandidatesTodo extends WorkbenchTodo { type: "only_candidates"; candidateEdges: Array<{ rawEdgeType: string; from: { file: string; heading: string | null }; to: { file: string; heading: string | null }; }>; actions: Array<"promote_all_candidates" | "create_explicit_edges">; } export interface MissingEdgesTodo extends WorkbenchTodo { type: "missing_edges"; section: { file: string; heading: string | null; }; actions: Array<"add_edges_to_section">; } export interface NoCausalRolesTodo extends WorkbenchTodo { type: "no_causal_roles"; edges: Array<{ rawEdgeType: string; from: { file: string; heading: string | null }; to: { file: string; heading: string | null }; currentRole: string | null; suggestedRoles: string[]; }>; actions: Array<"change_edge_type">; } export interface OneSidedConnectivityTodo extends WorkbenchTodo { type: "one_sided_connectivity"; section: { file: string; heading: string | null; }; actions: []; // Informational only } ``` ### 3. Integriere Findings in Workbench Builder Erweitere `workbenchBuilder.ts`: ```typescript export async function buildWorkbenchModel( app: App, report: ChainInspectorReport, chainTemplates: ChainTemplatesConfig | null, chainRoles: ChainRolesConfig | null, edgeVocabulary: EdgeVocabulary | null, allEdges: IndexedEdge[] ): Promise { const matches: WorkbenchMatch[] = []; const globalTodos: WorkbenchTodoUnion[] = []; // NEU: Global todos from findings // ... existing template match processing ... // NEU: Generate todos from findings if (report.findings && report.findings.length > 0) { const findingsTodos = generateFindingsTodos( report.findings, allEdges, report.context ); globalTodos.push(...findingsTodos); } return { context: report.context, matches, globalTodos, // NEU: Add global todos timestamp: Date.now(), }; } ``` ### 4. Erweitere WorkbenchModel Interface ```typescript export interface WorkbenchModel { context: { file: string; heading: string | null; zoneKind: string; }; matches: WorkbenchMatch[]; globalTodos?: WorkbenchTodoUnion[]; // NEU: Todos from findings (not template-based) timestamp: number; } ``` ### 5. UI-Integration Erweitere `ChainWorkbenchModal.ts`: ```typescript // Show global todos (from findings) separately if (model.globalTodos && model.globalTodos.length > 0) { // Render "Section-Level Issues" section // Show findings-based todos before template matches } ``` --- ## Vorteile 1. **Nutzt getestete Heuristiken** - Findings aus 0.4.x werden verwendet 2. **Vollständigere Analyse** - Nicht nur Template-basiert, sondern auch Section-Level 3. **Konsistenz** - Chain Inspector und Workbench zeigen dieselben Probleme 4. **Bessere UX** - User sieht alle Probleme auf einen Blick --- ## Implementierungsreihenfolge 1. **Phase 1:** Todo-Types erweitern (`types.ts`) 2. **Phase 2:** `generateFindingsTodos()` implementieren (`todoGenerator.ts`) 3. **Phase 3:** `buildWorkbenchModel()` erweitern (`workbenchBuilder.ts`) 4. **Phase 4:** UI erweitern (`ChainWorkbenchModal.ts`) 5. **Phase 5:** Actions implementieren (z.B. `create_missing_note`, `retarget_link`) --- ## Offene Fragen 1. **Priorität:** Sollen Findings-Todos höhere Priorität haben als Template-Todos? 2. **Duplikate:** Wie vermeiden wir Duplikate zwischen Findings-Todos und Template-Todos? - Beispiel: `dangling_target` könnte auch als `missing_link` Todo erscheinen 3. **Filterung:** Sollen Findings-Todos gefiltert werden können (z.B. nur Errors)? 4. **Actions:** Welche Actions sind für welche Findings sinnvoll? --- **Letzte Aktualisierung:** 2025-01-XX **Status:** Vorschlag für zukünftige Implementierung