Commit Graph
5205 Commits
Author SHA1 Message Date
Neil 23c4fa300c fix(cloud): scope Orca Cloud workspaces to the active team; never list sandbox clones
Bug 6: a team switch left the previous team's cloud workspace in the
sidebar (as its own project header) and kept its lease scheduler, wake
and orcad calls running under the new team's token.

- Orca Cloud runtime records carry the owning control-plane account
  (cloudAccountId, sandbox-control's org:<id> / user:<id> form), read
  once at the create write-ahead from the active profile.
- Backfill: on the 30 s beat and on every auth change, list the active
  team's sandboxes (GET /v1/sandboxes is scoped to the caller's account)
  and file the listed records under that team; it re-lists only when the
  team or the unfiled set changes, and drops a list that answered for a
  team the user has since left.
- The session registry, OOM polling and the window's cloud workspace ids
  skip every record outside the active team, so the old team's sandboxes
  get no keep-alive or orcad calls after a switch.
- Sidebar rows, the jump palette and project headers hide another team's
  sandbox hosts and any whose team is unknown (or when signed out).

Bug 7 (per coordinator): every Orca Cloud sandbox's primary clone stays
hidden; each cloud workspace row appears once.
2026-11-10 16:26:48 -08:00
Neil d6cfb6bee0 feat(cloud): DS-40 Fix with agent for failed Orca Cloud environment builds (#301)
* feat(cloud): DS-40 Fix with agent for failed Orca Cloud environment builds

A failed environment build (Settings > Orca Cloud > Cloud environments) now offers, to admins on the
latest build, Try again next to Show error, plus Fix with agent when the install script is what failed.
Fix with agent opens the composer on Orca Cloud with the prompt prefilled ('The environment build
failed at {{step}}. Fix the install script so the build succeeds.'), the current install script and the
log lines already visible in the viewer (redacted, 60 lines / 6 KB, fences neutralized). The new cloud
workspace boots from the environment's last good build, or a blank sandbox if none succeeded, as every
new cloud workspace does. orca cloud env only works on the desktop, so the agent hands back the full
fixed script for an admin to save and rebuild.

Install scripts only run in environment builds (never during a workspace create), so this lives on
the environment panel's failure summary rather than the create sheet.

* fix(cloud): DS-40 design follow-ups: two actions, and clone failures

(a) The failed-build summary drops Show error: the failed step already opens on its error, and the
    summary title now jumps back to it (log scrolled, collapsed or virtualized). Actions are Try again
    (outline) and Fix with agent (ghost). The unused cloudEnvironment.log.showError key is pruned.
(b) Clone failures: from the visible log, repo-content failures (submodules, LFS, paths that can't be
    checked out) offer Fix with agent with 'The environment build failed while cloning {{repo}}. Fix
    the repository setup so the clone succeeds.' (no install script attached; the agent fixes the repo
    on a branch and opens a PR). Access and auth failures offer Give access (GitHub install for that
    repo), never an agent. Anything unrecognized, or a clone log that isn't loaded, offers neither.
    New fixtures panelCloneFailedContent / panelCloneFailedAccess; classifier and helper unit tests;
    fixture spec 3/3.
2026-11-10 11:47:23 -08:00
Neil 9b78cc13f6 feat(cloud): WSL rows name the selected account; classic SSH reports an API key overriding a sign-in (hasLogin)
- A16 panel WSL rows: 'Account: {{name}} (selected in Accounts)', read from this computer's
  settings (the selection the desktop pushes to the distro), so a stopped distro is never started.
- Classic SSH probe (private): hasLogin when an API key signs the agent in, from presence-only
  checks on the host (Claude: credentials file or macOS Keychain item existence, no -w/-g;
  Codex: grep -q for a refresh_token key). Each prints only yes/no; no value is read or returned.
  S3 shows 'API key overrides sign-in' (needs attention, Review); the panel row says the same.
2026-11-10 11:01:28 -08:00
Neil 36acde0023 feat(cloud): classic SSH agent sign-in status and code sign-in over remote exec
Spec v4 §4 annotations 4-5, Q8. Main runs the CLIs' own status commands (claude auth status --json,
codex login status) over the host's SSH exec only while it is connected, 60 s cache per target;
only verdicts reach the renderer. Code sign-in runs Claude's paste-code login and Codex's device
code over SSH exec (no callback, no forward): the pasted code goes to the CLI's stdin, never argv;
codes, tokens and CLI output are never logged. The A16 panel's classic-SSH rows get Sign in (inline
paste / device code), Sign out, the dated last report and the spec's disabled reason while
disconnected; S3 checks classic SSH hosts the same way. No #40228 file edited.
2026-11-10 10:37:31 -08:00
Neil 5883d7eaf6 fix(cloud): tell a provider that was never offered (flag off) from the kill switch
GET /v1/agent-credentials adds providerState {claude, codex: on|off|disabled} next to providerEnabled.
Clients read it through orcaCloudProviderState (older servers: disabled = kill switch; a state that
contradicts providerEnabled is never trusted). Flag off is a new 'unavailable' kind: Settings says
it isn't available in Orca Cloud yet (no 'right now / until it's back'), and the composer hides the
Agent row like an agent without an account path. Kill-switch copy is unchanged.
2026-11-10 09:02:08 -08:00
Neil 6da29ef05c Merge pull request #282 from nwparker/cloud/agents-s0
feat(cloud): S0 Orca Cloud agent accounts + onboarding Agent row (G)
2026-11-10 08:30:08 -08:00
Neil e69a92a608 fix(cloud): a confirmed sandbox delete never surfaces as invalid_response (#285)
The desktop parsed the DELETE answer with the full strict sandbox view, so any view field the control
plane adds later (e.g. archive state) turned a successful delete into 'Orca Cloud returned an unexpected
response'. Destroy now parses only what confirms the delete (id + status) and ignores unknown keys; a
body without them is still rejected. Tests cover both.
2026-11-10 08:30:02 -08:00
Neil ece50d6b80 merge integration 2026-11-10 08:21:18 -08:00
Neil e6cdedd45e Merge pull request #247 from nwparker/cloud/agents-aws-badge
fix(cloud): W10-2: AWS keys marked 'Real value in sandbox' with a focusable tooltip; fixtures
2026-11-10 08:21:14 -08:00
Neil 6973c6abe7 Merge remote-tracking branch 'private/cloud/integration' into cloud/agents-s0
# Conflicts:
#	src/renderer/src/components/new-workspace/NewWorkspaceComposerProjectSection.tsx
2026-11-10 08:11:00 -08:00
Neil a3d362a49a fix(cloud): S0 security review: Windows quoting, repaint-safe token capture, broker id, identity binding
- setup-token on Windows goes through cmd with the shared quoting as one verbatim
  ConPTY line; the child env is buildClaudeChildProcessEnv (no inherited auth) and
  runs in the home directory.
- Token capture drops styling escapes, breaks on cursor moves, waits 1 s for a
  repaint and keeps the longest complete copy, so a split copy is never stored.
- Broker ids must start with a letter or digit (no '.'/'..' path tricks), checked
  at parse time too; server error names are looked up with a Map.
- A setup belongs to the Orca identity it started under: a changed identity drops
  the captured token / cancels the broker and resets the rows.
- A token being stored can't be cancelled or raced by a paste or a new start.
- The Codex driver only shows OpenAI sign-in pages and caps the wait at 20 min.
- The paste field clears in a finally; a rejected IPC reads as unknown.
2026-11-10 08:05:45 -08:00
Neil 0fd423dea1 feat(cloud): S0 Orca Cloud agent accounts + onboarding Agent row (G)
Main:
- agent-credentials client for /v1/agent-credentials, /v1/agent-sources and the
  Codex broker routes; replies and errors are codes only. The shared control-plane
  request keeps the server's error name (HostedSandboxRefusalError) so newer
  routes (broker_in_progress, rate_limited, no_golden_image) map to codes.
- claude setup-token runner (pseudo-terminal in production, fake child in tests):
  captures the sk-ant-oat01 token in memory, never logs it, PUTs it from main
  with the local Claude account email as label. Capture failure or no claude
  offers "Paste the token instead"; a pasted value goes renderer -> main once.
- Codex broker driver: device code, poll until active, cancel, code expiry.
- orcaCloudAgents IPC + preload bridge: states and codes only.

Renderer:
- Settings > Agent accounts > Orca Cloud (S0, spec §5): not set up, setting up
  (browser / preparing / device code / paste / saving), state 7 Source choice,
  active, expiring, expired/revoked, kill switch, signed out, load and save
  errors; the mandatory policy line; Source via SettingsSegmentedControl.
- The composer's Agent row (cloud-start G) replaces ComposerCloudAgentHint:
  from your Orca account / team key (collapsed), Set up once -> S0, kill switch
  info, signed-out copy; hidden for members blocked by billing; never blocks.
- Telemetry cloud_first_start_agent_coverage (once per install).
- Fixtures: settings/agent-accounts/OrcaCloudAccounts:*, new-workspace/OrcaCloudAgentSetupRow:*.
2026-11-10 07:56:58 -08:00
Neil 3c368cbe52 Merge remote-tracking branch 'private/cloud/integration' into cloud/w2-d4-github-projects 2026-11-10 07:49:42 -08:00
Neil 13d6cf7e51 feat(cloud): GitHub-only projects in the Project picker (cloud-start D4) 2026-11-10 07:44:33 -08:00
Neil e48cf41c69 Merge pull request #276 from nwparker/cloud/agents-a5-followups
A5 follow-ups: offline last-known state, retry missed syncs, remove-prompt fixture, dev e2e
2026-11-10 07:43:54 -08:00
Neil 67008f4515 feat(agent-api-keys): A5 follow-ups: offline last-known state, retry pending saves, remove-prompt fixture
- Signed in but Orca unreachable: rows keep their last-known state (from the per-account ledger:
  names, key ids and timestamps only) under "Can't reach your Orca account right now", with no
  account actions that would fail.
- Saves made while signed in that miss the account (offline or a transient failure) are queued in
  the ledger and retried at start, on wake and with backoff while waiting; the timer stops when
  idle. Only that key at that version: edits, removals and signed-out saves are never uploaded.
- Fixtures: removePrompt, cloudUnreachable.
2026-11-10 07:36:51 -08:00
Neil e7f74b595a Merge remote-tracking branch 'private/cloud/integration' into cloud/w2-cloud-start 2026-11-10 07:16:43 -08:00
Neil f094594d0e merge integration; design-squad copy: generic 'this key' sentence for non-AWS keys, subscription-token refusal points to Settings → Agent accounts 2026-11-10 06:58:16 -08:00
Neil b574953493 Merge remote-tracking branch 'private/cloud/integration' into cloud/agents-a5
# Conflicts:
#	src/renderer/src/i18n/locales/en.json
2026-11-10 06:50:12 -08:00
Neil 0df70ebdf7 feat(agent-api-keys): save Agent API keys to the Orca account and import from this Mac (A5/D12)
While signed in to Orca with Orca Cloud, saving an Agent API key also writes it to the
personal Cloud secret of the same variable through /v1/secrets. The sealed vault stays the
cache and the source for non-Cloud launches; host scope stays local. Only every-host keys the
egress proxy swaps are written. A main-side ledger (names only, per account) tracks what this
computer wrote, and only those copies can be removed from the account, after confirmation.

Import from this Mac: main scans OpenCode's auth.json, ~/.gemini/.env and the login shell env;
the renderer sees names, sources and last fours only, and main re-reads values on import.
OAuth sign-ins are listed, never read.
2026-11-10 06:46:50 -08:00
Neil 8089315803 chore(l10n): sync protected copy keys 2026-11-10 06:44:23 -08:00
Neil d5ea304eaf Merge pull request #262 from nwparker/cloud/w6-spec-ui
feat(cloud): agent-accounts W6 UI: panel Cloud sections 2–3, S2 build-sheet Secrets, S4-b secret request card
2026-11-10 06:38:12 -08:00
Neil f375fae7ad Merge remote-tracking branch 'private/cloud/integration' into cloud/w2-cloud-start 2026-11-10 06:29:55 -08:00
Neil a0b600f4fd wip(cloud): Start in Orca Cloud spec v2 (no shortcuts/split menu, trial, GitHub row, hours) 2026-11-10 06:29:55 -08:00
Neil 7c5c00331f Merge pull request #263 from nwparker/fix/billing-usage-alert-refresh
fix(billing): timely usage alerts — re-read on cloud create/wake and every 30 min while running
2026-11-10 06:26:22 -08:00
Neil 51ace4d05f feat(billing): one-time Orca Cloud trial (N11) and its desktop surfaces (T1)
Billing Worker:
- trials + trial_claims (migration 0005): 2 sandbox hours per new team, no card, no Stripe.
- POST /v1/billing/trial grants it (idempotent, any member); grantTrial/trialOffer exported for
  the setup session. offers.trial on GET entitlements only when this caller could still claim it.
- Abuse limits: once per team, Orca user, normalized verified email, GitHub user (token claim)
  and GitHub owner (POST /v1/internal/trial/github from the binding; a reused identity revokes),
  disposable-domain blocklist, 3 grants per IP per day. Keys stored as SHA-256 hashes.
- Entitlement trial {includedSeconds, usedSeconds, remainingSeconds, exhausted}; metered from
  usage_events, concurrency 1, never overage; trial_used_up (suspendRunning) / trial_unavailable.
- Any subscription ends the trial; unused trial hours lapse.
- e2e: trial path (grant, no Stripe customer, concurrency, metering to used up, once per user,
  plan ends it) with cleanup of the run's abuse keys.

Desktop: trial_used_up / trial_unavailable classify as 'plan'; copy in billing, phone and CLI;
"Trial" badge, TrialPlanSummary in Plan & billing and the plans page strip, account menu row
"Trial · {{count}} sandbox hours left" (Choose plan for owners/admins); billingClaimTrial IPC
and claimOrcaCloudTrial() for the composer.
2026-11-10 06:20:22 -08:00
Neil 1b2cfb9c7d fix(billing): re-read usage on cloud create/wake and every 30 min while one runs
Usage alerts only fired on a billing read, so a team crossing 75/90/100% mid-session
wasn't alerted until a restart, a team switch or opening a billing view. Main now owns one
app-wide schedule: the hosted recipe's onReady (create and resume success) asks the main
window for a forced billing re-read, and the session registry's sync (already run on every
lifecycle change and on the existing 30 s beat) reports whether any cloud workspace is
running, which drives a 30-minute poll with no timer of its own. Requests go only to the
trusted main window so extra windows never stack reads; the per-level ledger still dedupes.
2026-11-10 06:15:39 -08:00
Neil 7fc9af478d Merge remote-tracking branch 'private/cloud/integration' into cloud/w2-cloud-start
# Conflicts:
#	src/renderer/src/components/new-workspace/NewWorkspaceComposerProjectSection.tsx
2026-11-10 06:15:39 -08:00
Neil 9b1754a6d7 Merge remote-tracking branch 'private/cloud/integration' into cloud/w6-spec-ui
# Conflicts:
#	src/renderer/src/i18n/locales/en.json
2026-11-10 06:12:10 -08:00
Neil 33950fa436 feat(cloud-setup): desktop side of the one-tab setup session (N1), team-first plans (O1)
- Signed out, Set up and start opens one tab. The authorize page shows the
  setup account step (A2). Once the code is exchanged, the loopback holds the tab,
  creates the billing setup session and 302s the same tab into the setup pages.
