Skip to main content
Not yet released. This guide describes implemented changes awaiting rollout. Availability requires the corresponding backend and dashboard release.

Goal

Create and recover an explicitly requested preview without copying production data or credentials.

Prerequisites

  • An unreleased backend with Application preview migrations and controllers enabled, plus the existing preview plan entitlement.
  • An owner-accessible Application with GitHub workloads, explicit 40-character lowercase commit SHAs and eligible hosting or BYOS placement.
  • Fresh PostgreSQL capacity and preview-specific non-production variable references. Capacity and quotas still apply. Workloads on your own server, including a VPS provisioned through StackShift, have no additional hosting charge; server rental and separately purchased services remain separate.

Workflow

1
Open the parent Application previews view, inspect capability and select the workloads and pinned commits. Include each worker explicitly.
2
Declare repository dependencies, required configuration keys and side effects, plus migrations and optional test seed commands. Select versioned variable-reference metadata; never paste secret values into a preview request.
3
Save a draft, then plan it. Review fresh resources, inherited placement, commands, repository declarations, variable references, expiry and itemized known database rates with explicit exclusions. An unavailable component is not zero.
4
Start the exact reviewed plan. Connected agents receive an independent approval; saving or planning does not approve resource creation.
5
Inspect retained resources and release receipts. Resume partial work using the same preview. Configuration prepared and release requested are distinct from runtime verified.
6
Clean up the preview when finished, or explicitly extend it before expiry. For promotion, review the current parent diff and supply separate parent variable-reference mappings.

Fresh data and side effects

Application previews are explicit requests and do not require auto-deploy. Existing per-project pull-request previews remain separate. PostgreSQL dependencies are freshly provisioned. Parent snapshots, rows, credentials, global environment variables and global build-access defaults are not copied. Workload and database mappings retain exact ownership for cleanup. Use non-production references from outside the parent Application. References contain IDs, keys and RFC3339Nano versions; values remain encrypted server-side and are resolved only when applying configuration. Platform-managed schedules and integrations are not cloned. STACKSHIFT_PREVIEW=true and STACKSHIFT_PREVIEW_EXTERNAL_INTEGRATIONS=disabled identify the child runtime. Workers also require explicit inclusion. These flags are application signals, not a network sandbox. Each workload requires a repository_declaration naming external_dependencies, required_configuration and side_effects, with preview_behavior set to none, disabled_by_repository or test_only. Repository code must implement the declared disabling or test-only behavior. The outbound policy below restricts external runtime traffic; the platform does not interpret arbitrary application business logic. All three declaration lists must be present, including explicit empty arrays. Each list allows at most 20 trimmed nonempty entries of 200 bytes; configuration entries are environment key names of at most 128 characters, never values. The none behavior requires an empty side-effect list; the other modes require at least one declared side effect. Review.repository_declarations carries each source_project_id and its declaration; declarations are bound into both creation and promotion review hashes. Old drafts without declarations cannot be newly planned or started; retained cleanup remains available. The maintained App + PostgreSQL and API + worker samples include preview.json and npm run seed:preview. Seeds contain only synthetic test records and refuse to run without preview flags. Review migrations and seed commands before approval.

Outbound policy (next release)

Planning and resuming an Application preview require workload network enforcement. Preview identity comes from the retained child Application record, not an environment flag. The runtime policy disables public-web egress and discards all external grants, including operator-approved destination-specific grants. New external grants are rejected for preview workloads. Runtime host-network destinations are restricted to canonical private endpoints for bound, preview-owned fresh databases. Parent databases, unowned attachments and environment-inferred platform destinations are excluded. Private bindings between included child services remain available. Metadata, unrelated private ranges and alternate DNS stay blocked. Repository declarations do not override these restrictions. The supported data mode is a fresh PostgreSQL database with optional repository-owned synthetic seeds. Production snapshots, masked copies, object-storage forks and queue cloning are not supported by this preview flow. Workers require explicit inclusion; scheduled workloads remain unsupported. These policy changes are implemented for the next release. Local policy tests do not establish deployment or live network enforcement on a hosted or customer-owned node.

Resource support and consistency boundary

Web/API services: pinned GitHub code and supported workload configuration, in a dedicated child Application. Workers: explicit inclusion only. Every bound workload dependency must be selected; scheduled jobs are unsupported. PostgreSQL: fresh allocation, newly generated credentials and reviewed migrations; optional repository seeds create synthetic records. No snapshots, production rows or reader-replica cloning. Use private_runtime bindings; private_read dependencies require a separate supported design. Storage: no managed bucket forks, production prefixes or inherited storage credentials. External queues: no cloning or access. Database-backed test queues can use the fresh PostgreSQL database and explicitly included worker; no parent jobs are copied. Mail, payments and webhooks: use a private child HTTP capture service. The maintained stackshift_server/internal/applicationrecipes/preview-test-sink sample accepts POST /mail, /payments and /webhooks, returns delivered=false, and supports reading/deleting captured records. It never sends an external request. This is an application-adapter contract, not an SMTP server or payment-provider SDK emulator. Copy the sink into your repository as a private API service, include it explicitly in the preview and bind consumers to its private URL. Route preview-only delivery adapters to it. Its bounded in-memory records are synthetic and disposable; production credentials and customer data must not be supplied. This is a fresh dependency environment, not a point-in-time production replica. No cross-resource snapshot consistency is promised. Preview variable references must be non-production and outside the parent Application; no parent or global variables are inherited.

