Skip to content

🫴 fix: Preserve Queued Follow-Ups Through Handoff - #15942

Merged
danny-avila merged 7 commits into
devfrom
danny-avila/jovial-dirac-fb60fa
Sep 15, 2026
Merged

danny-avila merged 7 commits into
devfrom
danny-avila/jovial-dirac-fb60fa

Conversation

@danny-avila

@danny-avila danny-avila commented Sep 14, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

I fixed the gap between an agent run completing and its server-queued follow-up appearing. The queued words now appear immediately as a presentation-only user row, with cancellation available until the backend fences admission. The row never enters message history or becomes a send/edit/fork anchor.

  • Separate the drawing from admission ownership: history replaces the drawing, while the handoff guard remains until a newer generation attaches or terminal evidence settles all pending successors.
  • Preserve the queue’s original parent/epoch pair separately from its display position and advancing completion boundary so another follow-up submitted during handoff is durably queued and survives reload with its quotes, skills, and attachments.
  • Route typed and dictated composer submissions consistently, and reject competing direct sends before consuming draft context.
  • Allow cancellation of queued and claimed rows; preserve the chip when the backend refuses cancellation after admission begins.
  • Observe receipt and status caches without registering a replacement history fetcher; retain bounded receipt polling and preserve off-screen guards while receipts still owe work.
  • Delegate draft consumption to autosave so its actual storage key and cross-tab ownership remain authoritative.
  • Preserve refused automatic prompts as editable composer text across slash selection, variable dialogs, and library actions.
  • Recover exact response identity instead of choosing a regeneration sibling by array order.
  • Handle cancellation reselection, cold history, restored sessions, terminal recovery, and mixed local/server queues without changing backend persistence or wire formats.

How it works

completed run → response ID + predecessor epoch
  useQueueDrain → first admissible server-owned row
    useQueuedTurnReveal → presentation + handoff guard
      PendingTurn → drawing only, hidden when history has a successor
      useSteering → durable enqueue against immutable queue lineage
      useChatFunctions.ask → refuse competing sends before draining context
      receipt cancellation / newer attachment / terminal repair → release guard
Boundary Regression coverage
History arrives before stream attachment Keep the guard while hiding the drawing; release only for a newer attached generation or terminal result
Another submission during handoff Enqueue with the original parent/epoch and context; reconstruct from the server receipt after remount
Cancellation races admission Attempt cancellation while claimed; retain the row and draft when cancellation is refused; select the next eligible row after settlement
Consecutive successors Preserve the guard through missed runs and remember later admission boundaries after their receipts disappear
Recovery and expiry Preserve off-screen ownership while work is owed; match exact response IDs when regenerations share a parent
Draft ownership Consume the actual autosave key only on acceptance; retain foreign-owned drafts

Change Type

  • Bug fix (non-breaking change which fixes an issue)

Testing

  • Passed 516 tests across 16 focused suites: queued reveal, queue drain, steering, direct sends/regeneration, resume-on-load, resumable SSE, pending chips, pending row, composer routing, receipt polling, ChatView, subagent ChatView, hover controls, autosave, prompt submission, and prompt commands.
  • Confirmed four new regression cases fail on the previous PR head: durable enqueue during handoff, accepted/refused claimed cancellation, and direct-send rejection. They pass with this fix.
  • Reproduced the browser failure for a second handoff submission at the previous head; preserved the original queue parent/epoch pair and asserted that identity in the browser test. Also reproduced wrong-sibling recovery locally before fixing exact response matching.
  • Passed scoped ESLint, Prettier, import sorting, and git diff --check.
  • Ran npx tsc --noEmit in client and compared diagnostics against untouched origin/dev using the same installed dependencies. No new diagnostics after normalizing source positions and the added translation-key union length; existing dependency/type errors prevent a clean local typecheck.
  • Strengthened e2e/specs/mock/queued-reveal.spec.ts: hold successor discovery, assert immediate rendering, enqueue another follow-up during handoff, then verify both persisted turns after reload without a synthetic focus event. Run with npx playwright test --config=e2e/playwright.config.mock.ts queued-reveal.spec.ts after preparing the build.
  • Attempted npm run lighthouse; local preparation is blocked by the installed tsdown/declaration-tool mismatch in unchanged packages/api/src/stream/jobStoreCapabilities.ts. All CI checks passed at 941d227913, including Lighthouse, client typechecking, all browser lanes, and the strengthened queued handoff test. Final-head CI verification is in progress.