- Signed in, the session is created and its start URL is opened.
- IPC: orcaProfiles.cloudSetupStart / cloudSetupGet / cloudSetupLink (Copy setup
  link mints a fresh one-time link).
- Renderer: cloud-setup-session.ts polls the session (2 s for 3 min, then 10 s),
  keeps a snapshot for the composer and tracker, and switches the profile to the
  team setup chose.
- Plans dialog: Checkout joins the open setup session. A personal account
  (409 team_required) goes through setup instead, which makes or picks a team
  first.
- Billing: POST /v1/cloud-setup/sessions/:id/link.
2026-11-10 06:07:35 -08:00
Neil 055428b381 feat(billing): dedicated 100% usage alert copy by overage state (design-squad) 2026-11-10 06:03:44 -08:00
Neil 7f5e6a9af3 feat(billing): alert owners and admins at 75/90/100% of sandbox hours
- Desktop notification (title "Orca Cloud", body reuses the in-app usage sentence) when a
  billing read crosses 75, 90 or 100%, once per level per account and billing period. Main
  owns the ledger (userData/orca-billing-usage-alerts.json), so reloads, re-renders and
  second windows never repeat it; a new period starts over. Members are never notified.
- Click opens Settings > Orca account (Plan & billing) via ui:openSettings with a target.
- The in-app usage notice (account menu, billing panel, plans page) is now owners/admins only.
- Billing panel: muted note under the Overage description that owners and admins are alerted
  at 75%, 90% and 100%.
