Skip to content

Refuse to send into a busy thread unless the caller injects - #9

Merged
MajesteitBart merged 1 commit into
mainfrom
t3code/send-if-busy
Oct 2, 2026
Merged

MajesteitBart merged 1 commit into
mainfrom
t3code/send-if-busy

Conversation

@MajesteitBart

Copy link
Copy Markdown
Owner

Adds the busy-thread guard that @jarekbird proposed in #2 to the merged threads send.

Changes

  • --if-busy reject|inject: reject is the default. It refuses with THREAD_BUSY (exit code 4) and dispatches nothing while a turn runs or an earlier message still waits for its turn. error.details says which, with the session and latest-turn state.
  • inject: sends into the running turn, as send did before. The provider then folds the message into that turn or queues it, and --wait follows either way.
  • New settings: send with new settings is still refused mid-turn, even with inject, because new settings can't reach a running turn.
  • Docs: README, t3thread, and use-t3code-cli updated. The busy check is a snapshot, not a lock, as Add threads send with configurable busy-thread injection #2 also noted.

Testing

pnpm check passes with 166 tests. Checked live against T3 0.0.45-nightly. A second send during a just-started turn returned THREAD_BUSY with "has a message waiting for its turn", and then "is running a turn" once the turn ran. Neither message reached the thread.

threads send gains --if-busy reject|inject, as proposed in #2 by
@jarekbird. reject is the default: send refuses with THREAD_BUSY and
dispatches nothing while a turn runs or an earlier message waits for
its turn. inject sends into the running turn, as send did before.
@clark-review

clark-review Bot commented Oct 2, 2026 •

Copy link
Copy Markdown

Mira PR Walkthrough

This PR makes threads send reject busy threads by default with THREAD_BUSY and exit code 4, without dispatching a message. Callers can explicitly choose --if-busy inject to preserve the previous behavior, but new settings remain prohibited during a running turn. It also adds tests and documents that the busy check is a snapshot rather than a lock.

graph LR
  cli["src/cli.ts"] --> controls["src/threadControls.ts"]
  cli --> service["src/service.ts"]
  service --> controls
  threadsTests["src/threads.test.ts"] --> service
  cliTests["tests/cli.test.mjs"] --> cli
Loading
Confidence: 4/5   ◉◉◉◉○   Likely safe to merge
  • The focused scope, reported 166 passing tests, and live verification support confidence, though the supplied metadata cannot establish implementation correctness or coverage of snapshot races.

⚠️ Potential overlap with other open PRs — these may be stepping on this one:

  • #2 (duplicate effort + merge-conflict risk) — Both implement the same busy-thread reject/inject behavior for threads send and modify its shared CLI and service code. Shared: README.md, src/cli.ts, src/service.ts

8 files reviewed


Comment @clark-review help to get the list of available commands and usage tips.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 2, 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-10-02T18:48:19.982890Z d099cd0 PR opened
🔒 Security Review ✅ Completed 2026-10-02T18:49:03.195919Z d099cd0 PR opened
ℹ️ 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.

@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: d099cd07a8

ℹ️ 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 src/service.ts
Comment on lines +543 to +544
const busy = busyState(thread);
if (busy && (options.ifBusy ?? "reject") === "reject") {

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 Badge Restrict injection to an actively running turn

When the thread has queued messages but no running turn, busy is non-null with turnRunning: false, yet --if-busy inject bypasses this guard and dispatches another turn-start command. There is no running turn to inject into in that state, so this silently adds more queued work despite the option being documented as steering a running turn; queued-only threads should remain rejected until the existing message starts or finishes.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Keeping this as is. inject means "send anyway", as #2 defined it ("sends immediately even when busy"). The queued-only state also occurs right after every send: in the live check, a second send hit "has a message waiting for its turn" before the first turn started. Rejecting inject there would make it fail unpredictably at the start of every turn. In that state T3 accepts the message, and the provider folds it into the starting turn or queues it, which --wait follows. reject stays the default, so nothing is added unless the caller asks for it.

@MajesteitBart
MajesteitBart merged commit f735716 into main Oct 2, 2026
4 checks passed
@MajesteitBart
MajesteitBart deleted the t3code/send-if-busy branch October 2, 2026 18:50
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