Skip to content

Add cost-aware GCP Cloud Labs #39

Description

@ElbertePlinio

Goal

Add PickLab Cloud Labs: cost-aware, bring-your-own-GCP test machines that AI agents can provision, use for visual app testing, collect evidence from, and shut down safely.

The user sees and approves the estimated cost before any billable resource is created.

Product boundary

V1

  • Bring your own GCP project; Google bills the user directly.
  • Mandatory cost preflight in terminal, JSON, MCP, and local responsive HTML.
  • Ubuntu target with remote PickLab sessions.
  • Windows Server Desktop Experience compatibility target with CUA/native automation.
  • Infrastructure-enforced runtime limit, ownership labels, evidence, and cleanup proof.
  • Agent access through narrow PickLab tools rather than unrestricted cloud administration.

Not V1

  • Pickforge-managed cloud accounts, credentials, or billing.
  • AWS/Azure provider abstraction before the GCP contract is proven.
  • Exact Windows 11 BYOL/sole-tenant provisioning; track separately after V1.
  • Production credentials, customer data, or always-on shared machines.

User flow

  1. Configure provider, region, targets, machine sizes, disks, runtime, and cleanup mode.
  2. Generate a dated estimate showing hourly cost, maximum session cost, retained monthly cost, and exclusions.
  3. Save an immutable plan with a plan hash.
  4. Human approves that exact plan; agents cannot silently change it.
  5. PickLab provisions, tests, streams evidence, and cleans up.
  6. Final report states test result, evidence location, and verified cloud cleanup state.

Proposed commands:

picklab cloud plan --provider gcp --targets linux,windows --hours 80 --open
picklab cloud create --plan .picklab/cloud/plans/<plan-id>.json
picklab cloud run --plan <plan-id> --artifact <path>
picklab cloud status <run-id>
picklab cloud artifacts <run-id>
picklab cloud stop <run-id>
picklab cloud destroy <run-id>
picklab cloud list --orphaned
picklab cloud doctor

Cost preflight contract

  • One typed calculation engine powers terminal, --json, MCP, and HTML output.
  • Show runtime, maximum approved session cost, and retained-resource cost separately.
  • Show pricing source, capture time, currency, assumptions, and exclusions.
  • Include CPU, memory, disk, Windows Server license, external IPv4, snapshots/images, NAT, and expected egress when applicable.
  • Warn that taxes, credits, negotiated discounts, commitments, and Windows VDA licensing can differ.
  • Reject invalid combinations before provisioning: E2 + nested virtualization, Server Core + visual test, ordinary multitenant GCP + Windows 11, and incompatible architecture/artifact pairs.
  • Require the approved plan hash for non-interactive or MCP creation.
  • Expire stale plans and require re-estimation after configuration or price-snapshot changes.

Initial pricing direction: ship a dated, versioned public list-price snapshot for the supported template matrix; separately spike authenticated live refresh through Google’s pricing/cost-estimation APIs. Do not add a Pickforge-hosted pricing service for V1.

Cleanup and billing-safety contract

Hooks are best-effort convenience, not the safety boundary.

Layer 1 — structured lifecycle

  • All provision/run paths use one idempotent lifecycle with AbortSignal and try/finally cleanup.
  • Handle SIGINT, SIGTERM, and SIGHUP where supported, with a bounded cleanup deadline.
  • Do not rely on Node’s synchronous exit event for asynchronous cloud cleanup.
  • Repeated, concurrent, or partially completed stop/delete requests are safe.

Layer 2 — cloud-enforced dead-man switch

  • Every VM is created with GCP scheduling.maxRunDuration and instanceTerminationAction matching the approved plan.
  • Revalidate/reapply the runtime limit on every restart; a restart must not extend the approved budget unnoticed.
  • Default ephemeral runs to DELETE after evidence is durably streamed; use STOP only when the plan explicitly retains disks/state and shows their monthly cost.
  • Windows 11 sole-tenant follow-up must delete/migrate guests and prove the node group reached zero; stopping a guest alone is insufficient.

Layer 3 — ownership and recovery

  • Label every resource with managed-by=picklab, run ID, stable project ID, plan hash, and expiry.
  • Never delete or mutate a resource without valid PickLab ownership markers.
  • Persist the minimum recovery record outside the source repo before the first create call.
  • cloud list --orphaned and cloud doctor detect expired or partially created resources.
  • Cleanup failures return the exact remaining resource IDs, estimated residual cost, and safe recovery command.
  • Guest/controller failure, laptop sleep, credential expiry, network loss, and process kill are covered by tests or controlled smoke scenarios.