Cost review and cleanup

Hosted fresh PostgreSQL allocations have itemized NGN quotes in kobo per hour, before plan allowances. Each rate has a catalog revision and 15-minute expiry bound to the review. Missing catalog prices block planning; changed or expired quotes block pending database creation. Historical plans without quotes must be newly reviewed. Owner-server workloads have zero additional StackShift hosting charge. Server rental, unpriced compute, storage growth, backups, network and taxes remain explicit exclusions. Existing spending limits remain in force; this workflow adds no aggregate infrastructure cap. If a quote becomes stale after a child has been admitted, clean up the retained preview and create a new reviewed preview. Cleanup is requested at preview expiry; charges can continue until resource retirement finishes. Expiry is not a guarantee of instantaneous deletion or billing cessation.

API, CLI and MCP

Owner APIs use /api/v1/applications/{applicationID}/previews. Connected APIs use /api/v1/agents/connections/applications/{applicationID}/previews. The Application ID is always the parent. Authenticated responses use the data envelope and no-store caching. GET /capability reports entitlement, placement, a maximum of two active previews and a default expiry of 24 hours. GET /variable-references accepts purpose=create or purpose=promotion. GET / lists at most 100 records with an opaque next_cursor; GET /{previewID} inspects retained state. POST / saves name, workloads and expiry_hours with Idempotency-Key. Each workload has source_project_id, commit_sha, include_worker, optional migration_command and seed_command, required repository_declaration, and variables containing key, reference_id and reference_version. Expiry is bounded to 1-168 hours. POST /{previewID}/{action} supports plan, start, resume, extend, cleanup, promotion-plan and promote. Retain Idempotency-Key with the exact body. Mutations include expected_revision; start and promote include review_hash. Extension includes expiry_hours. Promotion planning includes explicit parent_variables. The CLI preview command group calls these same connected routes. MCP provides application_preview_capability, application_preview_variables, application_previews, application_preview_draft, application_preview_get and the corresponding action tools, including application_preview_promotion_plan.
Preview scopes are application.preview.read, application.preview.create, application.preview.resume, application.preview.extend, application.preview.cleanup and application.preview.promote. Existing grants do not gain them automatically. Connected creation also requires the ordinary one-Application creation allowance and its exact hosting or BYOS constraints. Parent workloads, database dependencies and variable-source projects need independent current resource authority. The preview is bound to its original connection. Agents cannot approve their own operations. Admission, approval and execution recheck current scope, membership, target revisions and reference versions. Selected source workloads, database dependencies and variable-source projects are included in affected approval targets with resource versions. Promotion checks every promoted workload under application.preview.promote. Cleanup and cleanup recovery use retained owned resources and do not require fresh source access. Credential replacement does not broaden authority or replenish creation allowances.

Expiry and recovery

Creation approval includes scheduled cleanup of preview-owned resources at expiry. Extension requires authorization before cleanup begins. Cleanup cancels outstanding child releases before deleting owned workloads, bindings and databases. Parent resources and reused attachments are not deletion targets. Partial failure retains successful resources and receipts. Resume retries the retained child release when possible; it does not create a second preview. Cleanup failure stays visible and can be resumed. Inspect a failed parent promotion release through the parent release interface. HTTP 409 revision_conflict or target_changed requires reload and fresh review. HTTP 410 preview_expired rejects elapsed authority. A mismatched retained key returns idempotency_conflict. After a network error or uncertain 5xx response, replay the identical key and body before attempting another operation. Denied or expired approvals remain in history. Reload the preview and prepare a new explicitly reviewed request; an approval record is not runtime success.

Promotion and verification limits

Promotion requires runtime verification, a diff against the current parent revision and a separate coordinated-release approval. Parent changes invalidate the review. Promotion applies pinned code, supported workload configuration and reviewed migrations. Map every selected preview variable explicitly to an authorized parent reference. Preview data, credentials, test seeds, endpoints, placement and preview flags are never promoted. Local fixtures and controlled observations do not establish hosted or BYOS deployment, production HTTPS, external delivery or production promotion. This behavior is unreleased; consult the validation ledger for qualified local paths and deferred checks.

Expected result

One retained preview links its child Application, fresh databases, workloads, bindings, approvals and release receipts. Runtime and deployed endpoint evidence require actual controller observations.

Agent feature availability

Find the actions available to your agent and resolve access or configuration requirements.

Saved Application recipes

Review and continue an Application with private PostgreSQL using the dashboard, CLI or an authorized external connection.

Connection access and approvals

Understand selected resources, permitted actions, owner decisions and revocation.

Agent connection API and OAuth

Separate owner governance from scoped execution, handle OAuth challenges and recover recorded operations.