Files
ClaudeDo/docs/open.md
T

23 KiB
Raw Blame History

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-TaskRowViewModels 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 (UnifiedDiffParserDiffFileStatus.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).

Design-Entscheidungen (27.07.-Batch, Sichtprüfung am 2026-08-06 abgeschlossen)

Der Sichtprüfungs-Block dieses Batches (Ctrl+K/#, Titel-Edit, ConPTY-/Refine-Spinner, Interactive-Chip, Diff-Viewer-Abstände, Manual-Tasks, Vorgaben-pro-Modell-Tabelle) ist von Mika verifiziert und deshalb hier entfernt. Es bleiben die Entscheidungen, die daran hängen:

  • 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.
  • QueueServiceTests.UsageGate_TransitionLogging_FiresOncePerChange ist zeitbasiert flaky, unabhängig von dieser Session: Schlägt reproduzierbar fehl (Expected 1, Actual 0 Warn-Log-Aufrufe), sowohl solo (--filter) als auch im Vollauf, auf einem sauberen git worktree add gegen main (bdee731) — also kein durch diese Abschluss-Session verursachter Regress (die Session hat keine .cs-Datei angefasst). Ursache: der Test verlässt sich auf einen festen Task.Delay(200), um mehrere 50-ms-Backstop-Ticks abzuwarten (Kommentar im Test: „Several backstop ticks (50ms interval) all observe the same blocked state"); auf einer stark ausgelasteten Maschine (hier: viele parallele ClaudeDo-Worktrees/Builds) reicht das Fenster nicht immer. Zum Vergleich: derselbe Test lief in einer zweiten, isolierten Verifikation (Scratch-Merge für den Environment-Checks-Task) sauber durch (876/876). Fix wäre ein Poll-basiertes Warten statt fixem Sleep — aber außerhalb des Scopes dieser Doku/Verifikations-Session (keine Code-Änderung angefasst).

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: "), 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).

  • Roadblock reply field (2026-08-05) — build + unit tests all green, but not visually verified: on a Done (or WaitingForReview/Failed/Cancelled) task with a reported roadblock, the ROADBLOCK card shows a reply textbox + Send button under the roadblock text. Check layout/spacing against the AskUser question card it's modeled on, Enter-to-send, the disabled state + hint text when there's no session ID to resume, and that an override-slot-busy error shows up in the footer log strip (not a modal) with the typed text still in the field. 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.

  • Post-merge verify gate (2026-08-05) — build + unit tests all green (incl. real-process VerifyCommandRunner exit-code/output/timeout tests and TaskMergeService success/failure/ timeout paths via a fake runner), but not visually verified: open a list's Settings modal, confirm the new "VERIFICATION" section renders below Agent with a settable/clearable VerifyCommand field; approve a task on a list with a failing command configured and confirm the footer/error surfacing (ShowErrorAsync) actually shows the verify failure message instead of silently looking like nothing happened. Also no real-build smoke test (a real dotnet build/ dotnet test invocation as the configured command) — only fast synthetic commands (exit N, ping for timeout) were exercised.

Offene Verifikation (2026-08-05, Usage Monitor)

  • Visueller Pass Usage-Pill (Footer und Mission-Control-Header): Text/Tooltip, Dot-Zustände normal/warn/stale/blocked, Dark/Light.
  • Visueller Pass Usage-Monitor-Modal: Gauges (dynamisch aus limits[]), Modell-/Task- Tabellen, Info-Bänder (stale/gate-blocked), 7d/30d-Presets + Custom-Range, Dark/Light.
  • E2E Gate: das Gate greift real, sobald ein Bucket (five_hour/seven_day) die konfigurierte Schwelle reißt — Queue-Nachschub pausiert, laufende Runs/RunNow/ConPTY/ Planning/Prime bleiben unberührt — und die Queue nimmt nach dem Reset selbstständig wieder auf (30s-Backstop, kein persistenter Pause-Zustand).
  • Risiko: der Usage-Endpoint (GET https://api.anthropic.com/api/oauth/usage) ist undokumentiert und kann sich ändern; bei Ausfall/Formatänderung ist das Gate wirkungslos (fail-open by design — kein Blocker, aber der Schutz fällt dann aus, ohne dass es auffällt).

Nachtrag 2026-08-05: 429-Fix (Poll-Kadenz + Refresh-Button)

Der 60s-Poll lief in 429s. Neu: aktivitätsabhängige Kadenz (5 Min. solange ein Task Running ist, sonst 15 Min.), 429-Backoff mit Retry-After, und ein „Jetzt aktualisieren"-Button im Usage-Monitor-Modal (RefreshUsageUsageMonitorService.RefreshNowAsync, 10s-Cooldown). Unit-Tests grün, offen:

  • Visueller Pass Refresh-Button im Modal (Button + Spinner + Hinweiszeile, Dark/Light, en/de) — Teil des oben schon offenen Modal-Passes.
  • E2E: über ≥20 Min. mit und ohne laufenden Task beobachten, dass keine 429s mehr im Worker-Log auftauchen und die Pill trotzdem aktuell bleibt.
  • Beachten: die Pill wird jetzt erst nach 3× 15 Min. als stale markiert — ein echter Endpoint-Ausfall fällt vorher nur über LastError auf (der IsStale sofort setzt).

Offene Verifikation (2026-08-05, Max-Turns-Ceiling)

Build + unit tests grün (ResolveMaxTurns-Klemmung, Repository-Backfill von model_presets, Migration AddMaxTurnsCeiling gegen eine Scratch-DB angewendet), aber nicht visuell verifiziert:

  • Agent-Settings-Editor (Task und Liste): Max-Turns-Feld auf einen Wert über der Ceiling (Default 80) setzen, Hinweistext unter dem NumericUpDown erscheint ("Runs are capped at {N} turns…").
  • Settings → Allgemein → Vorgaben pro Modell: eine Zeile über 80 setzen, derselbe Hinweistext erscheint unter der Zeile.
  • MaxTurnsCeiling ist seit 2975f90 selbst editierbar (Settings → Allgemein, SettingsModalView.axaml) — Feld prüfen: Wert ändern, speichern, Hinweistexte oben ziehen mit.

Offene Verifikation (2026-08-05, Environment Checks / SystemCheckPage)

Checks + SystemCheckPage (claudedo/06aca9b3…) und das ExecutableResolver-Wiring im Worker (claudedo/40272c0b…) sind seit 2026-08-06 auf main gemerged; die frühere „erst mergen"- Voraussetzung ist erledigt. Details → installer-preflight in docs/explore-notes/README.md und der Abschnitt „Environment Checks" in src/ClaudeDo.Installer/CLAUDE.md.

Update (2026-08-06): beide Folge-Features sind jetzt implementiert und auf main.

  • Diagnose-Sektion (Config-Modus/SettingsWindow): Pages/DiagnosePage/ + geteilte Checks/CheckListViewModel.cs/Checks/CheckListView.xaml (auch von SystemCheckPage genutzt, keine zweite Implementierung). Unit-getestet (tests/ClaudeDo.Installer.Tests/Pages/DiagnosePage/DiagnosePageViewModelTests.cs).
  • „Claude Help Me"-Button: Core/ClaudeHelpLauncher.cs + SystemCheckPageViewModel/-View, unit-getestet (tests/ClaudeDo.Installer.Tests/Core/ClaudeHelpLauncherTests.cs).

Beides nicht visuell verifiziert:

  • Help-Me-Button ist deaktiviert, wenn claude-cli nicht Ok ist oder claude-auth Failed ist (bleibt aktiv bei Unknown), mit erklärendem Tooltip — unit-getestet.
  • „Claude Help Me" öffnet tatsächlich ein Terminal mit laufender Claude-Session, und die Session hat den Diagnose-Report gelesen — nicht verifiziert (der eigentliche Terminal-Start/wt.exe-Zusammenspiel und die Session-Qualität sind nur über die injizierte IProcessLauncher-Fake getestet, nie mit einem echten Terminal/CLI).
  • Platzierung des Help-Me-Buttons: er sitzt seit dem Merge der Diagnose-Sektion in einer eigenen Zeile unter dem geteilten Check-Listen-Footer (der reservierte Slot im Footer entfiel mit der Extraktion nach CheckListView.xaml). Optisch prüfen, ob das so bleiben soll oder ob der Button in den geteilten Footer gehört.
  • Diagnose-Sektion im Config-Modus: Öffnen von SettingsWindow löst keinen Prüflauf aus, Klick auf „Erneut prüfen" schon; zeigt die echten installierten Pfade/Ports (nicht die InstallContext-Defaults), und der laufende Worker auf dem konfigurierten SignalR-Port gilt nicht als Konflikt — unit-verifiziert, visueller Durchlauf noch offen.

Weitere Punkte, gebaut + unit-getestet auf main, aber nicht visuell verifiziert:

  • SystemCheckPage: Layout, Icon-/Farbwirkung der vier Status (Ok grün / Warnung orange / Fehler rot / Unbekannt grau — StatusGreenBrush/StatusOrangeBrush/StatusRedBrush/ StatusGrayBrush), Lesbarkeit der Hint-Texte, DE und EN.
  • Weiter-Button gesperrt bei einem echten blockierenden Fehler (z. B. claude nicht im PATH → claude-cli Error/Failed), und der Grund ist in der Zusammenfassungszeile sichtbar (nennt den/die blockierenden Check(s) namentlich).
  • „Erneut prüfen" wechselt einen Status live (z. B. git-Identity setzen → Warnung verschwindet), ohne dass ein zweiter paralleler Lauf startet, wenn währenddessen erneut geklickt wird.
  • Update-Modus zeigt die SystemCheckPage nicht (Wizard bleibt Welcome + Install).
  • Auf einem Rechner mit npm-installiertem claude.cmd: claude-cli-Check findet es (Detail-Text „Resolved via a shim…"), und ein Task läuft im Worker durch (bestätigt, dass ClaudeProcess/ClaudeCliPreflight den Shim über cmd.exe /c tatsächlich startet, nicht nur, dass der Check ihn findet).

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.