mirror of
https://github.com/stablyai/orca.git
synced 2026-09-21 16:02:20 +00:00
fix(mobile): name a create's launch so a lost reply cannot build two workspaces (#21137)
* fix(mobile): name a create's launch so a lost reply cannot build two workspaces `agent.launch` admits a caller-supplied `operationId` through a durable ledger, so exactly one execution happens and every replay returns the recorded answer. No client sent one, so the machinery was inert and the original defect was still live: mobile retries a lost create by design, and a retried launch built a second agent in a second workspace. Mobile now mints an operation id per create candidate and sends it whenever the host advertises `agent.launch.replay.v1`. The invariant is one operation per candidate. `computeAgentLaunchFingerprint` folds `target` whole, so the workspace name is inside the fingerprint; carrying one id across a name-collision bump would meet its own row under a differing fingerprint and refuse `agent_session_operation_conflict`, failing the create outright on the second candidate. The id is therefore minted beside `clientMutationId` at the top of each loop iteration and reused verbatim by every retry arm inside that candidate — never re-minted, since a new id is a new operation. Admission runs ahead of every effect, so `_invalid` / `_expired` / `_capacity` prove nothing launched: those re-send the same candidate unnamed rather than let bookkeeping fail a create the host would have performed. `_unknown` is the one refusal that is not safe to re-send, and it surfaces. Also corrects a false comment: the legacy path caches the whole launch under `clientMutationId`, so inside its 60s window a replay adds neither a workspace nor a surface, and outside it adds both — not "a second surface, never a second workspace". * fix(mobile): preserve launch identity on refusals * fix(mobile): use launch receipts to authorize replay * test: move mobile launch replay coverage outside node project * fix(mobile): enforce replay-safe launch delivery at the host * test: run mobile launch contracts in mobile checks * test: cover mobile launch contract workflow dependencies
This commit is contained in:
@@ -9,6 +9,18 @@ on:
|
||||
- ready_for_review
|
||||
paths:
|
||||
- 'mobile/**'
|
||||
# Mobile launch contracts exercise the real host dispatcher and durable receipt store.
|
||||
- 'src/main/agent-launch/**'
|
||||
- 'src/main/runtime/rpc/**'
|
||||
- 'src/main/runtime/runtime-rpc/**'
|
||||
- 'src/main/runtime/runtime-rpc.ts'
|
||||
- 'src/main/runtime/device-registry.ts'
|
||||
- 'src/main/runtime/orca-runtime.ts'
|
||||
- 'src/main/runtime/agent-session-*.ts'
|
||||
- 'src/main/native-chat/agent-session-wire/**'
|
||||
- 'src/shared/agent-launch-*.ts'
|
||||
- 'src/shared/agent-session-*.ts'
|
||||
- 'src/shared/new-workspace/worktree-create-collision.ts'
|
||||
# Why: the mobile terminal link parsers are conformance-tested against
|
||||
# these shared fixtures; desktop-side fixture edits must re-run this suite.
|
||||
- 'src/shared/terminal-file-link-conformance.ts'
|
||||
@@ -21,11 +33,6 @@ on:
|
||||
# schema edit anywhere under here changes mobile's types, so a desktop-only
|
||||
# change can break mobile's typecheck with no other mobile signal.
|
||||
- 'src/shared/rpc-contract/**'
|
||||
# Why: the catalog above holds params only. This file is the sole holder of
|
||||
# the agent.launch RESULT shape, and mobile imports it as a value, not just
|
||||
# a type. CROSS_VERSION_WIRE_PREFIXES already treats it as wire-critical, so
|
||||
# without this one gate classes it that way while this one cannot see it.
|
||||
- 'src/shared/agent-launch-intent.ts'
|
||||
# Why: this job holds the only checks that load the Fastfile, so edits to
|
||||
# it or to the release workflow it guards must re-run them.
|
||||
- '.github/workflows/mobile.yml'
|
||||
|
||||
Reference in New Issue
Block a user