Skip to content

fix(server): held agent messages no longer block settling - #24891

Open
mkantautas wants to merge 5 commits into
pingdotgg:mainfrom
mkantautas:fix/settle-held-queue
Open

mkantautas wants to merge 5 commits into
pingdotgg:mainfrom
mkantautas:fix/settle-held-queue

Conversation

@mkantautas

@mkantautas mkantautas commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Problem

A failed or stopped thread can refuse to settle even when every held message came from another agent or a scheduled task. I hit this with 14 held automatic messages: the server reported that a queued message must be sent or removed. The settle guard only recognized notification and delegated-completion envelopes as automatic; ordinary MCP agent messages and scheduled prompts fell through to the human-message guard.

Change

Recognize non-user authors and scheduled-task provenance as automatic messages too, then use the existing cancellation path when settling. A queued human instruction still blocks settlement, including when automatic messages are beside it; rejecting settlement preserves the whole queue.

Scope and approval

This is a focused fix for the incomplete automatic-message classification in the existing settle workflow. It extends the cancellation already applied to automatic notifications and delegated completions, without adding a recovery workflow or changing the active-run and pending-request guards. It qualifies for the small obvious-bug exception.

Verification

  • Extended the existing held-queue lifecycle regression to cover an MCP agent message, a scheduled prompt created with user provenance, a system message, and a mixed human/agent queue.
  • Negative control on main at 3d00499: the regression fails with has a queued message. With the fix it passes: automatic runs are cancelled and the thread settles; a human queue rejects settlement without cancelling either queued run.
  • current head fca88e640c: blacksmith vp run check:changed refs/remotes/github/main passed formatting, lint, knip, graphql, affected-package typechecks, and 131 tests. all 29 PR checks are green.
  • Earlier settle-related suite run: 133 tests passed across five files. No client rendering changes or live-install validation.

Written with Claude Opus 5.5 in Claude Code and GPT-6 Astra in the Codex harness, through T3 Code.

runtime verification at c205a62259, with identical server/web/contracts/client-runtime trees on the final head, used the web client, devReplay adapter, and actual CLI/MCP messages. a held agent queue settles and cancels; a mixed human queue remains unchanged until the human message is removed. recording cuts from rejection to the loaded settled state after removal. native clients, paid providers, and remote connections were not exercised in this pass.

mixed human queue blocks settle; automatic queue cancels after human removal

merge fixup and verification by gpt-6.1-sol in the codex harness.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:XS 0-9 changed lines (additions + deletions). labels Oct 25, 2026
@macroscopeapp

macroscopeapp Bot commented Oct 25, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 7fafbe1

Macroscope's review found this PR approvable — This is a narrow server-side bug fix that extends the existing settlement cancellation path to held agent, system, and scheduled messages. Human-queued messages remain blocking, with regression coverage for both automatic-only and mixed queues.

You can add or adjust custom eligibility rules. Learn more.

@coderabbitai

coderabbitai Bot commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

Explain Change →

No actionable comments were generated in the recent review.

Walkthrough

Settlement now classifies more queued messages as automatic. The existing settlement handling cancels queued runs that match this classification. Tests cover automatic messages and verify that queued user and agent messages remain when settlement is rejected.

Changes: Queued message settlement

Layer / File(s) Summary
Automatic message classification and settlement tests
apps/server/src/orchestration-v2/Orchestrator.ts, apps/server/src/orchestration-v2/runtimeLayer.test.ts
Messages not created by users or with a scheduled-task ID now qualify as automatic alongside messages with notification or delegated-completion data. Tests cover notification, agent, scheduled, system, and user messages. They also check that rejected settlement leaves the thread unsettled and preserves queued message IDs.

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Possibly related issues

Possibly related PRs

  • pingdotgg/t3code#30582: Changes the same thread.settle branch and defines a different predicate for automatic queued messages.
  • pingdotgg/t3code#27221: Releases held queued runs for non-user messages and scheduled tasks, which overlap with the messages classified as automatic during settlement here.

Suggested labels: bugfix

Suggested reviewers: juliusmarminge, t3dotgg, yash-singh1

Merge Risk: Minimal · up to c205a

Held automatic agent and scheduled messages no longer prevent a stopped or failed thread from settling, while queued human messages still block it. Automatic settlement may also cancel held agent runs, which fits the intended behavior but is worth confirming. No concrete merge-blocking risk remains.

