Defer initial context insertion until the first turn (#14313)

## Summary
- defer fresh-session `build_initial_context()` until the first real
turn instead of seeding model-visible context during startup
- rely on the existing `reference_context_item == None` turn-start path
to inject full initial context on that first real turn (and again after
baseline resets such as compaction)
- add a regression test for `InitialHistory::New` and update affected
deterministic tests / snapshots around developer-message layout,
collaboration instructions, personality updates, and compact request
shapes

## Notes
- this PR does not add any special empty-thread `/compact` behavior
- most of the snapshot churn is the direct result of moving the initial
model-visible context from startup to the first real turn, so first-turn
request layouts no longer contain a pre-user startup copy of permissions
/ environment / other developer-visible context
- remote manual `/compact` with no prior user still skips the remote
compact request; local first-turn `/compact` still issues a compact
request, but that request now reflects the lack of startup-seeded
context

---------

Co-authored-by: Codex <noreply@openai.com>
This commit is contained in:
Charley Cunningham
2026-03-11 11:41:50 -07:00
committed by Michael Bolin
parent c32c445f1c
commit f5bb338fdb
16 changed files with 107 additions and 124 deletions

View File

@@ -1933,21 +1933,9 @@ impl Session {
};
match conversation_history {
InitialHistory::New => {
// Build and record initial items (user instructions + environment context)
// TODO(ccunningham): Defer initial context insertion until the first real turn
// starts so it reflects the actual first-turn settings (permissions, etc.) and
// we do not emit model-visible "diff" updates before the first user message.
let items = self.build_initial_context(&turn_context).await;
self.record_conversation_items(&turn_context, &items).await;
{
let mut state = self.state.lock().await;
state.set_reference_context_item(Some(turn_context.to_turn_context_item()));
}
// Defer initial context insertion until the first real turn starts so
// turn/start overrides can be merged before we write model-visible context.
self.set_previous_turn_settings(None).await;
// Ensure initial items are visible to immediate readers (e.g., tests, forks).
if !is_subagent {
self.flush_rollout().await;
}
}
InitialHistory::Resumed(resumed_history) => {
let rollout_items = resumed_history.history;