Deliver launch context out-of-band via the system-prompt channel - #452
Merged
Conversation
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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:--append-system-prompt "<preamble>\n<context>…"-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/ContextPayloadStoreare 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:session_launch_context(migrationv17_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.cliLaunchreads the persisted text via a sync accessor (getSessionLaunchContextTextSync, mirroringgetAIConfigSync) on resume launches.Monitoring stays clean by construction
event_msg/user_messageevents as user content and ignoresmessage-type response items, so the injected developer-role instructions never appear in monitoring. Verified against the parser, not assumed.Also fixed
AgentHubGhosttyTerminalSurface.restart()re-configured withmetadataStore: niland 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, mirroringTerminalContainerView.Test plan
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).CLICommandConfigurationArgumentHandlingTestsresume assertions (resume now re-passes the system prompt on both providers)../scripts/test.shgate: 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 appsession_workspace_stateverified byte-identical before/after the gate.🤖 Generated with Claude Code