π Fix workspace lifecycle contracts - #13
Conversation
Disable implicit host workspace access and require explicit roots. Keep failed sandboxes visible and workspace-scoped until destruction. Preserve retained workspace deadlines when sandbox creation fails.
Revalidate registered host workspaces against current allowed roots. Keep retained workspaces out of trash while a sandbox is unfinished.
Start managed workspace retention only after its final unfinished sandbox is destroyed.
Leverframe reviewπ’ Incremental review completed in 311s
Changes |
There was a problem hiding this comment.
Leverframe review
Found one concurrency defect. Verification used the repository-declared Node 24/pnpm 11.23.0 environment: Node v24.20.0, pnpm 11.23.0, TypeScript 5.9.3, and Vitest 4.1.11. The normal quality gate passed; real Docker Sandboxes E2E remained unavailable because sbx is not installed.
Findings
1 finding was published inline.
Checks
5 passed Β· 1 failed Β· 0 not run
Show 6 checks
| Status | Check | Evidence |
|---|---|---|
| π’ passed | pnpm install --frozen-lockfile |
pnpm 11.23.0 verified the 552-entry lockfile and installed 464 packages on Node v24.20.0. |
| π’ passed | pnpm check |
Formatting, oxlint/eslint, TypeScript typecheck, 64 unit/integration tests across 13 files, and the production build passed. |
| π’ passed | pnpm exec vitest run --project integration test/integration/sandbox-service.test.ts test/integration/workspace-service.test.ts && pnpm exec vitest run --project unit test/unit/config.test.ts |
All changed focused suites passed: 24 integration tests and 6 configuration unit tests. |
| π’ passed | pnpm exec vitest run --project integration test/integration/review-unhealthy-race.test.ts |
A temporary focused regression test reproduced the concurrent false-reuse behavior; the temporary test file was removed afterward. |
| π’ passed | git diff --check a7693b08bcc9765cf41fc11fdaac861f1f9151b3...5bb8fe4f9d9c1af878871a58e1c835c9780bd878 |
No whitespace errors were reported. |
| π΄ failed | pnpm test:e2e |
The suite stopped at its prerequisite check with spawnSync sbx ENOENT; no E2E behavior executed. |
Limitations
- Real E2E verification was unavailable because the required Docker Sandboxes
sbxexecutable and plugin are absent. Docker Engine 29.7.2 is available, but the repository provides no container or wrapper substitute forsbx.
Record an unhealthy sandbox as failed before waiting for runtime cleanup so concurrent creation cannot return it as reusable.
There was a problem hiding this comment.
Leverframe review
Reviewed the complete incremental diff using Node v24.20.0 and pnpm 11.23.0, matching CI's Node 24 and the packageManager declaration. Repository checks passed, but a focused concurrency test reproduced one new active-limit defect.
Findings
1 finding was published inline.
Checks
3 passed Β· 1 failed Β· 0 not run
Show 4 checks
| Status | Check | Evidence |
|---|---|---|
| π’ passed | node --version && pnpm --version |
Node v24.20.0 and pnpm 11.23.0. |
| π’ passed | pnpm check |
Formatting, Oxlint, ESLint, TypeScript typecheck, 65 unit/integration tests across 13 files, and the Node 24 build all passed. |
| π΄ failed | pnpm exec vitest run --project integration test/integration/review-active-limit-race.test.ts |
Temporary focused review test: expected Active sandbox limit reached while removal was blocked, but a second sandbox was created. The temporary test was removed afterward and the worktree was clean. |
| π’ passed | git diff --check 5bb8fe4f9d9c1af878871a58e1c835c9780bd878...fc4558b20c7c2111a2f230a1f44f285207d98563 |
No whitespace errors. |
Keep unhealthy sandboxes in destroying state until runtime cleanup finishes so resource limits and restart reconciliation remain accurate.
There was a problem hiding this comment.
Leverframe review
Reviewed both incremental changed files using the repository-declared Node 24 and pnpm 11.23.0 environment (actual versions Node v24.20.0, pnpm 11.23.0). The patch fixes both previously reported live-process races, but introduces one limited restart-window lifecycle defect.
Findings
1 finding was published inline.
Checks
4 passed Β· 1 failed Β· 0 not run
Show 5 checks
| Status | Check | Evidence |
|---|---|---|
| π’ passed | pnpm install --frozen-lockfile |
Installed the frozen pnpm lockfile with pnpm 11.23.0; 464 packages were installed and supply-chain policy verification passed. |
| π’ passed | pnpm exec vitest run --project integration test/integration/sandbox-service.test.ts -t 'an unhealthy sandbox cannot be reused while its runtime is being removed' |
Vitest 4.1.11: 1 test passed, confirming both active-limit and same-workspace reuse races are fixed. |
| π’ passed | pnpm check |
Formatting, oxlint/eslint, TypeScript 5.9.3 typecheck, all 65 unit/integration tests, and the Node 24 production build passed. |
| π΄ failed | temporary focused Vitest: interrupted unhealthy cleanup remains failed after restart |
Focused diagnostic reproduced the defect: expected failed, received destroyed. The temporary test was removed afterward and git status/diff checks confirmed a clean worktree. |
| π’ passed | pnpm exec vitest run --project integration test/integration/sandbox-service.test.ts -t 'an unhealthy sandbox cannot be reused while its runtime is being removed|an unavailable runtime becomes an explicit failed sandbox without automatic restart|a controller restart invalidates runtimes' |
Three relevant lifecycle tests passed after removal of the temporary diagnostic test. |
Limitations
- Real sandbox E2E tests were unavailable because the repository-required
sbxexecutable and template are not installed. The changed service/database state-machine behavior was exercised at the repository's integration boundary.
Mark an unhealthy sandbox failed before removing its runtime, while counting cleanup-pending failures against the active sandbox limit. Reconciliation now completes pending cleanup without discarding the failure record that requires explicit destruction.
Keep failed creations active until their partially created runtime is confirmed removed. Preserve cleanup failures for restart reconciliation and document the active sandbox count consistently.
Hold the existing per-sandbox lock from creation through success or failure cleanup so concurrent destruction cannot be overwritten by the creator. Document and test both creation interleavings.
Summary
cloneordirectworkspaces can be selected, removing the host-specific implicit default.Verification
pnpm checkβ formatting, linting, type checking, 64 unit/integration tests, and the production build passedpnpm test:e2eβ the real Docker Sandbox lifecycle, managed/clone/direct workspace behavior, Bash sessions, and port exposure passedNotes
Host workspaces are now disabled unless
CHAT2SBX_ALLOWED_HOST_ROOTSis explicitly configured. Existing registrations remain stored and become usable again when their paths are allowed. This change does not add automatic retries, restarts, replacement, or failed-record cleanup.