Skip to content

Convert the ca-sandbox docker boundary to an async, cancellable runner (#394 AC-3) #479

Description

@SUaDtL

Split out of #394, which delivered the bounded and typed halves. This is the remaining acceptance criterion:

AC-3: Cancellation can interrupt an active Docker call and still executes bounded teardown.

Why it could not ship with #394

spawnSync is by construction uninterruptible. A deadline can be set on it — that is what #394 did, and a hung sandbox exec now terminates and stops the container it targeted — but nothing can interrupt the call once it is in flight. There is no point at which an AbortSignal could be observed, because the calling thread is blocked inside the syscall.

Shipping a deadline that looks cancellable and is not would be worse than the honest gap, so #394 stated it rather than implying it.

What the change actually is

Convert the single docker chokepoint (plugins/ca-sandbox/tools/docker.ts) from spawnSync to an async spawn-based runner that accepts an AbortSignal, then thread await through every consumer:

  • build.ts, claude-inside.ts, cli.ts, cp.ts, create.ts, destroy.ts, exec.ts, registry.ts, run.ts

The dockerRun injection seam every command module already exposes makes the test surface tractable — the fakes become async — but the ripple through the CLI dispatch is the bulk of the work, and the CLI's synchronous exit-code contract has to be preserved exactly.

Acceptance criteria

  • AC-1: an in-flight docker call aborts when its signal fires, rather than running to completion or to its deadline.
  • AC-2: an aborted call still executes the same bounded teardown a timeout does — for exec, the container it targeted is stopped.
  • AC-3: the CLI's observable contract is unchanged: same exit codes, same stdout JSON, same stderr diagnostics.
  • AC-4: the existing per-operation deadlines from Bound every sandbox Docker invocation and terminate timed-out execs #394 continue to apply, and a timeout is still typed distinctly from an abort.
  • AC-5: covered on every OS where Docker is available, through the existing docker-gate layer discipline.

Relevant sources

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions