diff --git a/docs/explore-notes/conpty-sessions.md b/docs/explore-notes/conpty-sessions.md index 6d477b1f..8984a383 100644 --- a/docs/explore-notes/conpty-sessions.md +++ b/docs/explore-notes/conpty-sessions.md @@ -1,8 +1,8 @@ # ConPTY interactive sessions & launch specs > **Explore-note — verify before trusting.** Distilled map of a subsystem, not authoritative. -> Last verified against commit `f6cb825` (2026-08-05). -> Drift check: `git log --oneline f6cb825..HEAD -- src/ClaudeDo.Worker/Planning src/ClaudeDo.Worker/Hub src/ClaudeDo.Ui/ViewModels/MissionControlViewModel.cs src/ClaudeDo.Ui/Views/InteractiveTerminalView.axaml` +> Last verified against commit `bdee731` (2026-08-05). +> Drift check: `git log --oneline bdee731..HEAD -- src/ClaudeDo.Worker/Planning src/ClaudeDo.Worker/Hub src/ClaudeDo.Worker/Runner/ClaudeArgsBuilder.cs src/ClaudeDo.Ui/ViewModels/MissionControlViewModel.cs src/ClaudeDo.Ui/Views/InteractiveTerminalView.axaml` > Stable structure only (no line numbers). See docs/explore-notes/README.md. Covers `InteractiveLaunchSpecService` and the four kinds of embedded ConPTY session the UI @@ -108,6 +108,47 @@ reaches the PTY**. See the note in `src/ClaudeDo.Ui/CLAUDE.md`. tapping it jumps to that Mission Control pane. `TasksIslandViewModel.SyncInteractiveSessions` mirrors Mission Control's open panes onto the rows. +## System-prompt matrix (autonomous vs. interactive) + +Autonomous and interactive sessions do **not** share a system prompt. Per start path: + +| Start path | Entry point | System prompt | +|---|---|---| +| Autonomous run/continue/retry | `TaskRunner.ResolveConfigAsync` → `ClaudeArgsBuilder.Build` | `--append-system-prompt `, recomputed and re-sent on **every** invocation including a `--resume` continue (`PromptKind.System` + improvement/list/task overrides) | +| Interactive task session, fresh | `InteractiveLaunchSpecService.BuildForTaskAsync` → `BuildFreshTaskArgsAsync` | none — no `--append-system-prompt(-file)` at all | +| Interactive task session, resume | `InteractiveLaunchSpecService.BuildForTaskAsync` → `WindowsTerminalLauncher.BuildResumeArgs` | none — only `--resume ` (+ `--effort`) | +| Ad-hoc directory session | `InteractiveLaunchSpecService.BuildForDirectoryAsync` | none | +| Planning session start | `InteractiveLaunchSpecService.BuildPlanningStart` → `WindowsTerminalLauncher.BuildPlanningStartArgs` | `--append-system-prompt-file ` (`PromptKind.Planning`) | +| Planning session resume | `InteractiveLaunchSpecService.BuildPlanningResume` → `WindowsTerminalLauncher.BuildPlanningResumeArgs` | none — only `--permission-mode default --allowedTools --resume ` | +| List handler ("Let Claude handle it") | `InteractiveLaunchSpecService.BuildForMergeHelperAsync` | `--append-system-prompt-file ` (`PromptKind.MergeHelper`), always fresh — this path never resumes | + +So every interactive resume (task session and planning) drops the system prompt entirely — it's +not that they inherit the autonomous one, it's that **no** `claude` process on any resume path +ever passes `--append-system-prompt(-file)`. + +### Does `--resume` bring back a prior `--append-system-prompt`? No. + +Checked by reading real session transcripts (`~/.claude/projects//.jsonl`) for +several autonomous ClaudeDo task runs, including ones with multiple invocations (initial run + +`ContinueAsync`/retry on the same session id, confirmed via that project's `task_runs` history). +Grepped for the `PromptKind.System` default text ("You are completing one well-defined task +autonomously...") and for any `"type":"system"` entry or `message.role == "system"` anywhere in +those files: the prompt text only ever showed up as ordinary tool-result content (e.g. a task +that happened to read `PromptFiles.cs`'s own source), never as a persisted system/config entry. +No session transcript — autonomous or interactive — carries a system-role message or a +per-session record of the CLI flags it was launched with; there is no sidecar file next to the +`.jsonl` either. The system prompt is purely a per-process request parameter the CLI builds fresh +from that invocation's own flags, never replayed from a resumed session's history. This matches +why `TaskRunner.ContinueAsync` (autonomous) explicitly re-resolves and re-passes +`--append-system-prompt` on every continue instead of relying on `--resume` to carry it — +if inheritance worked, that re-resolution would be redundant. + +**Conclusion: no leak.** An interactive resume (task or planning) does not pick up the autonomous +run's `--append-system-prompt` text — including the "commit your work" / `CLAUDEDO_BLOCKED` +instructions from `PromptKind.System`. It simply runs with the `claude` CLI's own baseline system +prompt, same as every other path in this table that passes no system-prompt flag. No code change +needed here. + ## Related hub methods `GetInteractiveLaunchSpec`, `GetAdHocLaunchSpec`, `GetMergeHelperLaunchSpec`,