Evidence versus cleanup

  • Stream important logs/evidence during the run; do not wait until shutdown to preserve everything.
  • Evidence upload failure must never leave compute running indefinitely.
  • The plan defines the bounded fallback: stop/delete at the TTL, report incomplete evidence, and preserve only explicitly approved retained resources.
  • Final status distinguishes test failed, evidence incomplete, and cleanup incomplete.

Security and state

  • Use Application Default Credentials or Workload Identity; no long-lived service-account key files by default.
  • No raw SSH/RDP ingress; human access uses IAP.
  • Agents receive narrow PickLab cloud tools, not unrestricted gcloud access.
  • Cost-incurring MCP operations require elicited human approval or an explicit CLI-approved plan hash.
  • Never store tokens in config, VM metadata, logs, screenshots, telemetry, or test artifacts.
  • Cloud plans, runs, pricing snapshots, and recovery records stay under PickLab's existing ~/.picklab/ home (for example ~/.picklab/cloud/) or PICKLAB_HOME; normal startup/run leaves the Git working tree clean.
  • Resource/project identifiers are redacted from telemetry where they could expose private infrastructure.

Technical spikes

  • Pricing: prove the versioned snapshot pipeline and assess authenticated live refresh without requiring broad billing-account permissions.
  • Windows UI: prove unattended boot → install → launch → CUA interaction → screenshot → tray → RDP disconnect → reboot without reusable credentials or an exposed desktop port.
  • Remote session: prove a secure, reconnectable local-agent-to-remote-PickLab transport and evidence stream.
  • Controller death: kill the local process/network during a live smoke run and prove GCP stops/deletes the VM at the approved limit.

Architecture direction

  • Add a focused packages/cloud-gcp package for pricing, plan, provision, ownership, lifecycle, and transport.
  • Keep only proven provider-neutral plan/run contracts in packages/core.
  • Do not force remote cloud liveness into the existing local-PID/Xvfb SessionRecord; model a higher-level cloud lab run that owns a remote PickLab session.
  • Keep packages/desktop-linux unchanged for local Linux automation.
  • Add Windows interaction behind a dedicated Windows backend only after the Windows spike passes.

PR plan

  • PR 1 — Cost model and preflight report
    • Depends on: none
    • Includes: typed plan, versioned prices, terminal/JSON/MCP/HTML parity, plan hash, staleness, invalid-combination checks
    • Validation: exact calculation/boundary tests, responsive HTML checks, zero billable calls
  • PR 2 — Safe GCP Linux lifecycle
    • Depends on: PR 1
    • Includes: auth/doctor, ownership, create, runtime TTL, rollback, stop/delete, orphan recovery
    • Validation: fake API contract tests plus one disposable-project smoke run
  • PR 3 — Remote PickLab and agent approval
    • Depends on: PR 2
    • Includes: remote session transport, evidence stream, MCP tools, elicitation/plan approval, cleanup report
    • Validation: remote Linux app launch/input/screenshot, network interruption, controller death, clean working tree
  • PR 4 — Windows Server compatibility target
    • Depends on: PR 3 and Windows technical spike
    • Includes: interactive test user, CUA/native input, WebView2, installer/tray/restart/uninstall, Event Log/crash artifacts
    • Validation: unattended lifecycle, RDP disconnect, reboot, credential-redaction tests
  • Open separate follow-up issue for exact Windows 11 BYOL/sole tenancy.
  • Final integration, release-note, flag enablement, and flag removal pass.

Partial PRs use Refs to this issue. Only the final PR that satisfies the full V1 contract uses Closes.

Feature flag

Flag: cloudLabs from @pickforge/flags, default off.

  • Merged behind flag cloudLabs
  • Tested on main with flag on
  • Enabled in the intended PickLab release
  • Flag removed after the enabled release proves stable
  • Remove the flagged label when the flag is removed

Validation baseline

bun run typecheck
bun run test
bun run build

Each PR also runs its narrow package/test targets. Live GCP checks use a disposable test project, explicit approved budget, short maxRunDuration, and cleanup verification.

Done when

  • A user can estimate, approve, provision, visually test, collect evidence, and clean up a GCP Linux target end to end.
  • The Windows Server compatibility target passes its unattended acceptance flow.
  • An AI agent can use the same flow without unrestricted cloud credentials or bypassing cost approval.
  • Forced controller/network failure still results in cloud-enforced shutdown/deletion.
  • Final reports prove both test outcome and cleanup state.
  • Exact Windows 11 is represented honestly as separate scope.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestflaggedFeature is dark on main behind a @pickforge/flags flag

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions