Farther ShoreDocs
Go to Farther Shore
What is FartherShore
Install the CLI
Quickstart
Core concepts
The @Product class
Meters & resources
Features & routes
Capabilities & entitlements
Plans & pricing
The Manifest IR
Bring your own backend
Transport modes
Metering & verification
Runtime tokens
Frontend SDK
Root & data components
Auth & sessions
Entitlement gates
Connect Stripe
Subscriptions & usage
Plan changes & grandfathering
Billing strategies
Apply & deploy
The apply phasesApplied vs deployed: DRAFT validates, ACTIVE deploysEconomic changesReading apply status from the CLICutting a releaseThe GitHub checksSee also
Environments
Migrations
Docs versions & archive
Operate with an agent
Operation classes
MCP server
End-to-end via CLI/MCP
CLI reference
@farthershore/product
@farthershore/backend
@farthershore/farthershore-js
Environment variables
Response & deny codes
Add a metered capability
Gate a feature
Change a price
Prepaid credits
Meter AI tokens
Operate via an agent
Prepare for launch
Status
Docs/Operate live/Apply & deploy

Apply & deploy

The apply lifecycle — how a product.config.ts push reaches the edge, and how to read the farthershore/apply check.

PreviousBilling strategiesNextEnvironments

When you push a change to product/product.config.ts, FartherShore applies it: it builds the Manifest IR, compiles it, accepts the new spec, and publishes the snapshot to the edge gateway. The whole sequence is one apply timeline — a single read-side view derived from the build, compile, and deployment records — surfaced as the farthershore/apply check on the pushed commit and as the deployments card in the dashboard.

You don't trigger apply by hand. Pushing the branch is the trigger. The CLI gives you farthershore build to compile locally and farthershore product publish to cut a release, but the apply itself runs server-side off the git event.

# Compile product/product.config.ts to Manifest IR locally (CI-safe).
# Server-side validation + apply happen when you push, not here.
farthershore build --format json

The apply phases

Every apply flows through the same ordered phases. Each phase has a status of pending, running, succeeded, failed, or skipped.

PhaseWhat it does
Build IRExecutes product/product.config.ts and emits the Manifest IR. (Labelled "Build IR" to distinguish it from a frontend portal build.)
CompileCore compiles the IR into the internal product model; surfaces compiler diagnostics on failure.
AcceptThe draft spec is promoted to the accepted spec, just before publish.
Apply to edgePublishes the compiled snapshot to the gateway. This is the step that makes the change live.
StripeOnly present for economic changes (pricing/plan edits) — reconciles Stripe. null (omitted) for non-economic applies.

The overall status collapses the phases: any failed phase ⇒ failed; edge succeeded ⇒ succeeded; any running phase ⇒ running; edge skipped (validated but deferred) ⇒ skipped.

The manifest apply (the farthershore/apply check, whose first phase is Build IR) and the portal build (the farthershore/frontend check) are separate pipelines. A template-mode product with no frontend change applies its manifest without ever building a portal — don't conflate the two checks.

Applied vs deployed: DRAFT validates, ACTIVE deploys

A push always validates — Build IR and Compile run for every commit, including on a DRAFT product and on pull-request commits (the farthershore/validate check). But validating is not deploying.

  • A DRAFT product compiles its manifest so you get fast feedback, but it does not publish to the edge until the product is ACTIVE. Going live is a deliberate step — see the product lifecycle.
  • A preview-environment push (ENV_PUSH) publishes its snapshot synchronously — a completed env apply is live on that env's edge. See Environments.
  • An economic change on the default branch defers its edge apply to a release (next section).

So "applied" (compiled + accepted) and "deployed" (serving on the edge) are distinct states. The apply check reports the edge phase honestly: a green Build IR + Compile with a skipped edge means validated but not yet deployed.

Economic changes

An economic change on the default branch — a pricing or plan edit — validates and accepts, then defers the real edge apply to a GitHub Release. Nothing is published on the push: the edge phase reads skipped until you cut the release, and the Stripe phase reconciles billing as part of that release apply. This is why pricing changes are gated behind an explicit release rather than landing the instant you push.

What counts as an economic change is defined with the product contract. To ship one, cut a release.

Reading apply status from the CLI

After a push, confirm a product is actually serving — not just that the commit compiled — with product status. It returns lifecycle, the latest release version, the latest deployment run, and a derived live boolean (ACTIVE + a real release applied + the edge serving the snapshot).

farthershore product status croncloud --format json
{
  "id": "prod_...",
  "status": "ACTIVE",
  "latestReleaseVersion": "v1.2.0",
  "live": true,
  "latestDeployment": {
    "id": "dep_...",
    "status": "SUCCEEDED",
    "edgePublishStatus": "SUCCEEDED",
    "createdAt": "2026-06-24T17:40:11.000Z"
  }
}

live: true is the only signal that means "subscribers are hitting the new snapshot." A SUCCEEDED build with live: false means the manifest validated but the edge has not published it (a DRAFT product, or a deferred economic change).

Cutting a release

product publish deploys the current spec live and cuts a versioned vX.Y.Z release with an auto-derived semver bump. It is the path for the deferred economic changes above.

# Auto-derive the bump from the change and cut the release.
farthershore product publish croncloud --format json

# Preview the computed bump + reasons without cutting a tag.
farthershore product publish croncloud --dry-run --format json

# Force a bump, or pin the exact next tag.
farthershore product publish croncloud --bump minor --format json
farthershore product publish croncloud --version v2.0.0 --format json

A breaking (blocking-risk) change is refused unless you pass --accept-breaking. Publish enforces the same go-live gates as the dashboard: at least one plan, an origin, and a verified Stripe connection (clear STRIPE_NOT_CONNECTED / STRIPE_NOT_VERIFIED / BILLING_TAX_NOT_ENROLLED remediation is printed).

The GitHub checks

FartherShore posts checks on the commit so apply status lives where you push. Check names double as commit-status contexts, so branch-protection required checks match even when the GitHub App lacks the Checks permission and the platform degrades to a commit status.

CheckPosted onReports
farthershore/validatePR commitsManifest validation (Build IR + Compile) for the proposed change.
farthershore/buildPushed/released commitsThe Product SDK build — the product/ build that produces the deterministic Manifest IR.
farthershore/applyPushed/released commitsThe full apply timeline — Build IR → Compile → Accept → Apply to edge (→ Stripe).
farthershore/frontendPushed/released commitsThe portal (frontend) build — the frontend/ build that renders a custom portal. Only fires when a frontend build actually runs.

Checks are feedback, never control flow: a GitHub or platform hiccup is logged and swallowed, and never blocks the apply itself.

See also

  • The @Product class — what you're applying.
  • Environments — preview vs stage vs production applies.
  • Migrations — moving subscribers after a plan change ships.