Pre-merge checks: Passed 4
Check name Status Explanation
Title check Passed The title clearly and concisely describes the main server fix: held agent messages no longer prevent thread settlement.
Linked Issues check Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check Passed Check skipped because no linked issues were found for this pull request.
Description check Passed The description states the problem (held automatic messages from non-user authors and scheduled tasks block settling), the change (classify non-user and scheduled-provenance messages as automatic and …
Full details: Description check

Explanation

The description states the problem (held automatic messages from non-user authors and scheduled tasks block settling), the change (classify non-user and scheduled-provenance messages as automatic and reuse the cancellation path), and a scope/approval argument invoking the small obvious-bug exception. It also gives detailed verification: a negative control on main, targeted test results, a broader check run, and a runtime verification with a recording. It deviates from the template in a few places. The title is not a conventional commit in the template's sense, though the PR objectives give 'fix(server): held agent messages no longer block settling'. The scope section does not link an issue or discussion, and it relies on the small-fix exception instead. The author also explains why the change qualifies, which the template allows. The verification section is thorough and states what was not checked. The model and harness are named at the end, as the template requests. Overall the description is mostly complete and addresses every required section.

Finishing Touches
Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
Recent review info
Run configuration
Commits

Reviewing files that changed from the base of the PR and between 7fafbe1 and c205a62.

Files selected for processing: 2
  • apps/server/src/orchestration-v2/Orchestrator.ts
  • apps/server/src/orchestration-v2/runtimeLayer.test.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 3 remain after this review.

maria-rcks commented Oct 26, 2026 •

Copy link
Copy Markdown
Collaborator

Note

Written by gpt-6.1-sol on behalf of Maria

kept @mkantautas's implementation and commit, merged current main (04a21bb1c1ce), and simplified the regression's nested provenance branches into a lookup table. the production fix remains the original two provenance conditions; human queues, running work and approvals keep their existing guards.

verification at 790a82a50ab509684e478542ed5736eeed868c9c:

  • the regression fails with current main's settlement guard, with the expected queued-message error.
  • blacksmith: all 89 runtime-layer tests pass; vp run check:changed passes format, lint, both knip checks, graphql, affected typechecks and 102 tests across three files.
  • github checks on this head are green. two independent gpt-6.1-sol source reviews found no blocking issues; the existing bot review has no actionable findings.
  • chrome: the same held scheduled-provenance message blocks settle with main's guard, then settles through the real sidebar action with this fix. a client-authored human message still blocks settlement. screenshots use matching thread data.

unverified: live provider delivery through MCP and an actual scheduler trigger, native clients and remote/tunnel connections. the runtime regression exercises persisted agent, system and scheduled provenance through the real sqlite projections; the browser setup dispatches scheduled provenance directly and interrupts before provider start.

@mkantautas one nonblocking semantics note: editing an automatic queued message retains its original provenance, so settle still cancels it. this follows the existing origin-based model; no extra actor tracking was added here.

before: held scheduled message blocks settlement

after: the same thread is settled and its queue is cancelled

sidebar settle cancels the held scheduled message

maria-rcks commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator

Note

Written by gpt-6.1-sol on behalf of Maria

Verified in a real dev environment

Verified head fca88e640cdd11c09af4ba1d7f4a10a849c5b99a on Linux with the real dev web client, Playwright from the repo, /usr/bin/google-chrome, and Codex gpt-6.1-sol through the local proxy. No replay provider, mocks, fixtures, or direct state writes. Created the project and turns through the app; sent automatic messages through the actual CLI/MCP path.

  • Reproduced on github/main at 8b44f42b14: start Codex running sleep 180, queue an agent message with thread send, stop in the UI, then settle. Settlement rejects with has a queued message; the agent message stays queued.
  • Stopped main's server before starting the exact PR head. With the same app-created thread/data, the sidebar settle action succeeds and cancels the held agent run. Screenshots below show matching data.
  • Un-settle works and the same thread starts another real Codex turn on the PR head.
  • Queue a human instruction with Ctrl-click in the composer and an agent message through CLI/MCP, then stop. Settle rejects and preserves both messages. Remove only the human message, then settle: the agent run is cancelled and the thread settles.
  • Read-only persisted-state inspection confirms queued automatic runs were cancelled without starting. The human run was cancelled by removal before the remaining agent run was cancelled by settlement.
  • Blacksmith: vp test run apps/server/src/orchestration-v2/runtimeLayer.test.ts -t 'settles past held automatic messages' passes (1 focused regression). GitHub's current checks pass or are skipped; no code changes were needed.

Short command transcript (IDs shortened):

thread send --base-dir /home/user/main/.t3 <thread> 'automatic held queue probe' --json
  status=queued delivery=queued run=ordinal:2
main: thread show --json
  model=gpt-6.1-sol status=queued settled=false
PR, after UI settle: thread show --json
  model=gpt-6.1-sol status=cancelled settled=true
PR, mixed queue: UI settle rejects; both queued messages remain
PR, remove human then settle: thread show --json
  status=cancelled settled=true
persisted automatic runs ordinal:2 and ordinal:4
  status=cancelled queueHeld=true startedAt=null

main: held agent message blocks settlement

PR: the same thread settles and its held agent queue is cancelled

mixed queue rejection, human removal, and settled result

The short recording removes navigation/loading frames between settlement and reopening the thread. Uploaded playback and seeking were checked.

Not verified

Native desktop shell, iOS/Android, remote/relay/tunnel connections, other providers, actual scheduled-task firing, and separately generated system messages were not exercised. Scheduled/system classification is covered by the focused runtime regression, not by a live scheduler run in this pass.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XS 0-9 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants