Skip to content

feat(desktop): device registry, inbox and leased claims for a background executor - #8644

Merged
waleedlatif1 merged 2 commits into
stagingfrom
feat/desktop-executor-foundation
Oct 6, 2026
Merged

waleedlatif1 merged 2 commits into
stagingfrom
feat/desktop-executor-foundation

Conversation

@waleedlatif1

@waleedlatif1 waleedlatif1 commented Oct 5, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

First Phase 1 PR for the desktop background executor. It adds the server half of the protocol a Sim desktop app will use to keep running a chat's desktop tools after the user leaves the chat.

What is reused, not rewritten

  • Claim, lease and fence. The device claim is the desktop claim, claimDesktopToolCall (run-locked through claimUnderRunAdmission, so it serializes with Stop), with an executor: { deviceId, ownerToken } option. It keeps everything the desktop claim already checks (a pending call, allowed by the permission gate, under the per-surface claim owner) and adds two things:

    • the run must be bound to that device;
    • the claim takes an execution lease under ownerToken, like Sim's own executions.

    Renewal is renewSimToolExecutionLease with a desktop option (the call must still be running on the device's run, so a call Stop settled cannot be renewed). The device's result goes through markAsyncToolStatus's execution-owner fence, which gains a lease mode: lease: 'any' records a late but real result until something else settles the call.

  • One sealing and settlement path. Sealing is fix(mothership): refuse desktop claims for unapproved or stopped calls #8643's sealClientToolSettlement. The CAS-then-publish step (settleClientToolCall, with a guard that picks the CAS) is extracted from /api/copilot/confirm into request/tools/client-settlement.server.ts. Confirm and the device's complete both use it.

  • Approvals. Approvals come from fix(mothership): refuse desktop claims for unapproved or stopped calls #8643's permission_requested_at: a call is approval_needed while it is requested and undecided, and claimable once allowed. A claim before that answers 403, as /api/desktop/tool/authorize does.

  • Stop. Stop is fix(mothership): refuse desktop claims for unapproved or stopped calls #8643's sealed settlement in the Stop transaction. A device result racing it waits on the row lock and is answered superseded.

  • Classifier. The device's tools are fix(mothership): refuse desktop claims for unapproved or stopped calls #8643's lib/mothership/tools/desktop-tools.ts, which gains the name list the inbox query narrows on and the executor's claim owner.

  • Transport. createSSEStream, createPubSubChannel, isFeatureEnabled, application operations and the route builders are used as they are.

What is new

  • Data model (0397_desktop_devices, generated with drizzle-kit, expand-only):
    • desktop_devices binds an install id to a user and to the Better Auth session that registered it. ON DELETE SET NULL means signing out disconnects the device.
    • copilot_runs.desktop_device_id has an FK added NOT VALID (every existing row is NULL) and a partial index built CONCURRENTLY.
  • Presence is truthful and driven by the device:
    • Every inbox pull, lease renewal and stream open refreshes desktop:presence:<id> (45 s TTL).
    • Only the TTL removes it.
    • A stream that a deploy or rotation closes does not read as offline. A sleeping device lapses.
  • Audit. Each claim and each recorded result writes an audit entry (desktop_tool_call.claimed, desktop_tool_call.completed, resource desktop_device) with the tool name, chat and call id, never the arguments or output. A duplicate or superseded result changed nothing and is not audited.

Device contract (for Phase 2)

All routes authenticate with the cookie of the session the device registered under. Any other session gets 401.

Step Request Semantics
Register after sign-in POST /api/desktop/devices {deviceId(uuid), name, appVersion, platform, capabilities:{executor, browser, terminal, localFiles}} Returns {enabled, protocolVersion, leaseMs:60000, leaseRenewMs:20000, reconcileMs:10000}. enabled:false is the kill switch. A 409 means the id belongs to another account: generate a new one. Registering from a new session rebinds the device, and the old session gets 401.
Doorbell GET /api/desktop/inbox/stream?deviceId Sends event: inbox_changed {reason: call/approval/cancel}. Pull the inbox on each event. Reconnect on close or on rotate.
Pull GET /api/desktop/inbox?deviceId Returns {items}. Pull on connect, on each doorbell, on wake, and every reconcileMs; the pull also keeps the device online. Claim call items in list order. Notify on approval_needed. Stop the local action for each cancel, then post its result to acknowledge it.
Claim POST /api/desktop/tool/claim {deviceId, toolCallId} Returns {toolName, args, chatId, workspaceId, executionToken}. Run the call in the chat's scope (chatId) with the server's args only. 403: not approved (yet). 409: the turn ended or was stopped. 404: no longer waiting for this device. On any 4xx, drop the call.
Renew POST /api/desktop/tool/lease {deviceId, toolCallId, executionToken}, every leaseRenewMs Returns {renewed:true}. A 410 means the call was stopped, settled or lapsed: stop the action.
Complete POST /api/desktop/tool/complete {deviceId, toolCallId, executionToken, status, message?, data?} Returns {outcome: recorded / duplicate / superseded, status}. Every 200 acknowledges the outbox entry. Retry a 5xx with backoff.

Test plan

  • lib/desktop/application/executor.integration.ts (real PostgreSQL and Redis), 23 tests. They cover:
    • registration: flag off, a foreign install id, a session rebind, sign-out;
    • claim exclusivity under 8 concurrent claims;
    • a settled call is unclaimable;
    • local reads are claimed under the files surface;
    • another device or user is refused, the claim primitive itself refuses a device the run is not bound to, and unbound runs are ignored;
    • the approval gate (requested: 403; allowed: claimable; declined: never claimable);
    • lease renewal and lapse;
    • Stop through the real requestRunStop: claim refused, renewal 410, a cancel item, and a late success answered superseded;
    • completion wakes the waiting run and publishes its confirmation; a retry is duplicate; the claim and the recorded result are audited once each, without the result's content; a late result after a lapsed lease is recorded;
    • a result whose call was settled as lost is superseded;
    • a result that waits on a concurrent settlement's row lock never overwrites it (pg_blocking_pids);
    • the inbox keeps persistence order and works without a doorbell;
    • presence is refreshed by a pull and by a stream open, and survives a stream close;
    • the doorbell rings only its own device;
    • sign-out ends the stream.
  • Red before the fix: each of 15 guards was reverted in turn, and every one turns its test red (including the claim primitive's own device-binding check, the executor lease, the owner fence's lease mode, and the 403 for an unapproved call).
  • fix(mothership): refuse desktop claims for unapproved or stopped calls #8643's suites still pass on this branch: desktop-tool-authorization.integration.ts (11 tests), async-runs/*.integration.ts, and confirm's unit tests.
  • scripts/test-desktop-inbox-e2e.ts, run against a local Next.js app with PostgreSQL and Redis, passes 10/10 checks over 33 HTTP requests:
    • registration;
    • presence on stream open;
    • four calls from two background chats are claimed, renewed and completed;
    • a lost doorbell is reconciled inside the pickup window;
    • a retried result is answered as a duplicate;
    • approval listing, and a claim refused (403) before approval;
    • Stop gives a 410 and a cancel item, then the call is acknowledged;
    • another desktop is isolated;
    • sign-out gives a 401;
    • presence is left to its TTL after the stream closes.
  • The gate passes: lint, type-check, check:audits, check:migrations, docs-manifest:check, the block registry check, drizzle-kit generate (no drift), and bun run test (37,229 passed).

Notes

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cubic-dev-ai review this PR

@vercel

vercel Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated
docs Skipped Skipped Oct 6, 2026 4:51am UTC

Request Review

@cubic-dev-ai

cubic-dev-ai Bot commented Oct 5, 2026

Copy link
Copy Markdown
Contributor

@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 cubic-dev-ai Bot left a comment •

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.

All reported issues were addressed across 26 files

Re-trigger cubic

Comment thread apps/sim/lib/desktop/executor/tools.ts Outdated
Comment thread apps/sim/lib/desktop/executor/repository.ts Outdated
Comment thread packages/db/schema.ts
Comment thread apps/sim/lib/desktop/executor/inbox.ts Outdated
Comment thread apps/sim/lib/desktop/executor/constants.ts Outdated
Comment thread apps/sim/app/api/desktop/inbox/stream/route.ts
Comment thread apps/sim/scripts/test-desktop-inbox-e2e.ts Outdated
Comment thread apps/sim/lib/desktop/executor/presence.ts Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment •

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.

All reported issues were addressed across 26 files

Re-trigger cubic

Comment thread apps/sim/lib/desktop/executor/inbox.ts Outdated
Comment thread apps/sim/lib/api/contracts/desktop-executor.ts Outdated
Comment thread apps/sim/lib/desktop/executor/repository.ts
Comment thread packages/db/migrations/0397_desktop_devices.sql
Comment thread apps/sim/lib/desktop/executor/presence.ts Outdated
Comment thread apps/sim/lib/desktop/application/executor.integration.ts
Comment thread apps/sim/app/api/desktop/inbox/stream/route.ts
Comment thread apps/sim/scripts/test-desktop-inbox-e2e.ts Outdated
@greptile-apps

greptile-apps Bot commented Oct 6, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

[Critical risk] Adds new API endpoints and database schema for desktop background executor.

The PR appears safe to merge based on the reviewed changes and resolved prior findings.

Summary

This PR adds a server-side desktop executor protocol: device registration and session binding, a reconcilable inbox with SSE doorbells, leased tool claims, fenced completion, presence, audit records, and supporting schema and tests.

  • Since the previous review, the only changes are boundary annotations on two raw-fetch calls in the HTTP E2E test.
  • The previous findings are resolved or withdrawn; no new actionable issue was identified.

Reviews (13) · Last reviewed commit: "test(desktop): mark the E2E's cross-proc..."

Comment thread apps/sim/lib/desktop/executor/repository.ts Outdated
Comment thread apps/sim/lib/desktop/executor/repository.ts
Comment thread packages/db/migrations/0397_desktop_devices.sql
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cubic-dev-ai review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

@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 cubic-dev-ai Bot left a comment •

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.

All reported issues were addressed across 26 files

Fix all with cubic | Re-trigger cubic

Comment thread apps/sim/lib/desktop/executor/repository.ts Outdated
Comment thread apps/sim/lib/desktop/application/executor.integration.ts
Comment thread packages/db/migrations/0397_desktop_devices.sql
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cubic-dev-ai review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

@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 cubic-dev-ai Bot left a comment

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.

No issues found across 26 files

Confidence score: 5/5

  • Automated review surfaced no issues in the provided summaries.
  • No files require special attention.

Re-trigger cubic

Comment thread apps/sim/lib/desktop/application/executor.integration.ts Outdated
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cubic-dev-ai review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

@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 cubic-dev-ai Bot left a comment

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.

No issues found across 27 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

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cubic-dev-ai review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai review this PR

@waleedlatif1 I have started the AI code review. It will take a few minutes to complete.

@waleedlatif1
waleedlatif1 force-pushed the feat/desktop-executor-foundation branch from e0e3fb7 to 48b2051 Compare October 6, 2026 03:12
@waleedlatif1
waleedlatif1 changed the base branch from fix/desktop-tool-authorize-stop to staging October 6, 2026 03:12
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cubic-dev-ai review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

@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 cubic-dev-ai Bot left a comment •

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.

All reported issues were addressed across 33 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

Comment thread apps/sim/lib/mothership/request/tools/client-settlement.server.ts
Comment thread apps/sim/lib/mothership/request/tools/client-settlement.server.ts
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cubic-dev-ai review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

@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 cubic-dev-ai Bot left a comment

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.

No issues found across 33 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

…und executor

Adds the server half of the desktop background executor's device protocol,
behind the mothership-desktop-background-executor flag (off by default),
built on the existing tool-execution primitives rather than new ones:

- desktop_devices binds an install id to a user and the Better Auth session
  that registered it; copilot_runs.desktop_device_id records which device a
  turn's desktop tools run on (nothing sets it yet).
- Claims, renewals and results reuse claimDesktopToolCall,
  renewSimToolExecutionLease and the execution-owner fence. A background
  executor's claim is the desktop claim plus an execution lease, only on a
  run bound to that device; a result is accepted after its lease lapsed
  until something else settles the call.
- /api/copilot/confirm and the device's complete share one sealing and
  settlement function, so a device result is sealed, settled and published
  exactly like a chat view's.
- POST /api/desktop/devices registers; GET /api/desktop/inbox lists calls,
  approval_needed items (from permission_requested_at) and cancel items;
  GET /api/desktop/inbox/stream is an SSE doorbell over Redis pub/sub.
- Presence is driven by the device: every pull, lease renewal and stream
  open refreshes a 45 s key, and only its TTL removes it.
@waleedlatif1
waleedlatif1 force-pushed the feat/desktop-executor-foundation branch from 1fe23de to 4cebfa2 Compare October 6, 2026 04:41
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cubic-dev-ai review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

@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 cubic-dev-ai Bot left a comment •

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.

All reported issues were addressed across 33 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

Comment thread apps/sim/lib/desktop/application/executor.integration.ts
Comment thread apps/sim/scripts/test-desktop-inbox-e2e.ts
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cubic-dev-ai review this PR

@cubic-dev-ai

cubic-dev-ai Bot commented Oct 6, 2026

Copy link
Copy Markdown
Contributor

@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 cubic-dev-ai Bot left a comment

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.

No issues found across 33 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

@waleedlatif1
waleedlatif1 merged commit ba12945 into staging Oct 6, 2026
36 checks passed
@waleedlatif1
waleedlatif1 deleted the feat/desktop-executor-foundation branch October 6, 2026 16:48

This branch was previously deployed

1 inactive deployment
Preview — 438588d4 Deployed Oct 6, 2026 by vercel[bot]
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