Test Configuration:

  • macOS, Node v24.16.0, reused installed dependencies, Jest/jsdom.
  • Dedicated worktree based on current origin/dev, continuing this PR’s existing branch.
  • Graph orientation and base SHA verified; graph caller queries timed out and no local selector token was available. Focused test selection used source callers and lifecycle boundaries.

Checklist

  • My code adheres to this project's style guidelines
  • I have performed a self-review of my own code
  • I have commented in any complex areas of my code
  • My changes do not introduce new warnings
  • I have written tests demonstrating that my changes are effective or that my feature works
  • Local unit tests pass with my changes

@danny-avila

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 14, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-09-15T00:52:38.631265Z 15074cf Manual request
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@danny-avila
danny-avila added this pull request to stack #15945 September 14, 2026 21:37

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 698d303321

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread client/src/hooks/Chat/useQueuedTurnReveal.ts Outdated
Comment thread client/src/hooks/Chat/useQueuedTurnReveal.ts Outdated
Comment thread client/src/hooks/Chat/useQueueDrain.ts
Comment thread client/src/hooks/Chat/useQueuedTurnReveal.ts Outdated
@danny-avila
danny-avila force-pushed the danny-avila/jovial-dirac-fb60fa branch from 698d303 to f1e70cc Compare September 14, 2026 21:52
@danny-avila

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f1e70ccabf

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/api/src/agents/triggers/host.ts Outdated
Comment thread client/src/hooks/Chat/useQueuedTurnReveal.ts Outdated
Comment thread client/src/components/Chat/Input/PendingSteerChips.tsx Outdated
@danny-avila

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c16217b298

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread client/src/hooks/SSE/useResumableSSE.ts
Comment thread packages/api/src/agents/triggers/host.ts Outdated
Comment thread client/src/hooks/Chat/useQueuedTurnReveal.ts Outdated
Comment thread client/src/components/Chat/Messages/HoverButtons.tsx Outdated
@danny-avila

Copy link
Copy Markdown
Collaborator Author

@codex review

Base automatically changed from danny-avila/options-greyed-between-runs-ba264f to dev September 14, 2026 22:36
@danny-avila
danny-avila force-pushed the danny-avila/jovial-dirac-fb60fa branch from 8060953 to 7998a2b Compare September 14, 2026 22:36

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8060953278

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread packages/api/src/agents/queuedTurns.ts Outdated
Comment thread client/src/hooks/Chat/useQueuedTurnReveal.ts Outdated
Comment thread client/src/hooks/Chat/useChatFunctions.ts Outdated
Comment thread client/src/hooks/Chat/useQueuedTurnReveal.ts Outdated
@danny-avila
danny-avila force-pushed the danny-avila/jovial-dirac-fb60fa branch 2 times, most recently from 7423608 to 4ad6ea3 Compare September 14, 2026 22:45
@danny-avila

Copy link
Copy Markdown
Collaborator Author

Rebased onto dev after #15938 merged and its branch was deleted. The round-4 fixes cited as 7423608661 in the thread replies are 4ad6ea3808 on the rebased branch; the first four commits are identical to the earlier rebase.

In an agent conversation the server admits a queued follow-up on its own clock, and the client learned of that successor only through the receipt poll, the active-job poll and a resume attach, so the user's words appeared as the latest turn a second or more after the reply above them ended.

The queued follow-up is now drawn as the newest user turn the moment its predecessor completes cleanly, with its chip reduced to a remove action until the server admits it. The drawn turn is presentation intent only: it never enters the message cache, anchors no send, edit, fork or rerun, and shows only while the completed response it follows is the thread's tail. The intent ends once anything parents on that response, on a cancelled, dead or indeterminate receipt, or on the user's own removal. The composer queues behind it and the completed response offers no rerun while it stands.

The receipt poll also stays alive while the client holds a server-owned row the projection has not settled, so a successor that starts and finishes inside one active-job poll gap is no longer noticed only on the next focus.
@danny-avila
danny-avila force-pushed the danny-avila/jovial-dirac-fb60fa branch from 4ad6ea3 to d65f5d7 Compare September 14, 2026 23:15
@danny-avila

Copy link
Copy Markdown
Collaborator Author

Reworked at d65f5d7d7b (single commit on dev). The revealed follow-up is now presentation intent rendered by PendingTurn after the thread's tail, not a row in the message cache. That removes the resume-attach reconciliation, the refetch re-append, the persisted/cancelled flags, the ask guard, the edit/fork id gating, and the backend userMessageId / overrideUserMessageId hand-off; packages/api is back to dev. The intent ends when anything parents on the completed response, on a cancelled/dead/indeterminate receipt, or on the user's removal. Threads from rounds 1–4 addressed code that no longer exists; the PR body describes the design as it stands.

@danny-avila

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d65f5d7d7b

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread client/src/hooks/Chat/useQueuedTurnReveal.ts Outdated
Comment thread client/src/hooks/Chat/useSteering.ts
Comment thread client/src/hooks/Chat/useQueueDrain.ts
…xpired Rows

A revealed head that is cancelled or dies before admission leaves the server-owned queue non-empty and its terminal evidence outside the settled receipts, so nothing re-ran the drain for the row the backend moves on to; the drain now subscribes to the admissible head and the reveal itself. An uncertain row whose reconciliation window has expired is held for manual recovery only and no longer keeps the receipt poll alive.
@danny-avila

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 674c6b843f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread client/src/hooks/Chat/useSteering.ts
…Path

A transcription completing while a queued follow-up was about to start called the send path directly and could race the turn the server already owed. The form's routing (answer mode, then steer or queue during a run or a pending reveal, then an ordinary send) now lives in one function that typed and dictated submissions share; a refused during-run submit keeps the text in the composer.
@danny-avila

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e1a4dcf195

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread client/src/hooks/Chat/useSteering.ts
Comment thread client/src/components/Chat/Input/PendingSteerChips.tsx
@danny-avila

Copy link
Copy Markdown
Collaborator Author

@codex review

Please review the current PR head 19ee541. Confirm that this exact commit is the reviewed commit and ignore findings that apply only to earlier heads.

This round follows a subsystem audit of presentation versus admission ownership, durable follow-up enqueue, direct-send context preservation, cancellation, cache observation, history/attachment races, remount and expiry. Please review the complete transition across these boundaries.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 19ee541809

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread client/src/hooks/SSE/useResumeOnLoad.ts
Comment thread client/src/hooks/Chat/useSteering.ts
Comment thread client/src/hooks/Chat/useQueuedTurnReveal.ts Outdated
@danny-avila

Copy link
Copy Markdown
Collaborator Author

@codex review

Please review the current PR head 941d227. Confirm that this exact commit is the reviewed commit and ignore findings that apply only to earlier heads.

I addressed all three current findings together: retain off-screen guards while receipts are owed, advance and remember completion boundaries through consecutive admissions, and consume the autosave-selected draft key. The broader audit also fixed exact recovered response identity and the browser-reproduced queue lineage mismatch: queue parent/epoch remain immutable and separate from presentation and completion boundaries. Focused transition tests pass; CI is running.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 941d227913

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread client/src/hooks/Chat/useSteering.ts Outdated
Comment thread client/src/components/Chat/Input/ChatForm.tsx
@danny-avila

Copy link
Copy Markdown
Collaborator Author

@codex review

Please review the current PR head 15074cf. Confirm that this exact commit is the reviewed commit and ignore findings that apply only to earlier heads.

The two input findings are addressed at their shared owners: useAutoSave supplies the actual draft-consumption callback to useSteering, and submitPrompt preserves refused auto-sends in the composer for all prompt pickers, including variable dialogs and library actions. I audited the remaining submitMessage callers: URL prompts stage their text before attempting submission; conversation starters retain their clickable source. All 516 focused tests pass. All CI checks, including the expanded two-follow-up browser regression, passed at the preceding head; current-head CI is running.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep them coming!

Reviewed commit: 15074cf9b7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

…loseout

# Conflicts:
#	client/src/hooks/Chat/__tests__/useSteering.spec.tsx
#	client/src/hooks/Chat/useSteering.ts
#	client/src/hooks/SSE/useResumeOnLoad.ts
@danny-avila danny-avila changed the title ⏱️ feat: Reveal Queued Follow-Up At Run Completion 🫴 fix: Preserve Queued Follow-Ups Through Handoff Sep 15, 2026
@danny-avila
danny-avila merged commit 96cb5e7 into dev Sep 15, 2026
24 checks passed
@danny-avila
danny-avila deleted the danny-avila/jovial-dirac-fb60fa branch September 15, 2026 01:04
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