Files
ClaudeDo/docs/open.md
T

90 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ClaudeDo — Offene Punkte
Stand: 2026-07-24. Diese Datei listet die **aktiv verifizierten Findings** aus der Verifikations-Session vom 2026-07-24. Die laufende Verifikations-Checkliste (Pass/Fail je Abschnitt, inkl. noch offener Abschnitte §7–§11 und Kanten) lebt in `docs/verification-handoff.md`. Erledigtes steht in den Commits/im Code, nicht hier.
---
## Bugs (verifiziert 2026-07-24)
- **OUTCOME-Karte rendert rohes Structured-Output-JSON:** `TaskMonitorViewModel.ApplyOutcome` (ClaudeDo.Ui) setzt bei Tasks ohne Roadblock-Marker `SessionOutcome = result` wörtlich (Zeile ~261). Der Worker legt in `task.Result` das rohe `{"summary":…,"files_changed":[…]}` ab (die lesbare Fassung steht in `task_runs.resultMarkdown`), also zeigt die Detail-Insel OUTCOME als JSON-Blob statt als Text. Fix: (a) UI parst ein JSON-Result und zeigt `summary`, oder (b) Worker schreibt `summary`/`resultMarkdown` statt des JSON in `task.Result`. Verifiziert am Task `verif §1 diff matrix`. Deckt sich mit Memory `worker_testing_findings`.
- **Approve & Merge schluckt einen „blocked"-Merge still:** `DetailsIslandViewModel.ApproveReviewAsync` reagiert nur auf `result.Status == "conflict"` (öffnet den Resolver); bei `"blocked"` (z.B. Ziel-Working-Tree hat uncommittete getrackte Änderungen) und anderen Nicht-`merged`/Nicht-`conflict`-Status passiert **nichts** — kein Footer-Fehler, kein Dialog (der `catch` greift nur bei Exceptions, „blocked" ist aber ein normaler Rückgabewert mit `ErrorMessage`). User sieht „Klick tut nichts". Doppelt verifiziert (Konflikt-Approve UND sauberer additiver Approve `verif §1b`, beide bei dirty `main`-Checkout still). Fix: bei `blocked`/unerwartetem Status `result.ErrorMessage` via `ShowErrorAsync`/`FlashFooterError` surfacen. Verstößt gegen `feedback_ui_error_surfacing`. (Der Konflikt-Resolver + 3-Pane-Editor funktionieren, sobald der Ziel-Tree sauber ist.)
- **„Waiting for Improvements" für Planning-Parents (Terminologie):** `taskStatus.waitingForChildren` = „Waiting for Improvements" (en.json:504), `agentStatus.children` dito (503), `childOutcomesLabel` = „IMPROVEMENTS" (191). Seit dem unified-parent-Modell gilt `WaitingForChildren` für Planning **und** Improvement-Parents — „Improvements" ist für einen Planning-Parent falsch. Auf neutrales „Waiting for Subtasks"/„Subtasks" umstellen (en **und** de — Localization.Tests-Parität). Verifiziert §3.
- **Kind-Rows aktualisieren nach Parent-Planning-Transitionen nicht live:** Parent-getriebene Änderungen propagieren nicht auf die Kind-`TaskRowViewModel`s ohne Listen-Reload. (a) Nach „Finalize planning" bleiben Kind-Rows auf „Draft" (`IsDraft`) statt „Planned" (`IsPlanned`) — der geänderte `ParentFinalized` kommt nicht über das Parent-`TaskUpdated`-Broadcast an. (b) Nach „Discard" bleiben die (in der DB gelöschten) Draft-Kind-Rows sichtbar, bis die Liste neu geladen wird. Gemeinsame Ursache: die Kinderliste/-zustände werden bei Parent-Transitionen nicht live neu aufgelöst. Doppelt verifiziert §3 (Finalize **und** Discard, 2026-07-24).
- **AskUser-Frage erscheint NUR in Mission Control, nicht in der Task-Detail-Insel:** Der `ask_user`-Banner (Frage + Antwort-Eingabe) lebt ausschließlich in `MonitorPaneView` (Mission Control). Die Detail-Insel (`DetailsIslandView`) streamt zwar den Live-Log eines laufenden Tasks, zeigt aber **kein** Frage-Banner — ein Nutzer, der nur die Detailansicht offen hat, sieht nicht, dass der Run auf eine Antwort wartet, und läuft nach 3 min in den Timeout-Fallback. Verifiziert §7 (User schaute Detailansicht, Frage war unsichtbar; erst in Mission Control sichtbar). Fix: Frage-Banner + Inline-Antwort auch in der Detail-Insel für den gebundenen laufenden Task surfacen (VM-Zustand liegt bereits in `TaskMonitorViewModel`, müsste für die Detail-Insel repliziert/geteilt werden). **Von Mika bei der §7-Verifikation ausdrücklich gewünscht** („vermisse diese Interaktion in der Detail-Ansicht"). §7.
- **„New session"-Button (Mission Control) unsichtbar — Icon.Plus ist Strich-Only:** `Icon.Plus` = `M12 5v14M5 12h14` (IslandStyles.axaml:61) ist reine Linien-Geometrie ohne Fläche; im `<PathIcon>` (MissionControlView.axaml:38, füllt Geometrie) rendert sie **unsichtbar** → der Ad-hoc-„New session"-Button erscheint leer und ist nicht auffindbar (Feature + VM `OpenAdHocConPtySessionAsync` + Tests funktionieren, nur das Icon fehlt sichtbar). Fix: Icon.Plus als gefüllte Geometrie authoren ODER als gestricheltes `Path` rendern (Icon-Gotcha in CLAUDE.md). **Andere `Icon.Plus`-Verwendungen mitprüfen.** Verifiziert §5.
## UX / Nits (verifiziert 2026-07-24)
- **„Resume planning session" ist grundsätzlich kaputt (Session-Id wird nie erfasst) + Fehler wird verschluckt:** Im UnfinishedPlanning-Modal macht **Resume** nichts. Ursache: `PlanningSessionManager.ResumeAsync` (PlanningSessionManager.cs:238) bricht mit `InvalidOperationException("No Claude session ID captured yet; cannot resume.")` ab, wenn `task.PlanningSessionId` leer ist — und der Setter `TaskRepository.UpdatePlanningSessionIdAsync` (TaskRepository.cs:322) hat **keinen einzigen Aufrufer** im Worker, d.h. `planning_session_id` wird nie befüllt (verifiziert an `verif §3 resume-discard`: `planning_session_id=NULL`, Token gesetzt, Drafts angelegt). Resume kann also **nie** erfolgreich sein. Zusätzlich verschluckt `TasksIslandViewModel.ResumePlanningSessionAsync` den ganzen Block in einem leeren `catch { }` (~Zeile 870) → der Button ist ein **stummer No-op**, kein Footer-Fehler, kein Dialog (verstößt gegen `feedback_ui_error_surfacing`). Hintergrund: die wt-Planning-Session ist interaktiv; ClaudeDo erfasst die claude-Session-Id dort nicht (analog zur bewusst nicht persistierten ConPTY-Session-Id, §5). Fix-Optionen: (a) beim Planning-Start/-Lauf die claude-Session-Id erfassen und via `UpdatePlanningSessionIdAsync` persistieren, damit Resume echt resumen kann; ODER (b) Resume entfernen/deaktivieren, wenn keine Session-Id vorliegt; in JEDEM Fall den Fehler statt des leeren `catch` surfacen. Verifiziert §3. §3.
- **Attachments: erster Drag&Drop der Session schlug einmalig fehl („An error occurred"):** Beim allerersten Drop-to-attach einer UI-Session zeigte die `DropStatus`-Zeile inline einen generischen Fehler und es wurde nichts persistiert (kein File, keine DB-Row); alle folgenden Drops derselben Session + der „Add file…"-Picker + Remove funktionierten fehlerfrei. Nicht reproduzierbar nach dem ersten Mal (App-Neustart nötig, um die „erster-Drop"-Bedingung wiederherzustellen). Kandidaten: transiente SQLite-Contention (der UI-Prozess schreibt `todo.db` direkt via `new TaskAttachmentRepository`, während der Worker dieselbe DB hält) ODER ein Fehler im Drop-Stream-Pfad (`IStorageFile.OpenReadAsync` im Code-Behind, außerhalb des `try` in `AddFilesAsync`). Falls es erneut auftritt: `AddFilesAsync`/`OnDrop` mit robusterem Error-Logging versehen (die genaue Exception-Message fehlt, weil `DropStatus` nur `{fileName}: {ex.Message}` zeigt). Verifiziert §9 (einmalig beobachtet). §9.
- **Agent-Settings-Gear weicht vom übrigen Settings-Icon ab:** Der Agent-Settings-Flyout-Button (`TaskHeaderBar.axaml:68`) rendert ein Unicode-Glyph `⚙` (`<TextBlock Text="⚙">`), während die Listen-Nav (`ListsIslandView.axaml:56`) und die Listen-Settings (`TasksIslandView.axaml:47`) das gefüllte `Icon.Settings`-PathIcon (Gear-StreamGeometry, IslandStyles.axaml:110) nutzen → optisch ein anderes Zahnrad. Angleichen: den `⚙`-TextBlock durch `<PathIcon Data="{StaticResource Icon.Settings}" .../>` ersetzen. Verifiziert §8 (User-Sichtprüfung). §8.
- **Session-Skills-Tab hat keinen Empty-State:** Bei 0 installierten Skills zeigt der Skills-Tab (Settings) nur eine nackte leere Fläche unter der Install-Zeile — kein erklärender Hinweis (z.B. „Noch keine Skills installiert — GitHub-URL oben einfügen"). Verifiziert §8 (frischer Zustand vor ponytail-Install). Kleiner Empty-State-Text ergänzen.
- **Diff-Viewer: reiner Rename schwach dargestellt:** Rename korrekt erkannt (`UnifiedDiffParser``DiffFileStatus.Renamed`, Badge `StatusCode="R"`), aber der File-Tree zeigt nur den neuen Namen + „+0 0" ohne „alt → neu"-Pfad; liest sich wie „keine Änderung". Optional: alten Pfad + „renamed"-Label anzeigen. §1.
- **Header-TurnsText zeigt `0/max` für abgeschlossene Runs:** `TurnsText => {Turns}/{EffectiveMaxTurns}``Turns` wird beim Laden eines terminalen Tasks nicht aus `task_runs.turnCount` restauriert (nur live gefüllt). Kosmetisch. §1.
- **Conflict-Resolver: Continue/Merge-Button klickbar trotz offener Konflikte:** Gate greift funktional (merged erst wenn alle Konflikte in allen Dateien gelöst), aber der Button ist nicht disabled/gegraut → früher Klick ist ein stummer No-op. Besser: disabled bis `AllResolved`, oder Hinweis „N Konflikte in M Dateien offen". §4.
- **Conflict-Resolver: mehrere Konfliktdateien schlecht erkennbar:** Beim 2-Datei-Konflikt schwer zu sehen, dass zwei Dateien betroffen sind (File-Switcher/Anzahl zu unauffällig). Prominentere Datei-Liste / „x von y Dateien". §4.
- **Planning-aktiver Parent zeigt weiter „Idle":** Parent in `planning_phase=active` hat `Status=Idle` (korrekt im Modell), aber der Row-Status-Chip zeigt „Idle"; der `PlanningBadge` ersetzt das nicht sichtbar → liest sich wie ein normaler Idle-Task. Wunsch: klarer „Planning/Draft aktiv"-Zustand, der Idle überschreibt. (Kinder zeigen korrekt „Draft".) §3.
- **Blocked-by-Kette nicht sichtbar:** Nach Finalize ist die sequentielle Kette korrekt gesetzt (child[i] blocked-by child[i-1]), aber die UI stellt die Reihenfolge/Abhängigkeit nicht dar. Wunsch: Kette visualisieren (z.B. „wartet auf <Vorgänger>"), nicht nur der „waiting"-Chip nach dem Queueen. §3.
- **Dequeue-„X" fehlt auf wartenden (blockierten) Kettengliedern:** `CanRemoveFromQueue = IsQueued || HasQueuedSubtasks`, `IsQueued` verlangt leeres `blocked_by`. Ein gequeuetes, aber blockiertes Kind (`IsWaiting`) bekommt daher kein Remove-from-queue-X — nur Parent + erstes (entsperrtes) Kind. §3.
- **„Open ConPTY session" erneut = Prompt wird neu gesendet, kein Resume:** Da die ConPTY-Session-Id bewusst nicht persistiert wird, startet ein erneutes „Open ConPTY session" auf demselben Task eine frische Session und sendet den Task-Prompt erneut (re-runt die Arbeit im selben Worktree) statt zu resumen. So designt, aber UX-Falle — evtl. „Resume"-Affordance oder Re-Open-Warnung. §5.
## Feature-Wünsche (aus der Session)
- **Conflict-Resolver: farbliches Hervorheben eingefügter Zeilen im Result-Pane** (grüner „flow" der übernommenen Zeilen). §4.
- Als ClaudeDo-Tasks in Liste „Claude do" erfasst: **Approve erzwingt Diff/Review vor Merge** (koppelt den blocked-Merge-Silent-Fail-Fix) und **interaktive Planning-Session über embedded ConPTY statt externem wt-Fenster** (koppelt den Planning-Permission-Prompt).
## Sichtprüfung offen (2026-07-27, Batch „Claude do"-Liste)
Alles gebaut + unit-getestet, aber **nicht visuell verifiziert** — Mika prüft:
- **Ctrl+K fokussiert die Suche, `#` ist wieder tippbar** (Binding war `OemQuestion` = `#` auf DE-Layout).
- **Titel-Edit in der Detail-Insel persistiert** (400 ms debounced, wie die Beschreibung); Row-Titel + Merge-Kontext ziehen mit.
- **Spinner beim ConPTY-Start:** Tile erscheint sofort mit „Sitzung wird gestartet…" und deckt Launch-Spec-Roundtrip + Spawn ab. **Nicht** abgedeckt: die Sekunden, die die claude-TUI danach zum ersten Frame braucht (dafür bräuchte es einen Hook auf `TerminalControl.DataReceived`). Bei Launch-Fehler bleibt das Tile jetzt mit Inline-Banner stehen statt zu verschwinden.
- **Spinner beim Refine** ersetzt den Refine-Button in der Row, solange der Run läuft.
- **Interactive-Chip** statt „Parked" auf Tasks mit offener ConPTY-Session; Klick öffnet Mission Control und fokussiert die Pane. Accent-Tint (bewusst dieselbe „live"-Familie wie Running, klar unterschieden vom slate-blauen Parked).
- **Diff-Viewer:** rechter Abstand der `+n n`-Zahlen im File-Tree.
- **Manual-Tasks:** MANUAL-Badge, Kontextmenü-Toggle, Listen-Checkbox „Manuelle Liste"; Queue/Refine/Planning ausgeblendet, ConPTY bleibt.
- **Settings → Allgemein:** Tabelle „Vorgaben pro Modell" (Effort + Max. Durchläufe je haiku/sonnet/opus/fable). Ersetzt das einzelne globale „Max. Durchläufe"-Feld.
Offene Entscheidungen dazu:
- Interaktive ConPTY-Sessions bekommen `--effort`, aber **kein** `--model` — die Session läuft weiter unter dem Modell aus Mikas Claude-Config, der Effort kommt aus dem Preset des Modells, das ClaudeDo für die Task auflösen würde. Falls ClaudeDo auch interaktiv das Modell erzwingen soll, ist das ein Folge-Task.
- `AppSettings.DefaultMaxTurns` ist jetzt tatsächlich verdrahtet (`ModelPresets.For(..., global.DefaultMaxTurns)` in `TaskRunner.ResolveConfigAsync`): reiner Fallback für ein Modell, das auch nach `ModelRegistry.TryNormalizeAlias` auf keine Preset-Zeile trifft — vorher war das Feld tot (hartkodierte 30). Hat weiterhin keinen eigenen Editor mehr (nur die Preset-Tabelle pro Modell); Spalte könnte später entfallen, falls das nie zutrifft.
## Beobachtung (offen — Entscheidung Mika)
- **`--permission-mode auto` + Modell `haiku` → Writes werden denied:** Kontrolliert verifiziert (CLI 2.1.207): unter dem Default-Mode `auto` bekommt **sonnet** Writes auto-approved (`permission_denials:[]`), **haiku** wird `denied` (`permission_denials:[Write]`, keine Datei) — eine haiku-Task macht unter `auto` still nichts und landet ohne Änderung in `WaitingForReview`. Normalbetrieb (Default = sonnet) nicht betroffen. KEINE CLI-Regression, sondern modellabhängiges `auto`-Verhalten. Optionen falls es nervt: haiku aus der Auswahl nehmen, ODER Runner auf `acceptEdits`/`bypassPermissions` (modell-unabhängig). Mika: erstmal beobachten. Siehe Memory `auto_permission_haiku_footgun`.
---
## Offene Verifikation (2026-07-27)
- **List handler (2026-07-27)** — visual pass: the Broom button is gone from the lists footer,
the context-menu item appears only on lists with a working dir, and the selection dialog has no
LIST column. Plus a real-Claude smoke run of the five phases (dedupe questions, enhancements
landing in task descriptions, queued execution, merges).
## Offene Verifikation (2026-08-05)
- **List handler owns a task (2026-08-05)** — build + unit tests all green, but **not visually
verified**: start "Let Claude handle it" on a list, confirm exactly one new task appears in that
list (`Idle`, MANUAL badge, title "List handler: <list>"), the Mission Control tile is
task-based (Submit for review button present), Submit for review flips it to
`WaitingForReview`, and the detail pane's diff/merge card shows the full range of everything the
run merged to main (via the new `HandlerBaseCommit`/`HandlerHeadCommit` fallback — no
`WorktreeEntity` is created for this task, so the diff comes from `list.WorkingDir` directly).
Approve should go straight to `Done` with no merge attempt. Design choice: the review range
lives as two new nullable columns directly on `TaskEntity` (not a phantom `WorktreeEntity` row),
specifically so `list_worktrees`/the Worktrees overview never see it.
---
## Bewusst verworfen (nicht erneut vorschlagen)
- **CI-Build/Test-Pipeline** — push-to-main + release-on-push deckt das ab; Tests laufen am Ende jeder Session.
- **Real-`claude`-Smoke-Test als xUnit-Test** — kein Claude in `dotnet test`; bleibt manueller Check. Tests nutzen `FakeClaudeProcess`.
- **`architecture.md` / ADRs** — die per-Projekt-`CLAUDE.md`-Dateien sind die lebende Doku.
- **Task-Mailbox-Integration** — geparkt; das generische `mcp__mailbox__*`-Plugin reicht (`mailbox-proposal.md`).
- **Tag-Negation, Tag-Multi-Select, Notes-`lists.kind`-Switch, Install-Service-Skript** — durch die aktuelle Architektur überholt.