Files
ClaudeDo/docs/open.md
mika kuns 2dfa9956c5 revert: drop real-claude smoke test; track as manual verification
A test that spawns the actual claude binary shouldn't live in the suite —
dotnet test must never invoke Claude. §1.0 step 3 stays a manual check.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-04 11:39:20 +02:00

223 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-06-04. Neu generiert nach Code-Audit gegen den tatsächlichen Stand auf `main`.
Die vorherige Version war auf 2026-04-30 datiert und inzwischen deutlich veraltet: zahlreiche als „offen" geführte Punkte sind gebaut, mehrere große Features (Localization, Weekly-Report + Daily-Notes, Daily-Prep) fehlten komplett, und das inzwischen entfernte Tag-System wurde noch als lebendig behandelt. Diese Version trennt sauber: **was seit 2026-04-30 dazukam**, **was wirklich noch offen ist**, **was inzwischen erledigt wurde** und **was fallengelassen / obsolet ist**.
Legende: ✅ DONE — 🟡 PARTIAL — ⬜ OPEN — ⛔ DROPPED/OBSOLET
---
## 0. Was seit 2026-04-30 dazugekommen ist
Diese Features gab es im alten Dokument noch gar nicht. Sie sind **fertig im Code**, brauchen aber teils noch manuelle Verifikation (siehe §1).
| Feature | Anker | Status |
|---|---|---|
| **Localization / i18n** | Eigenes Projekt `ClaudeDo.Localization` (`Localizer`, `CultureResolver`, `LocaleStore`, nested-JSON Parser); `loc:Tr` Markup-Extension; `locales/en.json` + `locales/de.json`; Settings-Sprachwahl; Installer-Sprachwahl | ✅ Code, Localization.Tests erzwingt Key-Parität |
| **Weekly Report** | `Worker/.../WeekReportService`, `ClaudeHistoryReader` (distilliert Session-Logs), Day-Major-Prompt-Builder; `WeekReportRepository`; `WeeklyReportModalView(Model)` | ✅ Code, manuelle Verifikation siehe §1.4 |
| **Daily Notes** | `DailyNoteRepository`, `INotesApi`, `NotesEditorView(Model)` mit Tagesnavigation + Bullet-CRUD; Notes-Mode in der Details-Island; gepinnte Notes-Row in MyDay | ✅ Code |
| **Daily-Prep („Plan My Day")** | `Prime/PrimeRunner` ruft Daily-Prep über erlaubte MCP-Tools; `get_daily_prep_candidates` + `set_my_day` MCP-Tools mit Cap-Guard; `DailyPrepMaxTasks`-Setting; Live-Prep-Output-Mode in der Details-Island (`PrepStarted/PrepLine/PrepFinished`); persistierter Prep-Log; MyDay-Header-Iconreihe (Prepare, Clear-day, Prep-log) | ✅ Code, manuelle Verifikation siehe §1.5 |
| **Waiting-for-Review-State** | Eigene Status-Stufe zwischen Run-Erfolg und Done; Approve/Reject-Rerun/Reject-Park/Cancel | ✅ Code |
| **Per-User Worker-Autostart** | Startup-Ordner-Verknüpfung statt Scheduled Task / Windows-Service (siehe §4.1) | ✅ Code |
| **Worktree-Overview-Modal** | `2026-05-19-worktree-overview-modal-design` | ✅ Code |
| **External-MCP UI-Parität** | ExternalMcpService von 11 → 18 Tools (siehe §5.4) | ✅ Code |
Weitere Specs/Plans seit 2026-04-30 (für die Historie): `planning-draft-planned-gate`, `repo-import-list-helper`, `ui-normalization`, `worker-lifecycle`, `prime-recurring-weekdays`.
---
## 1. Verification (vor allem anderen)
Der Code ist da; was fehlt, ist die **manuelle Bestätigung mit explizit notiertem Pass-Kriterium**. Ohne falsifizierbare Observable produziert ein Manual-Run nur „sah ok aus".
### 1.0 Plan-Verification — Kernpipeline
**2026-06-04: Kernpipeline läuft.** Der User bestätigt, dass Tasks mit echtem `claude` gestartet werden und der Happy-Path (non-worktree) durchläuft — Live-Stream und Wake-up inklusive. Die granularen Observables unten wurden nicht formell protokolliert; offen bleiben die worktree-spezifischen Pfade (57).
| # | Item | Status | Pass-Kriterium |
|---|------|---|---|
| 3 | Smoke-Spawn (`claude -p` „ping") | ✅ | (in der Praxis bestätigt 2026-06-04; formale Observables nicht protokolliert) |
| 4 | E2E Happy Path (Non-Worktree) | ✅ | (in der Praxis bestätigt 2026-06-04) |
| 5 | Worktree Happy Path | ⬜ | Liste mit `working_dir` auf temp-Repo, Task mit Codeänderung → `worktrees.state='active'`, `head_commit IS NOT NULL`, `diff_stat` non-empty, Branch `claudedo/<id>` auf Disk |
| 6 | No-Changes-Run | ⬜ | Prompt der nichts ändert → `status='Done'`, `worktrees.head_commit IS NULL`, `diff_stat IS NULL` |
| 7 | Kein Git-Repo | ⬜ | `working_dir=C:\Temp``status='Failed'`, **keine** `worktrees`-Row, Git-Fehler im Log |
| 8 | Merge-UI | 🟡 | `MergeTask` + `MergeModalView` da; manueller Run offen → `worktrees.state='merged'`, Commit im Ziel-Repo, kein Branch in `git worktree list` |
| 9 | Override-Parallelität | 🟡 | `OverrideSlotService`-Tests grün; UI-E2E offen → `GetActive` ≥ 2 Einträge bei Run+RunNow |
| 10 | Schedule | 🟡 | `QueuePicker`-Tests grün; UI-E2E offen → `scheduled_for=now+2min` bleibt Queued, dann automatisch Running |
| 11 | Worker-Offline-Erkennung | 🟡 | Auto-Reconnect implementiert; visuell prüfen: nach `taskkill` Statusbar in ≤ 5s „Offline", RunNow disabled |
| 12 | Live-Stream | 🟡 | `ClaudeProcess` streamt NDJSON via `TaskMessage`; visuell: ndjson-Zeilen laufen während Run ein |
| 13 | Wake-up (`WakeQueue`) | 🟡 | `QueueWaker.Wake()` bei Enqueue; visuell: Task in ≤ 1s auf Running statt nach Backstop-Intervall |
**Empfohlener Sprint:** Steps 37 in einem Rutsch (alles non-UI), 813 parallel beim normalen App-Lauf visuell abhaken.
### 1.1 Planning Sessions — Manual Verification
1. Manual-Task mit Title + TODO-Description anlegen.
2. Rechtsklick → **Open planning Session** → Terminal mit Claude CLI öffnet.
3. In CLI zwei Children via `mcp__claudedo__create_child_task` anlegen.
4. UI: Drafts eingerückt, italic, `DRAFT`-Badge; Parent `PLANNING`-Badge; Chevron klappt.
5. CLI `finalize` → Children Queued bzw. Queued+BlockedBy; Parent `Finalized` (`PLANNED`-Badge, blau); erste Child startet automatisch.
6. Terminal ohne Finalize schließen → Rechtsklick öffnet Resume/Finalize-now/Discard-Modal.
7. Delete auf Parent mit Children → freundlicher Fehlerdialog, kein Delete.
### 1.2 Prime Claude — Manual Verification
1. Settings → Prime-Claude-Tab → Schedule mit Uhrzeit + Wochentag-Toggles anlegen.
2. Trigger (ggf. verschobener `IPrimeClock`) → Footer-Notification, neuer Task in Ziel-Liste.
3. Worker-Restart im Schedule-Fenster → Catch-up genau einmal (kein Doppelfeuer).
4. Schedule editieren → `next_due_at` neu berechnet, UI aktualisiert.
5. Schedule löschen → keine weiteren Trigger, keine ghost-Tasks.
### 1.3 Self-Update — Manual Verification
Voraussetzung: Gitea-Release unter `git.kuns.dev/releases/ClaudeDo` mit `ClaudeDo-<version>-win-x64.zip`, `ClaudeDo.Installer-<version>.exe`, `checksums.txt`.
1. Baseline (z.B. `0.2.x`) installieren.
2. Neues Release `v0.3.0` veröffentlichen.
3. App starten → Banner `Update available: v0.2.x → v0.3.0`.
4. **Update now** → App schließt, Installer im Update-Mode, restartet Worker.
5. App neu starten → Banner weg; `Help → Check for updates` → „You're up to date".
6. Alten Installer manuell starten → bietet Self-Update an. **Update** / **Continue anyway** / **Cancel** je einmal durchspielen.
7. Network-Kill beim Start in App und Installer → silent fallback (kein Error, kein Banner).
### 1.4 Weekly Report — Manual Verification (NEU)
1. Menü → Weekly Report öffnen → Default-Range stimmt (Standup-Wochentag berücksichtigt).
2. Generate → Report-Body entsteht aus Session-History; Multi-Repo-Zuordnung korrekt; Standup-Wochentag-Sentinel greift.
3. Excluded-Paths in Settings → entsprechende Repos fehlen im Report.
4. Report wird persistiert (`WeekReportRepository`) und beim erneuten Öffnen geladen.
### 1.5 Daily-Prep — Manual Verification (NEU)
1. `DailyPrepMaxTasks` in Prime-Settings setzen.
2. MyDay-Header → **Prepare day** (oder geplanter Prime-Trigger) → Live-Prep-Output läuft in der Details-Island.
3. Claude wählt ≤ Cap Tasks aus, `set_my_day` schreibt sie in MyDay; Cap-Guard verhindert Überschreitung.
4. **Prep-log** öffnet den persistierten letzten Lauf im Terminal-View; **Clear-day** leert MyDay.
5. Re-Open des Prep-Windows lädt den persistierten Log; Empty-State-Hinweis startet Planung aus dem Fenster.
---
## 2. UI — Offene Punkte
### 2.1 Status-Bar Live-Update 🟡 (durch Refactor verschoben)
- `StatusBarViewModel` existiert **nicht mehr** als Datei — Connection-Status lebt jetzt in `IslandsShellViewModel` + `WorkerConnectionModalViewModel` (Islands-Architektur). Die Footer-Connection-Pill ist gebaut und farbcodiert.
- **Verbleibendes Risiko:** Ob `RunNow`-Enable/Disable pro Task-Row bei Connection-Change sauber re-evaluiert wird, ist nicht verifiziert. Gegen die aktuelle Architektur neu bewerten statt das alte `WeakReferenceMessenger`-Rezept blind umzusetzen.
- **Aufwand:** klein (erst messen, dann ggf. fixen).
> Erledigt seit letztem Backlog: Folder-Picker (§alt 2.1), Delete-Confirmation (§alt 2.2), Markdown-Rendering, Live-Log Auto-Scroll (§alt 2.4), Task-Level-Diff-Viewer (§alt 2.5, kein `cmd /k git diff` mehr), Settings-Dialog, Planning-Badge-Farben, tote Converter-Statics — siehe §6.
---
## 3. Worker-Robustheit
### 3.1 Worktree-Cleanup bei Anlage-Failed ✅
- `WorktreeManager.cs:64-92` heilt eine „branch already exists"-Kollision (remove + prune + delete + retry).
- Der DB-Insert (`:96-122`) ist jetzt in `try/catch` gekapselt: schlägt er fehl, nachdem `WorktreeAddAsync` erfolgreich war, wird der verwaiste Worktree + Branch best-effort (non-cancellable) entfernt und die Exception rethrown. Test: `WorktreeManagerTests.CreateAsync_DbInsertFails_RemovesOrphanedWorktreeAndBranch`.
### 3.2 CLI-Preflight beim Worker-Start ✅
- `Worker/Lifecycle/ClaudeCliPreflight.cs` + Wiring in `Program.cs`; skippable via `CLAUDEDO_SKIP_CLI_PREFLIGHT=1`; Tests vorhanden.
### 3.3 File-Sink-Logging ✅
- `Program.cs:34-40`: `UseSerilog` + `WriteTo.File("~/.todo-app/logs/worker-.log", rollingInterval: Day, retainedFileCountLimit: 7)`.
---
## 4. Service-Deployment
### 4.1 Worker-Autostart via Startup-Shortcut ✅ (ersetzt Scheduled Task + Windows-Service)
- Worker als `WinExe` + Serilog-File-Sink + Single-Instance-Mutex.
- Autostart über Startup-Ordner-Verknüpfung `ClaudeDo Worker.lnk`, vom Installer via `AutostartShortcut`/`ShortcutFactory` angelegt. Kein Scheduled Task, kein Windows-Service.
- `UninstallRunner` löscht die `.lnk` und migriert Legacy-Installs (best-effort Löschen des alten Scheduled-Tasks + Windows-Service).
- **Manuelle E2E-Verifikation am Gerät ausstehend** (Logoff/Logon-Autostart, Update-Pfad, Uninstall).
### 4.2 Pfad-Auflösung absolut ✅
- `WorkerConfig.Load` expandiert `~`/`%USERPROFILE%`.
### 4.3 Installer-Projekt ✅
- `ClaudeDo.Installer` (WPF) + `ClaudeDo.Releases` — Self-Update funktioniert (siehe §1.3).
---
## 5. Tests / CI
### 5.1 CI-Pipeline (Gitea Actions) ⛔ DROPPED
- Bewusst nicht gebaut: Workflow ist push-to-main ohne PRs, `.gitea/workflows/release.yml` baut bei jedem Push ein Release, und Tests laufen am Ende jeder Entwicklungssession. Eine separate `ci.yml` (Build/Test auf Push/PR) wäre für diesen Workflow reine Dopplung.
### 5.2 SignalR-Hub-Tests ✅
- `Hub/PlanningHubTests.cs`, `AgentSettingsHubTests.cs` decken Hub-Methoden via Fakes ab.
- **Optional:** echter Roundtrip mit `WebApplicationFactory<Program>` + `HubConnectionBuilder` — niedriger Mehrwert.
### 5.3 Smoke gegen echten `claude` ⛔ (kein automatisierter Test — manuell, siehe §1.0 Step 3)
- Bewusst **kein** xUnit-Test: ein Test, der das echte `claude`-Binary spawnt, soll nicht in der Suite leben (kein Claude-Aufruf in `dotnet test`). Stattdessen als manueller Verification-Schritt geführt (§1.0 Step 3): Task mit Prompt „ping" laufen lassen → `task_runs`-Row mit `session_id NOT NULL`, `result` non-empty, `output_tokens > 0`.
### 5.4 ExternalMcpService-Tests ✅
- Service exponiert **18 Tools** (war 11): `ListTaskLists`, `ListTasks`, `GetTask`, `AddTask`, `UpdateTask`, `UpdateTaskStatus`, `ReviewTask`, `RunTaskNow`, `CancelTask`, `DeleteTask`, `GetTaskStatusValues`, `GetTaskWorktree`, `GetTaskDiff`, `MergeTask`, `ListWorktrees`, `CleanupTaskWorktree`, `GetDailyPrepCandidates`, `SetMyDay`.
- `ExternalMcpServiceTests.cs` hat jetzt 26 Tests (war 14): die zuvor ungetesteten Worktree/Git-Tools (`GetTaskWorktree`, `GetTaskDiff`, `MergeTask`, `ListWorktrees`, `CleanupTaskWorktree`) haben je Error-Pfad + git-gestützten Happy-Path (skippen wenn git fehlt). Plus 4 Sibling-Dateien (`ConfigMcpToolsTests`, `LifecycleMcpToolsTests`, `ListMcpToolsTests`, `RunHistoryMcpToolsTests`).
---
## 6. Dokumentation
### 6.1 README.md ✅
- Existiert mit Inhalt (Projektbeschreibung, Architektur, Zwei-Prozess-SignalR-Modell).
### 6.2 docs/architecture.md ⬜
- Existiert nicht. Architektur lebt verstreut in `plan.md`, README und den Projekt-CLAUDE.md-Dateien. Entweder konsolidieren oder bewusst nicht ausgliedern.
### 6.3 ADRs ⬜
- Kein `docs/adr/` o.ä. Vorschläge: „SignalR vs. SQLite-Polling für IPC", „Worktree pro Task", „TaskStateService als alleiniger State-Owner", „BlockedByTaskId statt Status='Waiting'", „External MCP als zweite WebApplication".
- **Aufwand:** klein, hilfreich für später.
### 6.4 Mailbox-Proposal ⬜ (Entscheidung offen)
- `docs/mailbox-proposal.md` existiert weiter; **keine** Implementierung in `src/` (Grep nach „mailbox" → 0 Treffer). Entscheiden: bauen, droppen oder parken. Wenn droppen → Datei entfernen.
---
## 7. Erledigt seit dem letzten Backlog (Beweis-geführt)
Diese Punkte standen 2026-04-30 noch als offen/partial und sind verifiziert fertig:
| Item | Beleg |
|---|---|
| Folder-Picker (Working Directory) | `ListSettingsModalView.axaml.cs:73` `OpenFolderPickerAsync` |
| Delete-Confirmation (Listen + Tasks) | `ConfirmAsync(...)` in `ListSettingsModalViewModel.cs:98`, `DetailsIslandViewModel.cs:939`, `TasksIslandViewModel.cs:785` |
| Live-Log Auto-Scroll | `SessionTerminalView.axaml.cs:45` `ScrollToEnd()` |
| Task-Level Diff-Viewer | `DiffModalView` via `DetailsIslandViewModel.cs:845`; kein `cmd /k git diff` mehr |
| File-Sink-Logging | `Program.cs:34` Serilog |
| README.md | vorhanden |
| `.gitattributes` | vorhanden, `* text=auto eol=lf` |
| `WorkerHub.GetActive``ActiveTaskDto` | `WorkerHub.cs:21` Record statt anonymem Typ |
| TODO in `DetailsIslandViewModel` (SendPromptAsync) | entfernt — kein TODO mehr in der Datei |
---
## 8. Fallengelassen / Obsolet
| Item | Begründung |
|---|---|
| ⛔ Tag-Negation / Exclusion (alt §3.4) | Tag-System wurde entfernt — `TaskEntity` hat keine `Tags`-Property mehr, Queue-Picker filtert nicht mehr nach Tags. |
| ⛔ Tag Multi-Select Control (alt IP-4) | Dito — kein Tag-Control existiert, kein Bedarf mehr. |
| ⛔ Install-Service-Skript (alt §4.3) | App nutzt Startup-Ordner-Shortcut statt Windows-Service → ein Service-Install-Skript ist architektonisch obsolet. |
| ⛔ Notes-Mode `lists.kind`-Switch (alt IP-2) | Ursprüngliche Rahmung überholt: Daily-Notes + Notes-Mode in der Details-Island sind separat gebaut; ein List-Kind-Feld auf der Entity ist nicht nötig. |
---
## 9. Bekannte Code-Schulden / Smells
| Stelle | Issue | Status |
|---|---|---|
| `TaskRunner` Worktree-vs-Sandbox-Branch | In `PrepareRunDirectoryAsync` ausgelagert (kleiner Helper, kein Strategy-Pattern — bei 2 Pfaden Over-Engineering). `RunAsync` liest jetzt linear. | ✅ |
| `App.Services` statischer ServiceProvider | Entfernt: `App` bekommt den Provider per Constructor-Injection über `AppBuilder.Configure(() => new App(services))`; parameterloser Ctor + `BuildAvaloniaApp()` bleiben für den Designer. **UI-Start manuell smoke-testen** (kein headless-Lauf möglich). | ✅ |
---
## 10. Empfohlene Reihenfolge
**Block 1 — Kernpipeline beweisen** (kein neuer Code, nur Beweis): §1.0 Steps 37 manuell durchspielen. Das ist das größte ungedeckte Risiko.
**Block 2 — Neue Features verifizieren:** §1.4 Weekly-Report, §1.5 Daily-Prep, dazu §1.1/§1.2 Walkthroughs.
**Block 3 — Robustheit & Sicherheitsnetz:** §5.3 Real-`claude`-Smoke-Test. (§3.1 Worktree-Cleanup und §5.4 ExternalMcp-Tests sind erledigt; §5.1 CI fallengelassen.)
**Block 4 — Doku & Aufräumen:** §6.2 architecture.md (oder bewusst verwerfen), §6.3 ADRs, §6.4 Mailbox-Entscheidung, §2.1 Status-Bar-Risiko prüfen, §9 Smells.