Repository navigation
Description
Prompt recall can change text that the user actually typed when it resembles content appended by the app. This is an existing main behavior from #9173, verified while reviewing the main-to-V2 reconciliation #10051; it is not caused by the V2 merge.
recallableComposerPrompt in apps/web/src/components/chat/composerPromptHistory.ts strips an Ultrathink:\n prefix and trailing <review_comment>…</review_comment> blocks, and omits text matching the attachment-only bootstrap or plan-implementation prefix, using text matching without send-time provenance. A user-authored prompt with those same strings is indistinguishable from generated context.
Reproduction: send literal text Ultrathink: followed by a newline and Keep this prefix in my example. With an empty composer, ArrowUp recalls only Keep this prefix in my example. A literal trailing review-comment example can similarly disappear. This is source-verified in main 6270a6f88 and reconciliation da3cf59dd; the helper file is identical on those revisions. No OS-level keyboard reproduction was performed for this edge case.
Expected: recall preserves user-authored text byte-for-byte while excluding context that the application added at send time. Use reliable provenance or another representation that distinguishes the two; avoid inferring origin solely from matching text.
Acceptance:
- Literal user-authored prefixes and trailing blocks survive recall.
- Actually generated context remains excluded.
- Regression coverage distinguishes identical text with different origins and preserves normal history navigation.
Verified P2 follow-up; the V2 reconciliation preserves existing main behavior and does not claim this fixed. Checked existing prompt-history issue searches and #9173 before filing.
Reported through the OpenAI Codex harness by GPT-6 Astra.
Activity
juliusmarminge commentedon Sep 5, 2026
Triage
Confirmed bug on current
main. Prompt recall reconstructs “what the user typed” by stripping send-time decorations from persistedmessage.text. Those decorations are inferred by string match only; the timeline does not record which spans the app appended.Diagnosis
History is built on each ArrowUp/ArrowDown from timeline user messages (
buildComposerPromptHistoryEntries→recallableComposerPromptinapps/web/src/components/chat/composerPromptHistory.ts). The helper, unchanged since #9173 (fd773172e):Ultrathink:\n(CLAUDE_ULTRATHINK_PREFIX).<review_comment>…</review_comment>blocks (stripTrailingReviewComments).""(entry omitted) when the remainder equalsATTACHMENT_ONLY_BOOTSTRAP_PROMPTor starts withPLEASE IMPLEMENT THIS PLAN:\n.Send time writes a single decorated string.
ChatViewappends terminal, element, preview, and review-comment blocks, thenformatOutgoingPrompt→applyClaudePromptEffortPrefixmay addUltrathink:\n.OrchestrationMessagestores onlyid,role,text, attachments, and turn timestamps — no original composer text and no send-time span list.A user-authored prompt that begins with
Ultrathink:\nor ends with a review-comment block is therefore indistinguishable from an app-generated prefix/suffix. Mid-prompt review-comment blocks already survive (covered by existing tests); a trailing user-authored block does not. Existing tests encode the strip behavior; they do not distinguish identical text with different origins.This is the behavior #9173 shipped (“send-time appends are stripped so you get the text you typed”), implemented as a heuristic because that PR stored nothing extra. It is not caused by the V2 reconciliation. Open PR #10051 preserves this main helper and already names #10056 as the P2 follow-up.
Repro (source-verified)
Send exactly:
Clear the composer.
Press ArrowUp.
Recalled text is
Keep this prefix in my example. A prompt whose only extra content is a trailing<review_comment>…</review_comment>block recalls without that block. Same outcome onmain09aac7156/ cited6270a6f88; the helper file has one commit (#9173). No OS-level keyboard run in this triage.Ultrathink: …without the newline is not stripped (startsWith("Ultrathink:\n")only). That is a prefix-shape mismatch, not provenance.Expected
Recall should keep user-authored bytes and drop only context the app added at send time. Origin cannot be inferred from text match alone.
Acceptance (unchanged)
Priority and fix shape
P2. Common path (real send-time appends) works. Failure is an edge case: the user typed the same strings the app injects. Timeline still shows the full sent message; workaround is copy from the thread.
A durable fix needs send-time provenance (store original composer text, or the spans the app appended) and recall from that. Tweaking the strip regexes cannot tell the two cases apart and will regress one or the other. #9173 explicitly avoided new persisted fields; that is the constraint, not a reason to close this.
Related
Not a duplicate of #9173/#10051. Keep this issue open as the tracker. No
needs-triageon the issue today.Filed by Cursor Grok 4.6 via cloud-agent issue triage. Investigation only; no branch, commit, or PR.
juliusmarminge commentedon Oct 22, 2026
Reproduced in the Linux web dev app on 89fe509232. Sent the literal two-line
Ultrathink:example with Codex, then pressed ArrowUp in the empty composer: onlyKeep this prefix in my examplereturned. A second send containing a literal trailing<review_comment>block recalled only the preceding text. Checked 939 open issues and 1,382 open PRs; no matching duplicate or existing fix found.