- Fixtures: account menu at 90% (admin and member), billing panel member at 90%.
2026-11-10 06:03:44 -08:00
Neil 95bb1dd372 Merge pull request #249 from nwparker/cloud/w6-a9-recipe
A9 sign-out before delete + recipe env-forwarding warning (P-4)
2026-11-10 06:03:08 -08:00
Neil dddfa2ecfa fix(cloud): the host itself says it is an Orca Cloud VM; the desktop sends it no Agent API keys, whatever the name or pairing
Security re-review: the VM-side guard matched a fixed list of names, but the desktop key store
accepts any variable name, so a custom-named key (CODEX_API_KEY, GH_TOKEN, ...) could still reach a
hand-paired cloud VM. orcad now advertises host.orca-cloud.v1 in status.get when ORCA_IS_CLOUD=1, and
before any desktop key goes to a runtime host the desktop asks (cached 60 s); a cloud answer, or no
answer, sends none. The VM-side drop stays as defense in depth.
2026-11-10 05:56:23 -08:00
Neil 21ac87b972 feat(cloud-start): setup return link, setup telemetry, X1 error model, B2 team-plans lookup (NP-4)
- N9: orca://cloud/setup/return?session=cs_… is routed (open-url + second
  instance), validated, focuses Orca and fans out to renderer listeners
  (onCloudSetupReturn) so the setup session re-reads at once.
- N10: cloud_setup_step_{started,done,failed}, cloud_setup_first_sandbox and
  cloud_setup_plan_chosen, enum-only, derived from the setup rows.
- X1: setup error kinds (timed_out, checkout_canceled, bank_step,
  trial_unavailable, team_create_failed, wrong_account) and their actions.
- B2: billing POST /v1/billing/team-plans returns other teams' plan state with
  the caller's own token; auth confirms membership from that token (no new
  credential). Desktop IPC billingTeamPlans + useSwitchToPlannedTeam. The team
  switch logic moves out of SidebarTeamSubmenu so the composer can reuse it.
2026-11-10 05:50:29 -08:00
Neil 60b3d14489 merge agents-aws-badge (shared credential list) 2026-11-10 05:48:18 -08:00
Neil 4030deeba8 fix(cloud): every agent credential a sandbox gets in full is marked 'Real value in sandbox', not only AWS keys
A shared list of agent and model-provider credential names (AWS, Bedrock, OpenRouter, Groq, xAI,
Mistral, DeepSeek, Together, Fireworks, Perplexity, Cerebras, Moonshot/Kimi, DashScope, Z.ai,
MiniMax, NVIDIA, Cohere, Azure OpenAI, Hugging Face, Amp, Factory, ...) marks every one that has no
egress swap. AWS keeps its own sentence; others read 'Orca can't swap {{name}} at the network edge,
...'. The control-plane test now walks the server's agent keys, this list and the desktop's Agent
API key presets: each is swapped, or flagged.
2026-11-10 05:43:43 -08:00
Neil 732c04ddd7 Merge remote-tracking branch 'private/cloud/integration' into cloud/w6-a9-recipe
# Conflicts:
#	cloud/apps/sandbox-control/image/vm-scripts.generated.ts
2026-11-10 05:43:06 -08:00
Neil 7fa51b6a0b Merge pull request #246 from nwparker/np4/github-repo-access
NP-4: GitHub repo access, preselected install URLs, install requests, webhook auto-start, repository list (N2/N3/N12, D2/D3)
2026-11-10 05:42:57 -08:00
Neil 6bdee22ffe feat(cloud): Start in Orca Cloud - Run on segments, setup panel, state-aware primary, auto-start, run-on memory, New cloud workspace entry points 2026-11-10 05:30:25 -08:00
Neil fed130d30a feat(cloud): orcad reports its build; desktop flags out-of-range version skew with a cloud workspace (#254)
* feat(cloud): orcad reports its build commit; desktop flags out-of-range version skew with a cloud workspace

* review: shared compat verdict, status role, retries, tests, version-skew runbook section

* fix: lint gates (async commit read, no casts, retry outside effect, surface split)

* test(cloud): status panel error action is Try again (DS-13 copy)
2026-11-10 05:27:55 -08:00
Neil 849a12773b fix(cloud): find agent CLIs in /opt/orca/tools/bin; delete note only for running sandboxes; test retry skip
Verified on a dev sandbox (Claude Code 2.1.319, codex-cli 0.166.0): runCommand runs as ubuntu with
HOME=/vercel (same user as orcad); `claude auth logout` and `codex logout` exist and exit 0; the
script reported {loggedOut:2,left:0}, removed both credential files and kept other ~/.claude.json keys.
2026-11-10 05:27:41 -08:00
Neil 521c9fe3c5 feat(cloud): desktop repo access hook, GitHub row model and repo list plumbing (NP-4 N2/N12, D2/D3) 2026-11-10 05:19:45 -08:00
Neil bfa713140c fix(i18n): plural defaults for the recipe env warning; sync runtime and protected-copy catalogs 2026-11-10 05:03:10 -08:00
Neil 4ca180d5ae fix(w8): cloud-icon rule on the phone (paired desktop cloud rows, home label, nav glyph) (#245)
* fix(w8): cloud-icon rule on the phone: a paired desktop's Orca Cloud workspaces lead with the Cloud glyph + state dot (worktree.ps carries orcaCloud.status), home cloud rows read 'Cloud workspace, …', muted Cloud before the cloud workspace title

* fix(w8): cloud-icon review: glyph label merges into the row (no own focus stop), no filled ring behind the dot (pressed/active fills), newest VM record speaks for a workspace

* fix(w8): cloud-icon review 2: a cleaned-only workspace stays cloud (as on the desktop) with no dot, a live VM beats a cleaned one, cleanup_failed draws no forever-pulsing dot; store-order test

* test(w8): cloud-icon ps status test without a cast

* fix(w8): cloud-icon dot sits mostly outside the glyph's bottom-right (design-squad), clear of the title
2026-11-10 04:53:44 -08:00
Neil 2454d31779 feat(cloud): agent-accounts W6 UI slices: panel Cloud sections 2–3, S2 build-sheet Secrets, S4-b secret request card
- Panel sections 2–3 on Orca Cloud (standalone, for gap-agents' AgentHostPanel shell):
  Cloud-secret key rows with scope chips and shadowed keys listed disabled with the reason;
  effective variables; missing names with inline Add / Add mine; asleep and shared (D13) states.
- S2: missing = environment envVarNames − effective secrets for the repo and caller; Paste .env,
  per-name scope, batch save, build-time team-only note (Q7), post-open 'secrets missing' notice.
- S4-b: card for orcad secrets.requested/requestSettled; Personal by default, Repository only if
  writable, agent scope as hint; N more requests; expired and saved-after-expiry; touchRequest at
  most once a minute; Restart {{agent}}; value saved via Cloud secrets PUT, then resolveRequest.
- Main: cloudSecrets.workspaceSharing reads GET /v1/agent-sources (owner, sharedWorkspace).
- Fixtures for every state, dark and light.
2026-11-10 04:53:42 -08:00
Neil aedf0809eb Merge remote-tracking branch 'private/cloud/integration' into cloud/w6-a9-recipe
# Conflicts:
#	src/renderer/src/i18n/locales/en.json
2026-11-10 04:43:10 -08:00
Neil dd34314dc0 feat(billing): bill overage by the minute, put sandboxes to sleep at the cap (U22, U24)
- Overage stays $1.00 per sandbox hour (ORCA_CLOUD_OVERAGE_CENTS_PER_HOUR) and is now billed by
  the minute: a per-minute metered TEST price (unit_amount_decimal = rate / 60 to 12 decimals,
  transform_quantity divide_by 60, round up), created the same way by stripe-test-setup.ts.
  capSeconds rounds the cap down to whole minutes and spentCents mirrors the invoice, so the
  cap math matches Stripe. The meter still counts seconds.
- Opting in re-prices an overage item still on an older price (e.g. $0.75 / h) instead of adding
  a second item on the same meter, and removes any extra stale one.
- Alerts at 75%, 90% and 100% of included hours (warnAtPercent).
- New top-level entitlement.suspendRunning: payment grace expired, or at the limit (out of hours
  with overage off, or at the spend cap). The start check and usage answers carry it, so the
  control plane puts running sandboxes to sleep (snapshot kept, never deleted). Payment fields and
  /v1/internal/suspensions stay payment-only, so no data-retention clock starts at a cap.
- Copy (desktop billing panel, plan card, build sheet, phone, CLI): "billed by the minute" after
  the rate; at the limit "Running sandboxes go to sleep and new ones can't start. Nothing is
  deleted, and your files are safe."
2026-11-10 04:33:07 -08:00
Neil be30702701 Merge remote-tracking branch 'private/cloud/integration' into cloud/w6-a9-recipe
# Conflicts:
#	cloud/apps/sandbox-control/image/provision-golden.sh
#	cloud/apps/sandbox-control/image/vm-scripts.generated.ts
2026-11-10 04:11:07 -08:00
Neil 12fe0c867f feat(cloud): sign agents out before sandbox delete, scrub env-build images, recipe env warning (A9, P-4)
- Worker: run orca-agent-signout (each agent's logout, then credential files) on a running sandbox
  before the provider delete; bounded (20 s) and best effort, never blocks the delete.
- Environment builds: scrub agent auth (--scrub-only) before the snapshot; fail closed.
- New VM script registered in VM_SCRIPTS + provision loop; vm-scripts regenerated.
- Main IPC ephemeralVm:forwardedEnvSummary returns names only, grouped by credential-looking.
- P-4 warning component (+ fixture) shown under Settings > recipes; delete dialog line for awake
  Orca Cloud sandboxes.
2026-11-10 04:07:13 -08:00