Repository navigation
fix(mothership): refuse desktop claims for unapproved or stopped calls - #8643
Conversation
|
@cubic-dev-ai review this PR |
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
|
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
The desktop authorize route claimed any pending call, so a gated terminal run that was still awaiting approval, or a call on a run the user had stopped, could be claimed and executed. The claim now locks the run row and refuses once tool admission has closed (Stop, a newer turn, or the run's end), and refuses a call held for the user's decision until they allow it. Whether a call is gated depends on the turn, so pre-persist records it on the row (permission_requested_at). Stop now settles the stopped runs' open desktop calls in the transaction that closes admission: unclaimed calls as never started, claimed calls as outcome unknown. A result for an already-settled call (a retry, or one that lost to Stop) is acknowledged with the stored outcome instead of 404/500.
…0 after it Stop also settles delivered desktop calls and reads of granted local folders. Authorize checks admission before the call's status, so a call Stop already settled answers 410 rather than 404.
…r, sealed Stop results The desktop claim is now an option of the run-locked tool execution claim (claimSimToolExecution becomes claimToolExecution) instead of a second copy of the admission check. Stop picks the open desktop calls with the shared TS classifier, which moves to lib/mothership/tools/desktop-tools.ts, instead of a SQL restatement of it, and seals each result the way the confirm route does, so a waiter restores what Stop did rather than failing to unseal it.
8e796d1 to
2c923ff
Compare
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
All reported issues were addressed across 25 files
You've manually re-run cubic several times on this PR. Each manual re-review checks the full PR again and counts toward your usage quota. To preserve your usage limits, we recommend letting cubic automatically review new commits.
Fix all with cubic | Re-trigger cubic
…arker Calls gated before permission_requested_at existed carry no marker, so a recorded decision that does not allow the call now disqualifies it too.
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
|
@cubic-dev-ai review this PR |
@waleedlatif1 I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
No issues found across 25 files
Confidence score: 5/5
- Automated review surfaced no issues in the provided summaries.
- No files require special attention.
You've manually re-run cubic several times on this PR. Each manual re-review checks the full PR again and counts toward your usage quota. To preserve your usage limits, we recommend letting cubic automatically review new commits.
Re-trigger cubic
Summary
/api/desktop/tool/authorizeno longer hands a call to the desktop app when it should not run:permission_requested_at, nullable, expand-only migration 0395).claimSimToolExecutionbecomesclaimToolExecution, which takes either a Sim owner token (the existing leased claim, unchanged) or a desktop claim owner. Both lock the run row and check admission the same way, so a desktop claim serializes with Stop. There is no second copy of that logic.notStarted); a claimed one as outcome unknown (outcomeUnknown,doNotRetry).lib/mothership/tools/desktop-tools.ts, now the single "is this a desktop tool" module), not a SQL copy of it./api/copilot/confirmseals a client result (the sharedsealClientToolSettlement), so a waiter still listening restores what Stop did./api/copilot/confirmacknowledges a result for an already-settled call with the stored outcome (200), instead of 404 (native) or 500 (other client tools). That covers a retried delivery and a late result after Stop or a server-side settlement. Nothing is written or published again, and the renderer stops retrying.response.okon authorize, and an import refusal maps as before.A terminal command already running when Stop lands keeps running on the desktop. There is no cancel channel for it in the current IPC, so that is left to the desktop executor work.
Type of Change
Testing
desktop-tool-authorization.integration.ts(real Postgres + Redis, production pre-persist, authorize, tool-permission, Stop and confirm paths): 11 tests. Onstagingthey fail with 200 instead of 403/410, claims succeed after Stop, the waiter never wakes, a late result revives a stopped call, and duplicate results get 404/500. The Stop wake-up test runs with sealed provenance: with an unsealed Stop result it restores only a generic "Tool cancelled".bun run lint,bun run type-check,bun run check:audits,bun run check:migrations,bun run test,bun run test:integration(1438 passed),bun run docs-manifest:check, block-registry check: all pass.drizzle-kit generateproduces no new migration.Checklist
test-auditauthoring gate)