Skip to content

fix(native-chat): main's draft-queue tests follow #23524's /clear (fixes main) - #23940

Merged
brennanb2025 merged 1 commit into
mainfrom
brennanb2025/clear-queue-gate-after-23524
Sep 29, 2026
Merged

brennanb2025 merged 1 commit into
mainfrom
brennanb2025/clear-queue-gate-after-23524

Conversation

@brennanb2025

@brennanb2025 brennanb2025 commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor
Files Added Deleted Net
Test 3 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​9 $\color{#cf222e}{\Huge{\mathbf{−}}}$​33 $\color{#cf222e}{\Huge{\mathbf{−}}}$​24
Prod 3 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​7 $\color{#cf222e}{\Huge{\mathbf{−}}}$​8 $\color{#cf222e}{\Huge{\mathbf{−}}}$​1

ELI5

Main's unit tests and typecheck broke because two changes merged minutes apart disagreed. #23524 made an unfinished /clear count as never having happened, so it no longer blocks sending. #23726, which added the queue for messages typed while the agent is working, had three tests that still expected an unfinished /clear to hold that queue, plus one line that no longer typechecked. This brings #23726's tests and that line in line with #23524.

What Changed

Why

Linked Issue

Fixes main after #23524 and #23726.

Visual Proof

N/A: this changes tests, one type-level line and comments. Behaviour is unchanged from main's already-merged #23524.

Testing

  • The three test files, plus structured-conversation-command.test.ts and structured-agent-session-send-block.test.ts: 5 files, 76 tests pass.

  • tc:node passes, where it fails on main.

  • oxlint passes on the changed files.

  • Ablation: with the send check blocking an unfinished /clear again, the two "holds nothing" tests fail.

  • I manually tested these changes locally

  • Automated tests added/updated, or explained why not below

AI Disclosure

Review

Agent skill upstream boundary

  • Not applicable, or this change follows docs/reference/agent-skill-sharing-upstream-boundary.md and copies or mechanically translates no upstream skill-installer source, tests, fixtures, registry entries, path tables, comments, or documentation.

Notes

Host-side tests and one type-level line; no platform, SSH, mobile or wire effect.

Checklist

  • This PR is small and focused
  • I explained what changed and why (ELI5, the user-facing before/after, the mechanism, and why over the alternatives)
  • Before/after screenshots or videos attached for UI changes, or N/A with reason
  • Self-reviewed for correctness, security, and performance
  • Cross-platform, SSH/remote, and path/shortcut impact considered (or N/A)
  • pnpm lint, pnpm typecheck, pnpm test, and pnpm build pass (or CI will cover; local preferred)

…hed clear holds nothing

#23726 and #23524 merged minutes apart. #23726's queue gate takes its "blocked"
answer from the shared send check, which #23524 changed: a /clear that never
committed changed nothing the chat reads, so it refuses no send. Three #23726
tests still seeded a "prepared" /clear record and expected it to hold the queue,
and the /clear carry passed a possibly-undefined replacement id where #23726's
helper takes a string, so main failed its unit tests and tc:node.

The gate code already follows the new rule; the tests now say it: a /clear an
older build left prepared holds no draft and Send-now sends it, and a send made
while a /clear is starting its replacement is still told to wait. The carry reads
the replacement id from the ids it already checked.
@brennanb2025

Copy link
Copy Markdown
Contributor Author

Agreed, from the queue side. I checked it against my own fix for the same breakage, #23939, which I'm closing in favour of this one. The type fix and the three test rewrites match mine.

One thing to keep in view: on main the /clear hand-over of queued messages still runs before the clear is saved. Under #23524 a clear that never saved "never happened", so if that save fails the messages have already left the chat the user is still in. That's harmless today, because the queue isn't advertised yet. #23935 moves the hand-over after commitConversationClear, which fixes it. So #23935 needs to land before the queue is switched on.

A narrow gap remains even then: a crash between the clear's save and the hand-over leaves the messages hidden on the cleared chat, and nothing moves them later. I'll follow up with a re-carry: a cleared chat that still holds queued messages hands them over again. The hand-over is already idempotent.

@greptile-apps

greptile-apps Bot commented Sep 29, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 4/5

[Medium risk] Adjusts draft-queue behavior during session clear operations.

The PR appears safe to merge; the remaining issue is a misleading test-suite description.

Findings

  1. P2 Stale queue gate description ▶

Summary

The PR updates draft-queue tests to match the existing prepared-/clear send rule, corrects related comments, and uses the already-derived replacement session ID when carrying drafts. One suite description remains stale.

Reviews (1) · Last reviewed commit: "fix(native-chat): the draft queue follow..."

describe('the one queue gate', () => {
it('Send-now refuses while a clear is in doubt, with the refusal any send gets', async () => {
const working = await workingSend()
it('a clear an older build left prepared holds nothing: Send-now sends the draft', async () => {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Stale queue gate description The suite’s opening comment still says a “clear in doubt” holds the queue, but this rewritten test expects Send-now to succeed with a prepared clear. That contradiction could mislead someone updating the gate or its tests; please update the suite description to match the new expectation.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

✅ No new issues found.

Reviewed changes

  • Fixed the three stale draft-queue tests — structured-agent-session-queued-gate.test.ts now seeds an older build's prepared /clear and expects Send-now to proceed (ok: true) with the draft handed off; structured-agent-session-queued-messages.test.ts drains a draft held behind a prepared clear once the turn settles; both reflect #23524's rule that an unfinished clear changed nothing the chat reads.
  • Updated the in-flight clear test — structured-agent-session-queued-command.test.ts now waits on the replacement attach call (a live signal) instead of the prepared record #23524 no longer writes, while still asserting WAIT_REFUSAL for a send during an in-flight clear. The unused HOST_TEST_SESSION as SESSION import was dropped.
  • Type fix in structured-conversation-command.ts — the carry call reads ids.sessionId (narrowed to string inside if (ids)) instead of the optional replacementSessionId; the two are the same value there, so behavior is unchanged.
  • Stale comments corrected in structured-agent-session-queued-messages.ts and structured-agent-session-queued-mutations.ts.

I verified the changed tests pin real behavior rather than passing vacuously: with the send check made to block an unfinished clear again, the Send-now sends the draft and drains when the turn settles tests would fail. Ran the 5 named files (76 pass), pnpm tc:node, oxlint, and oxfmt --check — all clean. A full agent-session-wire/ run passed 1108 tests with one unrelated failure (structured-agent-session-wedged-profile-migration.test.ts:498 times out on base 29c49aec as well, so it is pre-existing and out of scope).

Pullfrog  | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

@coderabbitai

coderabbitai Bot commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

📝 Walkthrough

Walkthrough

Tests now expect Send-now to accept a queued draft and hand it off when the working turn settles while a prepared, unknown clear remains. The in-flight clear test waits for the mocked attach call. Comments describe queue holds and replaying idempotent carry inserts. The carry call uses ids.sessionId for the replacement session and journal lookup.

Priority: ⬇️ Low

Merge Risk: 🔵 Low · up to cabdd

The runtime behavior is not shown to change, but two updated tests could miss regressions in queued-draft hand-off timing and /clear persistence. The PR is mergeable with these focused lifecycle assertions restored.

Architecture Summary

Architecture risk: 🔵 Low · up to cabdd

The change affects 1 system.

Changed systems: src

Architecture concerns
No architecture-level concerns identified.

Review details

Systems and components

  • observed — src (service) was modified; 6 changed files map to changed impact.

Before / after behavior

  • observed — Modified behavior in src/main/native-chat/agent-session-wire/structured-agent-session-queued-command.test.ts: Removed the HOST_TEST_SESSION import alias.
  • observed — Modified behavior in src/main/native-chat/agent-session-wire/structured-agent-session-queued-command.test.ts: The in-flight /clear test now waits for the mocked attach call rather than asserting that the stored command reached the prepared phase with a replacement session ID.
  • observed — Modified behavior in src/main/native-chat/agent-session-wire/structured-agent-session-queued-gate.test.ts: The test no longer retains the active send’s handle for later settlement; its title and comment describe an unfinished /clear as not changing what the chat reads.
  • observed — Modified behavior in src/main/native-chat/agent-session-wire/structured-agent-session-queued-gate.test.ts: The test now expects Send-now to succeed and waits for the queued draft’s hand-off, replacing the previous refusal expectation and check that no hand-off occurred after settling the active send.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 2 functions across 6 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the native-chat draft-queue test updates and their alignment with the /clear behavior from #23524.
Description check ✅ Passed The description is detailed and covers the required explanation, changes, rationale, testing, visual proof, scope, and checklist items. It reports test and typecheck results, although the linked issue…
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.
  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
src/main/native-chat/agent-session-wire/structured-agent-session-queued-gate.test.ts (1)

44-51: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Assert handedOverAt after settling the active send.

workingSend() leaves the active submission unsettled. sendNow() records the queued submission immediately, but rig.handoff() checks only the queued-message link. The current assertion can therefore pass before delivery hands the draft over.

Suggested fix
-    await workingSend()
+    const working = await workingSend()
...
     expect(await sendNow(draftId)).toMatchObject({ ok: true })
-    await eventually(async () => expect(await rig.handoff(draftId)).toBeDefined())
+    expect((await rig.handoff(draftId))?.handedOverAt).toBeUndefined()
+    await settleAccepted(working, 'a')
+    await eventually(async () =>
+      expect((await rig.handoff(draftId))?.handedOverAt).toBeDefined()
+    )
src/main/native-chat/agent-session-wire/structured-agent-session-queued-command.test.ts (1)

112-113: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Assert the committed clear record after releasing attach.

The attach spy only synchronizes with the controller's in-memory pending gate. The send assertion can pass before the clear record is committed. The final assertions can also pass if setConversationCommand is skipped after attach, because they check only the returned replacement ID and draft lists. Assert the committed record to retain coverage of the clear lifecycle.

Suggested fix
 import {
+  HOST_TEST_SESSION as SESSION,
   HOST_TEST_THREAD as THREAD,
   hostTestMessage,
   hostTestOperationId
 } from './structured-agent-session-host-test-data'
@@
       }
       expect(await rig.drafts()).toHaveLength(0)
       expect(await rig.drafts(replacementId)).toHaveLength(0)
+      expect(rig.store.getRecord(SESSION)?.conversationCommand).toMatchObject({
+        command: 'clear',
+        phase: 'committed',
+        state: 'completed',
+        replacementSessionId
+      })
     } finally {

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: 736ed5fa-0ea4-484b-a3c5-54158e9d2217

📥 Commits

Reviewing files that changed from the base of the PR and between 29c49ae and cabdd75.

📒 Files selected for processing (6)
  • src/main/native-chat/agent-session-wire/structured-agent-session-queued-command.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-queued-gate.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-queued-messages.test.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-queued-messages.ts
  • src/main/native-chat/agent-session-wire/structured-agent-session-queued-mutations.ts
  • src/main/native-chat/agent-session-wire/structured-conversation-command.ts

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

@brennanb2025
brennanb2025 merged commit a57863b into main Sep 29, 2026
35 checks passed
brennanb2025 added a commit that referenced this pull request Sep 29, 2026
Brings in #23940, which fixed on main the same three #23726 queue tests
this branch had adapted. Resolution:
- The two tests where an older build's unfinished /clear holds nothing
  take main's version.
- The in-flight /clear test keeps this branch's version: it holds the one
  store write, because a /clear no longer starts the new conversation's
  agent, so holding that start would never engage.
- The draft carry keeps this branch's shape: it runs after the commit and
  opens the new conversation, under its own lock, only when there are
  drafts to carry.
brennanb2025 added a commit that referenced this pull request Sep 29, 2026
…3789, #23812, #23852) into brennanb2025/codex-home-single-writer

#23744 moves every agent's folder pre-trust into the PTY spawn hook (and
the structured Codex chat create), removing Codex's launch-prep and
resume-prep trust writes. markCodexProjectTrusted now takes the config
files to write.

Conflicts:
- agent-trust-presets.ts: #23744's configFiles signature and nested lane
  acquisition, with this branch's lane rationale (hook installs read and
  rewrite across awaits); main's "capture->restore window" wording
  described the grant snapshot this branch removed.
- agent-trust-write-deadline.ts: the Codex writer waits only on
  managed-home installs' inline grant; the real-home background approval
  holds no lane. #23744's SSH/SFTP writer is gone, so it is no longer
  named; its 1.5 s short deadline is kept.
- codex-trust-config-concurrent-launch.test.ts: this branch's tests
  (a launch's write lands while a grant session runs; the renamed
  sibling-failure case) with #23744's new call signature.

Outside the conflicts: codex-launch-during-real-home-grant.test.ts passed
launchAgent/workspacePath into launch prep, which #23744 removed; its
launch helper now runs launch prep and then applyAgentWorkspaceTrust, as
the spawn builder does, so it still proves a launch and its project trust
land while the real-home approval hangs.
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