Conversation
Meter Vercel sandbox allocations through the control Durable Object: admit an unmeasured interval before createSandbox, arm a durable continuation, pin the measurement cursor to the create-response createdAt, and settle through the heartbeat tick after the allocation stops. - vercel-provider: remove admission from create(), persist the create-response createdAt and terminal timestamps into the generation binding, and share the alive/terminal status classifier. - admission: accept an unmeasured context only without pendingStop and with a committed start ack; clear the context only on a definite rejection. Gate a fresh create on a predecessor generation's settlement; make uncertain admission retryable across the control boundary. - alarm: run the settlement-only path when the runtime is gone, rearm the continuation before returning, respect retryNotBefore, reconcile orphan continuations, and feed billingDueAt into composeControlAlarmAt. - meter: clip a reported segment at the interval's receipt time and recover a missing interval from the stop context.
c5edb06 to
c58f0ce
Compare
Code Review SummaryStatus: No Issues Found | Recommendation: Merge The incremental commit defers the billing continuation while a settlement delivery is in flight and fixes the Files Reviewed (4 files)
Previous Review Summary (commit a993b11)Current summary above is authoritative. Previous snapshots are kept for context only. Previous review (commit a993b11)Status: 2 Issues Found | Recommendation: Address before merge Executive SummaryThe Vercel billing wiring is well covered by tests; the main risk is a tight alarm loop in Overview
Issue Details (click to expand)WARNING
SUGGESTION
Files Reviewed (14 files)
Reviewed by deepseek-v4.1-flash · Input: 0 · Output: 0 · Cached: 0 Review guidance: REVIEW.md from base branch |
…delivery is in flight
Summary
Second chunk of a two-PR stack (stacked on the identity PR). Wires Vercel sandbox usage billing into
the control-plane Durable Object
SandboxControland turns the path on: a persistent,generation-fenced billing continuation is armed before the sandbox is created, admission happens
before
createSandbox, drains reconcile, and settlement is delivered through the heartbeat tick.Depends on the base branch of this PR (the identity chunk); review that one first.
What it does
creatingrecord whose caller ownscreateCommands,runEnsureReadyopens the meter interval (or re-acknowledges it) and arms the continuation beforecreateSandbox. Definite rejection: enforced blocks withbilling_blockedviafailCanonicalCreate;shadow continues this create with no interval. Uncertain start: enforced releases
creatingandzero-settles the retained generation; shadow keeps the generation and still creates — a meter outage
never blocks a shadow create.
provider work can remove the
creatingdeadline, marked settlement-due on terminal reconcile andremoved only on ack or the 60-minute abandon.
alarm()re-arms it and, whenruntimeDeleted, runs asettlement-only path (no
getSession, nodriveCanonicalStop).afterDrain/afterCanonicalCommitawait local preparation and alarmcomposition; meter delivery happens separately, off the billing and heartbeat queues, so a
heartbeat-triggered budget stop cannot deadlock.
create()stores the sessioncreatedAton the generation binding before returningthe ref;
observe()/stop()storecreatedAt/stoppedAt/abortedAt. An owned 404 is terminal.create()no longer calls admission; the shared alive/terminal classifier is exportedand used by both
observe()and the billing host.metered-billing-lifecycle.ts: accept an unmeasured context only whenthere is no
pendingStopand the start ack matches; clear only definite rejections.Verification
cloud-agent-nextunit suite: 255 files, 7750 passed, 3 skipped.pnpm lint0/0 andpnpm typecheckexit 0 forcloud-agent-nextandcontainer-usage-meter.container-usage-metertest:postgres: 15 passed against real Postgres.packages/container-usageunchanged.Not verified
Live Vercel end-to-end has not been run: it requires an enrolled org (
VERCEL_SANDBOX_ORG_IDS) plusthe Vercel runtime artifacts and credentials, and the operator SKU rows. Once enrolled, reconcile a
real session's persisted
confirmed_secondsagainst the Vercel sessioncreatedAt→stoppedAt.Scope
Only the sized presets
vercel-small/vercel-largeare metered.providerSupportsEnforcedBilling('vercel')stays false, so Vercel is not chosen as the enforced default provider; the unsized default Vercel
destination stays unmetered and fail-closed under enforcement.