fix(cloud): live Vercel Pro findings (bundle download, rehearsal cap) + results (#16)

* fix(cloud): provision bundle download no longer overwrites its source; shortened session deadline for staging rehearsals

* docs(cloud): live Vercel Pro results
This commit is contained in:
Neil
2026-11-09 02:19:23 -08:00
committed by Neil
parent a91ae681f5
commit a4d6079510
6 changed files with 34 additions and 8 deletions
@@ -28,9 +28,10 @@ fetch_verified() { # url sha256 dest
}
log 'orcad bundle'
fetch_verified "$ORCAD_BUNDLE_URL" "$ORCAD_BUNDLE_SHA256" /tmp/orcad.tgz
tar -xzf /tmp/orcad.tgz -C "$ORCA_HOME/runtime"
rm -f /tmp/orcad.tgz
bundle="$(mktemp -d)/orcad.tgz"
fetch_verified "$ORCAD_BUNDLE_URL" "$ORCAD_BUNDLE_SHA256" "$bundle"
tar -xzf "$bundle" -C "$ORCA_HOME/runtime"
rm -rf "$(dirname "$bundle")"
test -s "$ORCA_HOME/runtime/orcad/orcad-server.js"
node="$(find "$ORCA_HOME/runtime/runtimes" -type f -name node | head -n 1)"
test -x "$node"
+2
View File
@@ -30,4 +30,6 @@ export type Env = {
/** Public URL of this Worker's /v1/egress/proxy; Vercel forwardURL rules point here. */
EGRESS_PROXY_URL?: string
/** Shortened session deadline (ms) for staging rollover rehearsals; refused when SANDBOX_ENV=prod. */
SESSION_DEADLINE_MS?: string
}
+3 -1
View File
@@ -77,7 +77,9 @@ function lifecycleDeps(env: Env, deps: Deps): LifecycleDeps | null {
environment: env.SANDBOX_ENV,
goldenSnapshotId: env.GOLDEN_SNAPSHOT_ID,
defaultRegion: env.VERCEL_REGION ?? 'iad1',
egressProxyUrl: env.EGRESS_PROXY_URL
egressProxyUrl: env.EGRESS_PROXY_URL,
sessionDeadlineMs:
env.SESSION_DEADLINE_MS && env.SANDBOX_ENV !== 'prod' ? Number(env.SESSION_DEADLINE_MS) : undefined
}
}
}
+6 -3
View File
@@ -35,6 +35,8 @@ export type LifecycleDeps = {
goldenSnapshotId: string
defaultRegion: string
egressProxyUrl?: string
/** Staging rehearsals shorten the cap; production uses SESSION_DEADLINE_MS. */
sessionDeadlineMs?: number
}
}
@@ -80,12 +82,13 @@ function egressPolicy(deps: LifecycleDeps, row: SandboxRow) {
return compileNetworkPolicy({ mode: 'allowlist', credentials })
}
export function sessionFields(state: ProviderSandboxState, now: number): SessionFields {
export function sessionFields(deps: LifecycleDeps, state: ProviderSandboxState): SessionFields {
const now = deps.now()
const startedAt = state.session.startedAt ?? now
return {
session_id: state.session.id,
session_started_at: startedAt,
session_deadline_at: startedAt + SESSION_DEADLINE_MS,
session_deadline_at: startedAt + (deps.config.sessionDeadlineMs ?? SESSION_DEADLINE_MS),
lease_expires_at: startedAt + state.session.timeoutMs,
usage_settled_at: startedAt
}
@@ -116,7 +119,7 @@ async function boot(deps: LifecycleDeps, row: SandboxRow, state: ProviderSandbox
repo,
githubPlaceholder: deps.config.egressProxyUrl ? githubPlaceholderToken(row) : undefined
})
const running = await claim(deps, row, { status: 'running', last_error: null, ...sessionFields(state, deps.now()) })
const running = await claim(deps, row, { status: 'running', last_error: null, ...sessionFields(deps, state) })
return { row: running, connection }
}
+1 -1
View File
@@ -85,7 +85,7 @@ async function reconcileRunning(deps: LifecycleDeps, row: SandboxRow, summary: R
async function repairTransition(deps: LifecycleDeps, row: SandboxRow): Promise<void> {
const state = await deps.provider.getSandbox(row.provider_name, { resume: false })
if (state?.session.status === 'running') {
await transition(deps.db, row, { status: 'running', ...sessionFields(state, deps.now()) }, deps.now())
await transition(deps.db, row, { status: 'running', ...sessionFields(deps, state) }, deps.now())
return
}
await markProviderStopped(deps, row)
+18
View File
@@ -162,6 +162,24 @@ Compiled per sandbox by `compileNetworkPolicy()`:
recipe adapter; start one scheduler per ready hosted runtime (stop on suspend/destroy); an orcad RPC exposing
the idle-probe verdict + last PTY input for `readActivity`; header warning + mobile push for `warn`.
## Live results (2026-11-09, Vercel Pro team `lovecast`, project `orca-sandbox-control`, iad1)
Driven by the real Worker handler in-process (real Vercel REST, node:sqlite D1, stub billing) and the real desktop
driver/scheduler. Base OS is Amazon Linux 2023 (dnf), not Ubuntu.
- Golden image: orcad built from public stablyai/orca@7c14832 in a 8 vCPU build sandbox in 98s (67 MB tgz);
provision 14.3s (gh 2.103.3, Claude Code 2.1.319, Codex 0.166.0; orcad loopback smoke passed); wipe ok;
snapshot 8.2s. Bug found and fixed: provision downloaded the bundle over its own source path.
- Snapshot → orcad ready (`POST /v1/sandboxes`, incl. Vercel create + orca-sandbox-start): 5.4 / 4.1 / 4.9 s; WS open.
- Suspend (drain + stop) 7.6s; resume → ready 6.0s; same endpoint and same orcad host key (no re-pair).
- Shortened cap (6 min): scheduler warned T−15, then forced rollover at the deadline in 17.3s (drain, stop, boot,
orcad ready), reconnect WS open, new deadline set. Destroy 0.4–0.7s; zero sandboxes/snapshots left.
- Egress: allowlist resolves npm (200), `example.com` does not resolve (curl rc 6). Policy update 0.25s.
Placeholder → injected fake GitHub credential reaches GitHub (curl/gh `token` scheme: 401 Bad credentials);
attacker token and placeholder-less git → 403 `orca-egress-denied`. Node fetch under a transform rule still hangs
on Pro; `orca-egress-probe` reports `egress_framing_hang` (npm, untransformed: ok). No real GitHub token was used,
so a successful authenticated push is still unverified.
- Not covered live: forwardURL egress proxy (needs a deployed Worker URL), agent auto-resume with a real chat.
## What needs live access (not done)
Vercel Pro team id + project id + a Sandbox-scoped token (as Worker secrets), wrangler auth for a dev D1, a