Skip to content

fix(server): integrate launch retry keys with current main - #22446

Open
zainmitchell wants to merge 12 commits into
pingdotgg:t3code/peer/launch-request-keyfrom
zainmitchell:contribution/21671-reviewed-conflict-fix
Open

zainmitchell wants to merge 12 commits into
pingdotgg:t3code/peer/launch-request-keyfrom
zainmitchell:contribution/21671-reviewed-conflict-fix

Conversation

@zainmitchell

@zainmitchell zainmitchell commented Oct 20, 2026 •

Copy link
Copy Markdown

Summary

Integrate the active launch-request-key branch #16654 with the updated mode-limit layer and pinned main c22ace223a4911c770500bc591fa6f21015a219c. A retry with an accepted clientRequestId reuses the launch before mutable base-ref or default-model checks, while still enforcing worktree membership and caller limits.

accepted request key: reuse launch and original preparation
new request key: validate and create launch

This preserves the author's active design and ports Julius's reviewed fixes from the closed #21671 replacement. The docs now describe same-MCP-session replay and tell callers without a key to inspect existing threads before retrying. This updates the existing support PR rather than creating a replacement.

Scope and approval

Maintenance of #16654 and fixes already present in this support PR. Original design and implementation credit stays with @juliusmarminge. Maintainer feature acceptance, vouching and workflow approval remain separate requirements.

Evidence

  • Builder launch/MCP checks at this layer: 140/140 passed. Server, contracts and provider-core typechecks passed; scoped format/lint passed with upstream warnings only.
  • Parent review confirmed the accepted-launch receipt, project ownership, worktree membership and preparation paths. Independent combined-stack validation at 820e789c: 223 focused tests passed, plus server/contracts typechecks.
  • In the fresh two-machine run, a remote launch replay after peer restart returned the same thread and run. The top PR records all 8 runtime checks and their limits.

Merge Danger

Door: Two-way for the code change.

Blast Radius: Launches. Retry keys are scoped to an MCP session, not every future session of the same caller. The integration includes the lower layer and pinned main; no removed upstream test fixtures were restored.

Original implementation and retry fixes: Julius Marminge. Integration: Claude Opus 5.5 High through T3 Code. Independent review and runtime verification: GPT-6.1-Sol through Codex in T3 Code.

