Skip to content

fix(computer): never execute or overwrite a dead command - #111

Merged
jerelvelarde merged 9 commits into
CopilotKit:mainfrom
kvnloo:fix/computer-dead-command-guards
Oct 6, 2026
Merged

jerelvelarde merged 9 commits into
CopilotKit:mainfrom
kvnloo:fix/computer-dead-command-guards

Conversation

@kvnloo

@kvnloo kvnloo commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Problem

There are two races after a computer command row is created:

  1. If Stop quarantines the command before the executor re-checks its lease, the executor currently overwrites the existing interrupted receipt with a blind put().
  2. If Stop or lease recovery marks the command interrupted immediately after the lease check, the executor can still invoke Docker. Its final completion CAS then loses, leaving an interrupted receipt even though side effects actually ran.

That second case is particularly dangerous because it can invite a retry of side effects whose outcome is already unknown.

Change

  • Replace the stopped-before-execution blind write with a CAS on status: "running"; if another path already quarantined the row, return that receipt unchanged.
  • Re-read the command row after the lease check and return immediately if it is no longer running.

Tests

Two race regressions pin both boundaries:

  • a Stop quarantine that lands before lease re-check keeps its original "Stopped by the user" receipt and Docker is never invoked;
  • a command marked interrupted after lease validation is never executed.

No command schema, timeout, or successful execution behavior changes.

Current-main adaptation

After @jerelvelarde pointed out the computer-backend extraction, the two guards were moved onto the active backend receipt store (this.receipts) and the current session.exec path instead of the old Docker-only implementation.

The regressions now cover both Docker and the E2B desktop receipt store; a desktop command whose receipt becomes interrupted after lease validation is asserted never to dispatch.

Verification

Fresh CI on the reconciled current-main head:

  • quality: passed
  • computer-container: passed
  • browser: passed
  • iOS / Android / web platform jobs: passed
  • browser-container: failed in the unrelated worker /sessions/<id>/downloads fixture with WORKER_FAILURE.

Integration limits

The guards prevent dispatch at these two pre-execution race boundaries. They do not claim cancellation of a command already dispatched to a backend.

@jerelvelarde

Copy link
Copy Markdown
Collaborator

Reviewed head b0d3aa862095.

High-value fix: the CAS preserves a Stop/recovery receipt, and the second command-row read prevents executing a command already marked interrupted at that boundary. The regressions check both receipt preservation and absence of Docker execution. No new security or template-fit blocker found in this diff.

All seven current GitHub checks pass. Please record the check commands/results in the description. Also preserve these guards when reconciling with the computer-backend extraction in #133; an interrupted receipt must continue to mean the user should inspect before repeating the operation. This was static review; I did not rerun Docker tests.

@jerelvelarde jerelvelarde left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

The two guards are valuable and the original-head behavior is sound, but this PR cannot merge into current main: GitHub reports mergeStateStatus DIRTY / mergeable CONFLICTING in the command-execution area.

Please rebase and adapt the new CAS/fallback/post-lease reads to the extracted backend implementation. Current main stores command receipts through this.receipts (separate Docker and desktop stores) and dispatches via session.exec; the added code still hard-codes "computer-commands" and is attached to the old Docker-only executor. Preserve the two guards using the active backend's receipt store, then rerun the regressions plus desktop-backend tests so desktop commands cannot bypass the interrupted-receipt check.

Validation: all 14 tests in tests/computer.test.ts pass locally on the current PR head, including both new race regressions; root TypeScript and changed-file Biome checks pass. Existing GitHub checks are green for that old head, but cannot establish integration with the now-conflicting backend. Requesting changes for integration readiness, not a failure of the tested Docker-only fix.

kvnloo commented Oct 6, 2026

Copy link
Copy Markdown
Contributor Author

Thanks — reconciled against the extracted backend on the current head. Both guards now use this.receipts on the active session.exec path, and the regression coverage includes the E2B desktop receipt store so an interrupted desktop command cannot dispatch after lease validation. Fresh CI on 7b8a07b is green; the PR description now records verification and the remaining integration limit.

@jerelvelarde jerelvelarde left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Re-reviewed updated head: earlier backend integration blocker is resolved. Guards use active this.receipts and session.exec paths across Docker/desktop and preserve quarantined/interrupted receipts before dispatch. All 56 computer/E2B desktop tests passed, including three receipt-race regressions; current main merges cleanly. Useful command-safety fix, clear template limits, no remaining actionable security/correctness finding. Current exact-head seven CI checks are green.

@jerelvelarde
jerelvelarde merged commit e333eb6 into CopilotKit:main Oct 6, 2026
7 checks passed
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.

2 participants