feat: Use stable sandbox create keys#159
Conversation
✅ No Blockers —
|
tangletools
left a comment
There was a problem hiding this comment.
✅ Clean — a35858d1
Full multi-shot audit completed 1/1 planned shots over 2 changed files. Global verifier still owns final merge decision.
Full immutable report for this review: trace
Summary comment for this run: full summary
tangletools · 2026-06-30T16:25:14Z · immutable trace
tangletools
left a comment
There was a problem hiding this comment.
🟢 Value Audit — sound
| Verdict | sound |
| Concerns | 0 (none) |
| Heuristic | 0.0s |
| Duplication | 0.0s |
| Interrogation | 77.0s (2 bridge agents) |
| Total | 77.0s |
💰 Value — sound
One-liner passes the already-computed stable box name as the SDK's idempotencyKey, making workspace sandbox creates safe across retries and recreate-after-delete paths.
- What it does: Adds
idempotencyKey: nameto theclient.create(payload)call inensureWorkspaceSandbox(src/sandbox/index.ts:1384).nameis computed earlier at src/sandbox/index.ts:1242 as eithershell.boxKey(scope)(per-user) orshell.name(workspaceId)(per-workspace) — both already deterministic. The field is a real SDK parameter sinceCreatePayload = Parameters<Sandbox['create']>[0](src/sandbox/ - Goals it achieves: Make sandbox creation idempotent per workspace identity so that (a) an orchestrator retry after a transient create failure doesn't mint a duplicate box, and (b) the box's identity stays stable across recreate-after-delete, which keeps downstream references — notably workspace snapshot
fromSandboxIdinshell.restore— valid. Coherent with the existing architecture, which already keys box identi - Assessment: Good change on its merits. It uses the single natural stable identifier the code already computes (
name) and threads it into the SDK field designed exactly for this purpose. The change is minimal, correctly placed at the single create call, typed via the SDK's own parameter type (no shape drift), and covers both the default workspace-name and customboxKeyidentities — verified by the two new - Better / existing approach: none — this is the right approach. Searched for prior idempotency handling:
rg idempotencyreturns only the two new lines;CreatePayloadis the SDK's own type so the field is the SDK's intended seam. The stablenameis already the unique-per-workspace key computed at src/sandbox/index.ts:1242, so deriving the idempotency key from anything else would be strictly worse. No existing equivalent - Model: opencode/zai-coding-plan/glm-5.2
- Bridge attempts: 2
- Bridge warning: opencode/kimi-for-coding/k2p7: bridge stream ended without value-audit content
🎯 Usefulness — sound
One-line addition sends a deterministic idempotencyKey (the box name) on sandbox create so retries and recreate-after-delete collapse to the same backend box.
- Integration: Reachable and live: ensureWorkspaceSandbox is the central sandbox lifecycle entry (src/sandbox/index.ts:1233), called from src/sandbox/workspace-terminal.ts and exercised by tests/sandbox.test.ts. The idempotencyKey is added to the existing create payload (src/sandbox/index.ts:1384) typed as CreatePayload = Parameters<Sandbox['create']>[0] (src/sandbox/index.ts:971), so it flows straight into the
- Fit with existing patterns: Fits the established pattern precisely. The whole reuse strategy is already name-keyed: listRunning(client, name) at :1247, stopped-box match by name at :1223, and name is derived at :1242 from either shell.boxKey(scope) or shell.name(workspaceId) — both deterministic per identity. Making the backend dedupe key equal to the client lookup key is the same grain, not a competing one. grep found no pr
- Real-world viability: Holds up across the paths the PR targets. name is stable for a given workspace (default) or workspace+user (custom boxKey), so retries after a network blip or timeout, and a fresh create after a delete, all carry the same key and collapse correctly. Concurrency: two simultaneous creates with the same name are exactly what the backend dedupe should catch, and different names are different boxes by
- Model: opencode/zai-coding-plan/glm-5.2
- Bridge attempts: 1
No concerns — sound change, no better or existing approach found. ✅
What this audit checks
It judges the change on its merits — not whether it was tasked out in an issue. Unticketed, fast-moving work is fine; the question is whether the change is good and whether a better or existing approach should be used instead.
| Pass | What it asks |
|---|---|
| Heuristic | Vague title? Whitespace-only or cruft-bearing diff? (content signals only) |
| Duplication | Do added function/class names already exist elsewhere in the repo? |
| Value Audit | What does it do? What goal does it achieve? Is it good? Better architecture or already-exists? |
| Usefulness Audit | Does it integrate and fit? Will it hold up in real use and actually get used? |
Findings are concerns, not blocks — the human reviewer decides what to do with them.
Summary
idempotencyKeyfrom the resolved workspace box key/nameboxKeyidentitiesValidation
pnpm exec vitest run src/sandbox/index.test.tspnpm typecheckReview Guide
src/sandbox/index.ts: create payload now carries deterministic idempotency only; running/stopped reuse logic unchanged.src/sandbox/index.test.ts: asserts stable idempotency for normal names and custom box keys.Release note
fromSandboxIdstays stable.