input.files.map(async (relativePath) => {
const result = await executeAtomQuery(
appAtomRegistry,
projectEnvironment.readFile({

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.

🟠 High lib/addProjectToMachine.ts:148

Selecting an ignored binary file always produces a failed copy: projectEnvironment.readFile rejects files containing NUL bytes, and this read failure is recorded in failed instead of transferring the file. Use a binary-safe transfer path or exclude unsupported files before offering them in the dialog.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/web/src/lib/addProjectToMachine.ts around line 148:

Selecting an ignored binary file always produces a failed copy: `projectEnvironment.readFile` rejects files containing NUL bytes, and this read failure is recorded in `failed` instead of transferring the file. Use a binary-safe transfer path or exclude unsupported files before offering them in the dialog.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

This file is imported unchanged from main by the support merge. Git blob 367420c45e0f526f7ee6a878bb008abc59c8ee2f is identical at this PR's head ec2eba74, incorporated main f7f9e217, and main 5d4c202e (upstream source). It is outside both the launch-retry layer and the combined mode-limit/launch feature changes.

I am preserving the upstream file to keep this PR focused on integrating the existing stack. This comparison does not reproduce or dismiss the reported bug. Maintainer review of the merge remains required.

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.

Sorry, I'm unable to act on this request because you do not have permissions within this repository.

@@ -0,0 +1,10 @@
!macro customInstall
!ifndef DO_NOT_CREATE_START_MENU_SHORTCUT
${IfNot} ${FileExists} "$newStartMenuLink"

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.

🟡 Medium resources/installer.nsh:3

When $keepShortcuts is true, this recreates a Start Menu shortcut the user deliberately deleted on every update: customInstall treats the missing link as needing repair after the installer preserves its absence. Gate shortcut creation on $keepShortcuts so the user's choice is honored.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/desktop/resources/installer.nsh around line 3:

When `$keepShortcuts` is true, this recreates a Start Menu shortcut the user deliberately deleted on every update: `customInstall` treats the missing link as needing repair after the installer preserves its absence. Gate shortcut creation on `$keepShortcuts` so the user's choice is honored.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

This file is imported unchanged from main by the support merge. Git blob 092f641c3359fb58bf2232132e9bd4ef0491ac56 is identical at this PR's head ec2eba74, incorporated main f7f9e217, and main 5d4c202e (upstream source). It is outside both the launch-retry layer and the combined mode-limit/launch feature changes.

I am preserving the upstream file to keep this PR focused on integrating the existing stack. This comparison does not reproduce or dismiss the reported bug. Maintainer review of the merge remains required.

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.

Sorry, I'm unable to act on this request because you do not have permissions within this repository.

const scaledHeightDifference = previous
? (previous.height - current.height) * current.scale
: 0;
if (Math.abs(current.height - win.innerHeight / current.scale) <= 1) {

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.

🟠 High lib/softwareKeyboard.ts:48

On Firefox Android, opening the keyboard sets viewportOpen to false, so plain Enter can submit instead of preserving multiline input and the post-send keyboard blur is skipped. Firefox resizes both viewports together, making current.height equal win.innerHeight / current.scale here; navigator.virtualKeyboard is unsupported there, and the initial subscription check has the same limitation. Track keyboard visibility from a signal that does not require the layout and visual viewports to differ.

🤖 Copy this AI Prompt to have your agent fix this:
In file @apps/web/src/lib/softwareKeyboard.ts around line 48:

On Firefox Android, opening the keyboard sets `viewportOpen` to `false`, so plain Enter can submit instead of preserving multiline input and the post-send keyboard blur is skipped. Firefox resizes both viewports together, making `current.height` equal `win.innerHeight / current.scale` here; `navigator.virtualKeyboard` is unsupported there, and the initial subscription check has the same limitation. Track keyboard visibility from a signal that does not require the layout and visual viewports to differ.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

This file is imported unchanged from main by the support merge. Git blob e20d5fe00b4aa539792e0ee4a2d06658fc41c2cc is identical at this PR's head ec2eba74, incorporated main f7f9e217, and main 5d4c202e (upstream source). It is outside both the launch-retry layer and the combined mode-limit/launch feature changes.

I am preserving the upstream file to keep this PR focused on integrating the existing stack. This comparison does not reproduce or dismiss the reported bug. Maintainer review of the merge remains required.

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.

Sorry, I'm unable to act on this request because you do not have permissions within this repository.

@macroscopeapp

macroscopeapp Bot commented Oct 20, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Needs Human Approval

Macroscope's review found this PR requires human approval — Despite the launch-retry title, the base-to-head tree is a 1,703-file merge containing production server orchestration, authentication, desktop/mobile/web behavior, release workflows, and Macroscope/static-analysis configuration changes. The unresolved High/Medium runtime findings further support keeping this change set with human reviewers.

Needs human approval because:

  • 3 blocking correctness issues found at or above your repo's Minimum Blocking Severity

Adjust the Minimum Blocking Severity for this repo — including turning it Off — in Settings. You can add or adjust custom eligibility rules. Learn more.

juliusmarminge and others added 9 commits October 20, 2026 16:06
An OAuth client on /mcp is capped by the access it was approved with.
When another environment calls on behalf of one of its agents, that agent
may run under narrower modes, and the target has no way to know.

/mcp now reads `T3-Mode-Limit: <runtimeMode>/<interactionMode>` from OAuth
clients and caps the request at the narrower of the two. The header can
only narrow: a broader one changes nothing, and a malformed one is
refused with 400. The client's interaction mode can now be capped too;
before, it was always default.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A launch had no retry key, so an agent (or another environment calling on
its behalf) that lost the response could only guess whether the thread
was created, and a retry started a second one.

t3_thread_launch now takes an optional clientRequestId. The command,
thread and message ids derive from the caller and the key, and the launch
service already replays a command it accepted, so a retry returns the
first thread. Without a key every launch is new, as before.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Integrates upstream main c22ace2 (v0.1.1) into the retained catch-up
merge 4fbb8de. Clean merge; the mode-limit feature delta against main is
unchanged.
The launch section said launch has no retry key, but t3_thread_launch
accepts clientRequestId and replays the first accepted launch for the
same key within the caller's MCP session.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 452eb16)
@zainmitchell
zainmitchell force-pushed the contribution/21671-reviewed-conflict-fix branch from 452eb16 to 9621c64 Compare October 21, 2026 04:01
@zainmitchell zainmitchell changed the title fix(server): integrate the resolved parent into keyed launch retries fix(server): integrate launch retry keys with current main Oct 21, 2026
@zainmitchell
zainmitchell changed the base branch from takeover/ssh-relay-remote-15-launch-retry to t3code/peer/launch-request-key October 21, 2026 04:02
@zainmitchell

Copy link
Copy Markdown
Author

Additional combined-stack runtime evidence is recorded on #22448: the reviewed integration was deployed on two Windows PCs with Nightly 3486, existing peer links reconnected after both server restarts, and native agent send/wait/read completed successfully across both machines.

These results cover the combined Nightly integration, not this standalone PR head. This PR's code and target branch are unchanged. Exact source revisions, focused checks, model/harness attribution and verification limits are in the linked report. Maintainer direction/scope approval and review remain separate requirements.

@gitcafe-production
gitcafe-production Bot force-pushed the t3code/peer/launch-request-key branch 2 times, most recently from 88ec543 to 3b46b4c Compare October 22, 2026 04:36
A launch had no retry key, so an agent (or another environment calling on
its behalf) that lost the response could only guess whether the thread
was created, and a retry started a second one.

t3_thread_launch now takes an optional clientRequestId. The command,
thread and message ids derive from the caller and the key, and the launch
service already replays a command it accepted, so a retry returns the
first thread. Without a key every launch is new, as before.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@gitcafe-production
gitcafe-production Bot force-pushed the t3code/peer/launch-request-key branch from 3b46b4c to 1aa278b Compare October 22, 2026 04:55
Resolve the receipt-replay conflict in Orchestrator.ts by keeping the
mode-ceiling check for replayed deferred launches and the target's
queued-run.start replay. Drop a duplicate clientRequestId replay test that
both sides added at different positions in handlers.test.ts. The target's
launched-model lookup and this branch's accepted-launch lookup both stay:
an accepted receipt still decides the replayed model first.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@zainmitchell

Copy link
Copy Markdown
Author

Conflict refresh: cdb82b0

Merged the current target t3code/peer/launch-request-key at 1aa278ba2891974d3f1afd8ef83e16d0b55ad5cf into this PR as cdb82b078323f080ae220384dcb5743f70935ca4. The original PR head 9621c645 remains its first parent; no history rewrite or retargeting.

The resolution retains the receipt-validated launch retry and mode-ceiling recheck, upstream's new original-model lookup and selected queued-run replay, and the new upstream regression test. One byte-identical duplicate replay test was removed.

Validation on upstream's required Node 26.12.1: 113 focused tests passed across six files; server typecheck and scoped format/lint passed, with only inherited lint warnings. Independent parent verification passed 15 launch-handler/peer-link tests on the #22447 candidate; the launch handler and orchestrator files are byte-identical between these two refreshed candidates. The parent command was vp test run apps/server/src/mcp/toolkits/project/handlers.test.ts apps/server/src/peer/PeerLinks.test.ts.

The earlier two-machine runtime evidence remains evidence for its explicitly named older commits. It was not repeated on this new head. Maintainer scope approval and CI remain separate requirements.

Resolution: Claude Opus 5.5 High through T3 Code. Independent source review and focused verification: GPT-6.1-Sol through Codex in T3 Code.

@github-actions github-actions Bot added size:L 100-499 changed lines (additions + deletions). and removed size:XXL 1,000+ changed lines (additions + deletions). labels Oct 22, 2026
@gitcafe-production
gitcafe-production Bot force-pushed the t3code/peer/launch-request-key branch from 1aa278b to 071e661 Compare October 22, 2026 05:56
The target's launch commit now skips new-launch checks when a retry finds
its thread. Keep that for the worktree base ref and project defaults, and
also skip the base ref for an accepted receipt as before. Keep checking
existing-worktree membership on every launch: a retry may bind a workspace
to an idle accepted launch, and this branch's tests require the refusal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@zainmitchell

Copy link
Copy Markdown
Author

Launch-retry conflict refresh: 6d84a1e

Merged the amended target 071e6616495613844a1ff062446e41b4fc586d22 into the published head as 6d84a1e536c1418ea0ff459806e4bd08a5a0b606, preserving both parents. The target changed launch-retry behavior; this was not just a rebase.

Intentional resolution: retained Julius's earlier fix a615bda90 / 1fdb652e: an existing_worktree request must still pass project membership validation on a retry. An idle accepted launch can receive its first message and bind a workspace on that retry. Restoring upstream's new skip makes the existing regression test create a preparing run for an outside path instead of refusing it. Trade-off: a removed or unregistered existing worktree can cause a retry to be refused. This differs from the target's new unconditional replay skip and remains a maintainer review point.

Upstream's new base-ref retry behavior and regression test are kept: a retry still succeeds after its original base ref disappears. Model precedence and the receipt-validated replay remain unchanged.

Node 26.12.1 validation: 114 focused tests and server typecheck passed; scoped lint/format passed with two inherited warnings. Independently, the parent ran both named behavior tests on the combined #22448 candidate: the membership guard and deleted-base replay both passed. There is no new two-machine runtime claim for these heads.

Resolution: Claude Opus 5.5 High through T3 Code. Independent source review and targeted verification: GPT-6.1-Sol through Codex in T3 Code. Maintainer scope approval and CI remain separate requirements.

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:L 100-499 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