fix(codex): keep transport echoes out of durable user history

Port the exact submitted-wire-text ownership boundary from #93546 onto
current topical runtime code. Do not add the candidate's mocked-result
fallback or storage-level content deduplication. Preserve later distinct
and identical user events, separate identical accepted turns, and keyless
inputs. Add two regression invariants and offline subprocess-wire A/B.

Local wire A/B: 4/8 control matrix passing on base, 8/8 after.
Broader tests queued behind campaign lock; not ready for merge.

Refs #104653
Original diagnosis: @gitszabolcs (#38254)
Original implementation: #43127, submitted by @vashkartik
Focused salvage and wire-text correction: @fancyboi999 (#93546)
Current-main carry-forward considered: #104698

Co-authored-by: Xinmin Zeng <135568692+fancyboi999@users.noreply.github.com>
Co-authored-by: VECTOR <vector.hq@outlook.com>
This commit is contained in:
Teknium
2026-09-07 01:58:51 -07:00
parent 5904c7a395
commit a9ef4a7625
7 changed files with 188 additions and 2 deletions
+9 -1
View File
@@ -419,7 +419,15 @@ def _persist_projected_messages(agent, turn, messages: List[Dict[str, Any]]) ->
if not turn.projected_messages:
return
from agent.message_metadata import append_message
for projected_message in turn.projected_messages:
projected_messages = turn.projected_messages
# Turn-start persistence owns the accepted input. Codex's leading user item
# only echoes its coerced wire text; later/nonmatching events remain real.
submitted_user_text = getattr(turn, "submitted_user_text", None)
first = projected_messages[0]
if (submitted_user_text is not None and first.get("role") == "user"
and first.get("content") == submitted_user_text):
projected_messages = projected_messages[1:]
for projected_message in projected_messages:
append_message(messages, projected_message)
if getattr(agent, "_session_db", None) is None:
return