190 lines
11 KiB
Markdown
190 lines
11 KiB
Markdown
# Fix-Plan — Verifikations-Findings (Stand 2026-07-24)
|
||
|
||
Einstiegspunkt für eine **frische Fix-Session**. Sammelt die in der manuellen Verifikation
|
||
(§7–§9 + Kanten §1/§3/§4) gefundenen Probleme, gruppiert nach **Fixbarkeit**. Volltext je
|
||
Finding (mit Kontext/Wiederholschritten) steht in `docs/open.md`; hier steht der Fix-Blick:
|
||
Root-Cause, konkreter Ansatz, Loc/Test-Hinweise, und **welche Punkte vor der Umsetzung eine
|
||
Entscheidung brauchen**.
|
||
|
||
**Immer zuerst:** file:line-Angaben gegen den aktuellen Code prüfen (können minimal driften).
|
||
Build/Test-Regeln + Gotchas s. Projekt-`CLAUDE.md` (u.a. `.slnx` braucht .NET 9 → einzelne
|
||
`.csproj -c Release`; Localization.Tests erzwingt en/de-Parität; Subagents `sonnet`, Dateien
|
||
pfad-scoped stagen). Pro Fix ein Conventional Commit.
|
||
|
||
---
|
||
|
||
## Bearbeitungsstand (Session 2026-07-24, nicht gepusht)
|
||
|
||
**Erledigt & committed:**
|
||
- Gruppe A #1–5 + beide Optional-Nits (Icon.Plus gefüllt, Gear-PathIcon, Skills-Empty-State,
|
||
„Subtasks"-Terminologie, Conflict-Continue-Hinweis, Rename-Darstellung, Turns/Tokens-Reload).
|
||
- Gruppe B #7 (Resume-Fehler surfacen) + #8 (Attachment-Drop-Diagnose).
|
||
- Gruppe C #9 (AskUser-Banner in Detail-Insel via geteiltem `TaskMonitorViewModel`),
|
||
#11 (OUTCOME zeigt `summary` statt rohem JSON: Worker-Unwrap + UI-Sicherheitsnetz).
|
||
- Gruppe D #13 (Kind-Rows live-refresh bei Parent-Planning-Transitionen) + #14 (Idle-Chip auf
|
||
Planning-Parents ausgeblendet). *Visual-Verification für #13 (Finalize/Discard live) offen.*
|
||
|
||
**#6** war im aktuellen Code bereits abgedeckt (Worker wirft `HubException` bei `blocked`
|
||
→ UI-Dialog); zusätzlich als ClaudeDo-Task `f9809a93` erfasst. Nicht angefasst.
|
||
|
||
**Offen:**
|
||
- **#10 + #12** — bewusst gebündelt mit dem ConPTY-Planning-Task `5d627df8` (dort lässt sich
|
||
die Session-Id sauber greifen bzw. das MCP-Permission-Verhalten klären). Sofort-Schutz für
|
||
#10 (Resume ausgrauen wenn keine Id) wurde NICHT gebaut — bräuchte Worker-Plumbing, das der
|
||
ConPTY-Umbau ohnehin liefert; der #7-Fix verhindert bereits das stille Scheitern.
|
||
- **Gruppe E** — nur noch design-/feature-behaftete Punkte. Der scheinbare Quick-Win
|
||
„Dequeue-X auf blockierten Kettengliedern" wurde bewusst NICHT umgesetzt: einzelnes Dequeue
|
||
eines Kettenglieds hinterlässt hängende Nachfolger (deren `BlockedByTaskId` zeigt weiter auf
|
||
das nun idle Glied) → braucht Chain-Repair-Design.
|
||
|
||
---
|
||
|
||
## Gruppe A — Mechanisch, sofort fixbar (keine Entscheidung nötig)
|
||
|
||
Ideale Kandidaten für den Start / parallele Subagents (disjunkte Dateien).
|
||
|
||
1. **„New session"-Button unsichtbar (Icon.Plus strich-only)**
|
||
`IslandStyles.axaml` (`Icon.Plus` = `M12 5v14M5 12h14`, reine Linie) wird in einem
|
||
`<PathIcon>` (MissionControlView.axaml, füllt Geometrie) unsichtbar gerendert.
|
||
**Fix:** `Icon.Plus` als gefüllte Geometrie authoren ODER als gestricheltes `Path`
|
||
rendern (vgl. `Path.plan-icon`). **Andere `Icon.Plus`-Verwendungen mitprüfen.**
|
||
|
||
2. **Agent-Settings-Gear weicht vom Listen-Gear ab**
|
||
`TaskHeaderBar.axaml:68` rendert `<TextBlock Text="⚙">`; überall sonst `Icon.Settings`
|
||
(PathIcon, IslandStyles.axaml:110). **Fix:** den `⚙`-TextBlock durch
|
||
`<PathIcon Data="{StaticResource Icon.Settings}" Width=".." Height=".."/>` ersetzen.
|
||
|
||
3. **Session-Skills-Tab ohne Empty-State**
|
||
Bei 0 Skills nur nackte Fläche. **Fix:** Empty-State-Text unter der Install-Zeile
|
||
(z.B. „No skills installed — paste a GitHub URL above"). **Loc:** neue Keys in en.json
|
||
**und** de.json (Parität!). Datei: `SessionSkillsSettingsTab*`.
|
||
|
||
4. **„Waiting for Improvements" für Planning-Parents (Terminologie)**
|
||
`en.json` `taskStatus.waitingForChildren`/`agentStatus.children`/`childOutcomesLabel`
|
||
sagen „Improvements". Seit unified-parent gilt `WaitingForChildren` auch für Planning.
|
||
**Fix:** auf neutrales „Waiting for Subtasks"/„Subtasks"/„SUBTASKS" umstellen — en **und**
|
||
de (Parität).
|
||
|
||
5. **Conflict-Resolver: Continue-Button klickbar trotz offener Konflikte**
|
||
Merge passiert korrekt erst nach Auflösung, aber der Button ist nicht disabled → früher
|
||
Klick = stummer No-op. **Fix:** `CanContinue`/`AllResolved` an `IsEnabled` binden (ggf.
|
||
Hinweis „N Konflikte in M Dateien offen"). Datei: `ConflictResolverView(.axaml)` +
|
||
`ConflictResolverViewModel`.
|
||
|
||
Optional-Nits (gleiche Gruppe, niedrige Prio):
|
||
- **Diff-Viewer Rename schwach dargestellt** (alt→neu-Pfad + „renamed"-Label statt „+0 −0").
|
||
- **Header-TurnsText `0/max`** bei terminalem Reload — `Turns` aus `task_runs.turnCount`
|
||
restaurieren.
|
||
|
||
---
|
||
|
||
## Gruppe B — Error-Surfacing (klare Richtung: kein stiller/leerer Fehlerpfad)
|
||
|
||
Leitlinie `feedback_ui_error_surfacing`: User-Action-Fehler in den Footer
|
||
(`FlashFooterError`) bzw. Dialog, nie leerer `catch`/stiller No-op.
|
||
|
||
6. **Approve & Merge schluckt „blocked" still**
|
||
`DetailsIslandViewModel.ApproveReviewAsync` reagiert nur auf `Status == "conflict"`; bei
|
||
`"blocked"` (z.B. dirty Ziel-Tree) passiert nichts. **Fix:** bei `blocked`/unerwartetem
|
||
Status `result.ErrorMessage` surfacen. *(Als ClaudeDo-Task `f9809a93` erfasst — koppelt
|
||
„Approve erzwingt Diff/Review vor Merge".)*
|
||
|
||
7. **„Resume planning session" verschluckt den Fehler (Teil-Fix hier, Rest → Gruppe C #10)**
|
||
`TasksIslandViewModel.ResumePlanningSessionAsync` (~Zeile 870) hüllt alles in `catch { }`.
|
||
**Sofort-Fix:** den Fehler surfacen statt schlucken. Der eigentliche Resume-Defekt braucht
|
||
eine Entscheidung → #10.
|
||
|
||
8. **Attachments: intermittenter erster-Drop-Fehler („An error occurred")**
|
||
Einmalig beobachtet (erster Drop der Session, nichts persistiert), nicht reproduzierbar.
|
||
**Fix (diagnostisch):** `AddFilesAsync`/`OnDrop` robustes Error-Logging geben (die genaue
|
||
Exception fehlt, weil `DropStatus` nur `{fileName}: {ex.Message}` zeigt) — damit der
|
||
nächste Fall auswertbar ist. Kandidaten-Ursachen: SQLite-Contention (UI schreibt `todo.db`
|
||
direkt, während der Worker sie hält) oder Drop-Stream-Pfad (`IStorageFile.OpenReadAsync`
|
||
im Code-Behind, außerhalb des `try`).
|
||
|
||
---
|
||
|
||
## Gruppe C — Erst Entscheidung/Brainstorm, DANN umsetzen (nicht blind fixen)
|
||
|
||
9. **AskUser-Interaktion auch in der Detail-Insel** *(von Mika ausdrücklich gewünscht)*
|
||
Der `ask_user`-Banner + Inline-Antwort existiert nur in Mission Control
|
||
(`MonitorPaneView`); die Detail-Insel zeigt für den laufenden Task nichts.
|
||
**Entscheidung:** wie den Zustand teilen — `TaskMonitorViewModel` hält ihn bereits; für
|
||
die Detail-Insel replizieren, teilen, oder ein gemeinsames Banner-Control? Danach:
|
||
Banner + `AnswerDraft`/`SubmitAnswer` in `DetailsIslandView(Model)` einhängen.
|
||
|
||
10. **„Resume planning session" grundsätzlich kaputt (Session-Id nie erfasst)**
|
||
`PlanningSessionManager.ResumeAsync:238` wirft immer „No Claude session ID captured yet",
|
||
weil `TaskRepository.UpdatePlanningSessionIdAsync:322` **keinen Aufrufer** hat →
|
||
`planning_session_id` bleibt NULL. **Entscheidung:** (a) claude-Session-Id der
|
||
wt-Planning-Session erfassen + via `UpdatePlanningSessionIdAsync` persistieren (echtes
|
||
Resume) ODER (b) Resume entfernen/deaktivieren, wenn keine Id vorliegt. Hängt mit der
|
||
Design-Entscheidung „Planning über embedded ConPTY statt wt" zusammen (ClaudeDo-Task
|
||
`5d627df8`) — dort ließe sich die Session-Id sauber greifen.
|
||
|
||
11. **OUTCOME-Karte rendert rohes Structured-Output-JSON**
|
||
`TaskMonitorViewModel.ApplyOutcome` setzt bei Tasks ohne Roadblock `SessionOutcome`
|
||
= `task.Result` wörtlich; der Worker legt dort rohes `{"summary":…}` ab.
|
||
**Entscheidung:** (a) UI parst JSON-Result und zeigt `summary`, oder (b) Worker schreibt
|
||
`summary`/`resultMarkdown` statt JSON in `task.Result`.
|
||
|
||
12. **Planning-Session prompted nach MCP-Tool-Permission**
|
||
Trotz `--allowedTools "mcp__claudedo__*,…"` + `--permission-mode plan` prompted die
|
||
wt-Planning-Session beim ersten `create_child_task`. **Untersuchen/Entscheiden:** matcht
|
||
der `mcp__claudedo__*`-Glob in CLI 2.1.207 nicht (Syntax evtl. ganzer Server-Name), oder
|
||
gated Plan-Mode MCP-Writes generell? Gekoppelt an ConPTY-Planning-Task `5d627df8`.
|
||
|
||
---
|
||
|
||
## Gruppe D — Erst Root-Cause pinnen (Investigation)
|
||
|
||
13. **Kind-Rows aktualisieren nach Parent-Planning-Transitionen nicht live**
|
||
Nach **Finalize** bleiben Kind-Badges „Draft" statt „Planned"; nach **Discard** bleiben
|
||
die (in der DB gelöschten) Kind-Rows sichtbar — bis Listen-Reload. Doppelt verifiziert §3.
|
||
**Untersuchen:** wie wird die Kinderliste/-gruppierung auf ein Parent-`TaskUpdated`
|
||
reagierend neu aufgelöst? Vermutlich fehlt ein Regroup/Refetch der Children beim
|
||
Parent-Broadcast (`TasksIslandViewModel` hierarchie-Regrouping). Fix danach: Children bei
|
||
Parent-Transition live neu auflösen.
|
||
|
||
14. **Planning-aktiver Parent zeigt weiter „Idle"**
|
||
Parent `planning_phase=active` hat `Status=Idle` (korrekt im Modell), aber der Row-Chip
|
||
zeigt „Idle"; `PlanningBadge` überschreibt das nicht sichtbar. **Untersuchen/Design:** ein
|
||
klarer „Planning/Draft aktiv"-Zustand, der den Idle-Chip überschreibt. (Verwandt mit #13 —
|
||
Row-Statusdarstellung.)
|
||
|
||
---
|
||
|
||
## Gruppe E — UX-Nits / Feature-Wünsche (niedrige Prio, sammeln)
|
||
|
||
- **Conflict-Resolver: mehrere Konfliktdateien schlecht erkennbar** — prominentere Datei-Liste
|
||
/ „x von y Dateien".
|
||
- **Blocked-by-Kette nicht visualisiert** — Reihenfolge/Abhängigkeit darstellen
|
||
(„wartet auf <Vorgänger>").
|
||
- **Dequeue-„X" fehlt auf blockierten Kettengliedern** — `CanRemoveFromQueue` erweitern
|
||
(`IsWaiting` einschließen).
|
||
- **„Open ConPTY session" erneut = Prompt wird neu gesendet** — Resume-Affordance / Re-Open-
|
||
Warnung (bewusst kein Session-Persist).
|
||
- **Conflict-Resolver: farbliches Hervorheben übernommener Zeilen im Result-Pane** (Feature).
|
||
|
||
---
|
||
|
||
## Nicht anfassen / Kontext
|
||
|
||
- **§1 DiffModal-Fehler-State** (`vm.diff.unavailable`) ist **defensiver, über die UI
|
||
unerreichbarer** Code — alle Aufrufer sind gegated (`CanDiffMergedRange` verlangt base+head
|
||
non-null; `ConfigureWorktree` nur mit existierendem Pfad). Kein Fix nötig.
|
||
- **`--permission-mode auto` + `haiku` denied Writes** — modellabhängiges Verhalten, keine
|
||
Regression; Default (sonnet) unbetroffen. Beobachten (Memory `auto_permission_haiku_footgun`).
|
||
- **§10 Daily Prep/Weekly** — Verifikation zurückgestellt bis zum geplanten Rework.
|
||
|
||
---
|
||
|
||
## Empfohlene Reihenfolge
|
||
|
||
1. **Gruppe A** (mechanisch, schnell, teils parallel) → sofort sichtbare Wins.
|
||
2. **Gruppe B** (Error-Surfacing, klein & risikoarm).
|
||
3. **Gruppe C** — pro Punkt kurz brainstormen/entscheiden, dann umsetzen (#10 + #12 zusammen
|
||
mit der ConPTY-Planning-Entscheidung betrachten).
|
||
4. **Gruppe D** — Investigation, dann Fix (#13 zuerst — betrifft mehrere Planning-Flows).
|
||
5. **Gruppe E** — nach Bedarf.
|