Skip to content

Deliver launch context out-of-band via the system-prompt channel - #452

Merged
jamesrochabrun merged 1 commit into
mainfrom
jroch-context-bg
Aug 14, 2026
Merged

Deliver launch context out-of-band via the system-prompt channel#452
jamesrochabrun merged 1 commit into
mainfrom
jroch-context-bg

Conversation

@jamesrochabrun

Copy link
Copy Markdown
Owner

Summary

Curated launch context (the Context tab / context sets feature from #448) was prepended to the first user message — pasted into the Claude TUI, or passed as Codex's argv prompt. That polluted the visible first message, the transcript, and session previews.

Context now rides each provider's purpose-built background channel instead, folded into the same value as the existing simulator guidance in EmbeddedTerminalLaunchBuilder:

  • Claude: --append-system-prompt "<preamble>\n<context>…"
  • Codex: -c developer_instructions="<preamble>\n<context>…"

The first message carries only what the user actually typed; a context-only launch types nothing into the terminal. A one-line preamble gives the agent provenance ("the user attached this curated context when launching this session"). ContextAssembler / ContextPayloadStore are unchanged — blocks over 48 KB still spill to a payload file with a short reference prompt, which is what rides the flag.

Resume persistence

System-prompt text is per-invocation, not conversation history, so a resume that drops the flag silently loses the context. Both resume branches (claude -r, codex resume) now re-pass it:

  • New table session_launch_context (migration v17_create_session_launch_context) records the exact context text when a pending session resolves to its real session id; rows are pruned after 30 days on save.
  • cliLaunch reads the persisted text via a sync accessor (getSessionLaunchContextTextSync, mirroring getAIConfigSync) on resume launches.
  • Side effect: simulator guidance now also re-applies on resume, which is consistent — the XcodeBuildMCP config it depends on was already passed on resume.

Monitoring stays clean by construction

  • The Codex parser only surfaces event_msg/user_message events as user content and ignores message-type response items, so the injected developer-role instructions never appear in monitoring. Verified against the parser, not assumed.
  • Claude's appended system prompt is not a JSONL message, so nothing new shows up there either.
  • Session card previews and auto-naming now see the user's real first message instead of the context blob.

Also fixed

AgentHubGhosttyTerminalSurface.restart() re-configured with metadataStore: nil and unconditionally overwrote the stored reference, dropping AI-config (and now context) lookups after a restart. It now keeps the stored reference when nil is passed, mirroring TerminalContainerView.

Test plan

  • New: LaunchContextRoutingTests (context never merges into the prompt, both providers; whitespace-only context is byte-identical to no context), CombinedAppendSystemPromptTests, EmbeddedTerminalLaunchBuilderLaunchContextTests (flag placement + resume round-trip through a real temp SQLite store), SessionLaunchContextStoreTests (round-trip, upsert, retention pruning, and a v17 migration-preservation test seeded from the v16 baseline).
  • Updated: CLICommandConfigurationArgumentHandlingTests resume assertions (resume now re-passes the system prompt on both providers).
  • All targeted suites pass; Ghostty builds clean via xcodebuild.
  • Full ./scripts/test.sh gate: the AgentHubCore suite fails ~20 known load-dependent flaky tests (workspace detection, worktree progress, CI notifier, Monitor queue — the documented clean-tree flake set). Verified by running the identical suite on a clean worktree at the parent commit: same failure families, and every test that failed only on this branch passes in isolation here (38/38). Real app session_workspace_state verified byte-identical before/after the gate.

🤖 Generated with Claude Code

Curated launch context was prepended to the first user message (pasted
into the Claude TUI / passed as Codex argv), polluting the visible first
message and the transcript. Route it through each provider's background
instructions channel instead: --append-system-prompt for Claude and
-c developer_instructions= for Codex, combined with the existing
simulator guidance in EmbeddedTerminalLaunchBuilder.

System-prompt text is per-invocation, not conversation history, so both
resume branches now re-pass it: the context a session launched with is
persisted to a new session_launch_context table (migration v17, pruned
after 30 days) when the pending session resolves, and resume launches
re-read it from the metadata store.

The first message now carries only the user's actual prompt; a
context-only launch types nothing into the terminal. Codex monitoring
never surfaces the injected developer-role message (the parser only
reads user_message events), and session previews/auto-naming see the
real first message instead of the context blob.

Also fixes Ghostty restart() wiping its stored metadataStore reference,
which would have dropped AI config and context lookups on restart.
@jamesrochabrun
jamesrochabrun merged commit 8c900d5 into main Aug 14, 2026
1 check passed
@jamesrochabrun
jamesrochabrun deleted the jroch-context-bg branch August 14, 2026 05:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant