feat: add manually dispatched drafts - #3575
Merged
ymichael merged 15 commits intoSep 14, 2026
Merged
Conversation
…ollow-up-drafts-thr_934d2si9vc
…ollow-up-drafts-thr_934d2si9vc # Conflicts: # apps/app/src/views/thread-detail/ThreadDetailPromptArea.tsx # packages/db/drizzle/meta/0119_snapshot.json # packages/db/drizzle/meta/_journal.json # packages/domain/src/plugin-sdk-version.ts # packages/plugin-sdk/package.json
…ollow-up-drafts-thr_934d2si9vc # Conflicts: # apps/app/src/views/thread-detail/ThreadDetailPromptArea.tsx # packages/db/src/data/queued-thread-messages.ts # packages/domain/src/plugin-sdk-version.ts # packages/plugin-sdk/package.json
…ollow-up-drafts-thr_934d2si9vc # Conflicts: # packages/domain/src/plugin-sdk-version.ts # packages/plugin-sdk/package.json
…ollow-up-drafts-thr_934d2si9vc # Conflicts: # docs/api_to_audit.md
ymichael
deleted the
bb/prototype-adding-follow-up-drafts-thr_934d2si9vc
branch
September 14, 2026 22:41
ymichael
added a commit
that referenced
this pull request
Sep 15, 2026
## Human comments ## Before / After Both captures use the supported product journey **Fork into new thread → enter the shown prompt → Save draft… → Save draft** in the real source Chromium app. The QA threads were validated as M4 / Codex / gpt-5.6-sol / high / default / full. Assets are pinned to the separate evidence-only root commit [`722baf85893192feef86a5fccb94e3d8de74ad03`](https://github.com/get-bb/bb/tree/722baf85893192feef86a5fccb94e3d8de74ad03); PR head contains no screenshot commit. | Before — broken baseline | After — repaired | | --- | --- | | **Provenance:** baseline endpoint `054de3ae9c4d9551c845ada6549da5490af78988`, captured before source edits.<br><br>**Shown prompt:** “Fork draft before fix 054de3a — must remain queued and must not run.”<br><br>**Observed:** the fork is active (`Working…`), the prompt was accepted, provider output and command-tool work began, and the queue was empty.<br><br> | **Provenance:** repaired commit `065b5bf3ed3799efe2c2531a031878a6e78cdd74`, same source-app journey.<br><br>**Shown queued draft:** “Fork draft after fix 054de3a — must remain queued and must not run.”<br><br>**Observed:** the fork is inactive, with exactly one queued row held by **Drafts · Draft**. CLI/server evidence confirmed the inherited timeline remained at seq 5 with no matching requested or accepted provider turn and no new tool work.<br><br> | ## What was wrong The fork flow introduced in [#3575](#3575) rebuilt the new-thread submission through `buildForkThreadRequest` but omitted the composer's `pluginSubmission`. That stripped the Drafts plugin marker before the initial dispatch hook could see it, so **Save draft** displayed success while core treated the fork prompt as an ordinary message and immediately started a provider turn. Root and follow-up drafts were unaffected because those paths forwarded the submission unchanged. ## What changed `buildForkThreadRequest` now requires callers to account for `pluginSubmission` and preserves it when present. `RootComposeView` forwards the composer's value into the shared builder. The opaque plugin data still exists only during dispatch-hook processing and is not persisted in the accepted core message. No server, daemon protocol, CLI, SDK, or documentation contract changed. Added focused coverage for plugin submission on fork dispatch, an ordinary-fork control with no plugin submission, and controls proving root/new-thread and follow-up composers still forward plugin submissions. ## How you verified - Red/green fork assembler regression: 6/6 passed after the fix. - Root/new-thread and follow-up composer suites: 81/81 passed. - Drafts plugin tests: 6/6, plus typecheck. - Server dispatch-hook suite: 15/15 passed. - Turbo typechecks for `@bb/client-core` and `@bb/app` passed. - Real source Chromium journey: **Fork into new thread → Save draft** now creates an inactive fork with one exact queued draft and no accepted turn/tool work; **Send now** dispatches exactly once. - Source CLI smoke on the production worktree build: ordinary fork produced one request/acceptance, no queue or tools, and passed the M4/Codex/gpt-5.6-sol/high/default/full validator. > AGENT GENERATED
albrand
added a commit
to albrand/bb
that referenced
this pull request
Sep 17, 2026
…e merge - parity goldens: only the lines the merged bridges now emit deterministically (Claude estimated contextWindow deltas, restored cacheReadInputTokens, Codex coordination wait label); session-id churn from the replay was rejected. Claude pinned event counts follow the added deltas. - contract: the optional-field group limit is 32, covering upstream lifecycleOwnerThreadId and the fork send refusal group. - app: a plugin wait has no glyph, as upstream get-bb#3575 decided.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Human comments
What was wrong
There was no way to save a composed message into the normal queue without either sending it or pretending it was scheduled far in the future. That produced misleading schedule text and could eventually auto-send.
What changed
Adds the built-in Drafts plugin with a one-click “Save draft…” action in both new-thread and follow-up composers. The action has no modal. It submits through the composer with plugin-owned JSON, and the Drafts dispatch hook turns that submission into the existing plugin queue wait.
Plugins now run before core scheduling, busy-thread, provisioning, host, and interaction waits.
experimental_submit({ experimental_data })is generic: core validates and passes the JSON to dispatch hooks for the initial attempt but does not interpret or persist it. Later Drafts rechecks recognize the durable existingwaitingOn: { kind: "plugin", pluginId: "drafts" }queue state. Send now keeps using the existing hook bypass.There is no queued-message schema change, new draft queue type, or Drafts-specific core branch. Send Later continues to use
sendAtunchanged.How you verified
Held by Drafts · Draftwith no scheduled timeFixes #