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
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
The publish gates1. Build the manifest locally2. Confirm at least one plan, each rate-limited3. Connect and verify Stripe4. Preview the release5. Publish6. Confirm it's actually live7. Smoke-test with a real keyVerify it worksRelated
Status
Docs/Cookbook/Prepare for launch

Prepare for launch

The checklist for taking a draft product live — the gates publish enforces.

PreviousOperate via an agent

A product is born as a DRAFT. Going live means passing the publish gates — the same checks the dashboard's "Finish setting up" flow runs. farthershore product publish enforces them and prints a stable bracketed code with remediation when a gate fails. This is the agent-operable version of the launch flow; work it top to bottom before you invite subscribers.

The publish gates

publish refuses until all of these hold:

GateHow to satisfy itFailure code
At least one planfarthershore plan create … (or a @Plan member)—
Every plan has a rate limitA limits.requests rule on each planPLAN_RATE_LIMIT_REQUIRED
A product origin--origin at create, or @Product({ origin })—
Stripe connectedfarthershore connect stripe <product> (browser)STRIPE_NOT_CONNECTED
Stripe verified (KYC)Finish the Stripe onboarding in the browserSTRIPE_NOT_VERIFIED
Tax enrollmentEnroll in Stripe Tax in the dashboardBILLING_TAX_NOT_ENROLLED

1. Build the manifest locally

Catch schema and cross-reference errors — a plan granting an undeclared capability, a route reporting an undeclared meter — before anything touches live state. build runs the same deterministic compile the platform does.

farthershore build --format json

build does not enforce the per-plan rate-limit gate (so byte-identical fixtures can stay limitless), but publish does. Every plan must carry at least one rate-limit rule, e.g. limits: { requests: { rate: 600, interval: "minute" } }, or publish fails with PLAN_RATE_LIMIT_REQUIRED.

2. Confirm at least one plan, each rate-limited

farthershore plan list croncloud --format json

Every plan needs a rate limit. If a plan is missing one, add a limits.requests rule and rebuild — or, for a CLI-created plan, the --rate-limit flag (default 600/min) supplies it.

3. Connect and verify Stripe

Billing connection is a browser KYC flow — the one step that can't be done headless. Poll status until it clears:

farthershore connect stripe croncloud --format json

Resolve STRIPE_NOT_CONNECTED → STRIPE_NOT_VERIFIED → BILLING_TAX_NOT_ENROLLED in order; each remediation is printed when the gate trips.

4. Preview the release

publish --dry-run runs the full compile and semver derivation and returns the computed bump + reasons without cutting a tag. A breaking (blocking-risk) change is refused unless you pass --accept-breaking.

farthershore product publish croncloud --dry-run --format json

Confirm the computed bump matches your intent.

5. Publish

farthershore product publish croncloud --format json

Publish auto-derives the semver bump and cuts a vX.Y.Z release. Existing subscribers are grandfathered by default — see Change a price for moving them.

6. Confirm it's actually live

ACTIVE is not the same as serving. product status returns a derived live boolean (ACTIVE + a real release applied + the edge serving the snapshot) — poll it until live: true.

farthershore product status croncloud --format json

7. Smoke-test with a real key

Before real subscribers arrive, mint a test persona in a preview environment, call the gateway, and confirm usage lands:

farthershore persona bootstrap croncloud --env preview --plan pro --format json
farthershore usage summary croncloud --format json
  • A valid key is allowed, forwarded upstream, and counted on the right meter.
  • Missing / invalid / revoked keys fail with the expected gateway codes.
  • A request over a plan limit is denied.

Verify it works

  • farthershore build compiles clean.
  • plan list shows ≥1 plan and each carries a rate limit.
  • connect stripe reports connected + verified.
  • product publish --dry-run shows the expected bump; publish cuts the release.
  • product status reports live: true and a real latestReleaseVersion.

Related

  • Operate via an agent — the full headless create→publish flow.
  • Change a price — what publishing does to existing subscribers.
  • Gate a feature — verify each plan's access before launch.