Commercial releases
The immutable, content-addressed, per-business bundle that binds structure and money — publication, activation, diff, rollback, and active-at-admission.
A commercial release is one immutable bundle per business and environment that binds every artifact the gateway uses at admission to every artifact core uses at rating: compiled plans, route grants, entitlements, measurement schema, admission descriptors, commercial policy (funding, disclosure, exhaustion), and rating contexts. Its id is derived from the hash of its content; identical content yields the same release.
Publication is not activation
Building and pushing a business compiles a release and publishes it: the
immutable CommercialReleaseVersion and its membership index are persisted,
every artifact is written to the edge under versioned keys and read back.
Activation is a separate, per-business step: an entry is appended to the
business's release log and the per-business active pointer is promoted to the
new sequence. Only activated releases admit traffic.
content-hash → health-probe → sequence reserve → versioned keys
→ readback → per-business two-phase pointer promotion → readback → watermark
A stale publisher (one that did not observe the newest release) cannot publish over it. Business A's activation or rollback never touches business B.
Diff two releases
farthershore commercial-release diff <from-release.json> <to-release.json> --format json
The command compares two compiled release manifests locally and reports
unchanged, compiled plans added / removed / changed, rating-context versions
added / removed, every changed manifest path, and compatibility-fence changes.
Active at admission
"Active" is a property of an admission, not of the current pointer. A request is admitted under exactly one release cohort — the route table, grants, entitlement, measurement schema, admission descriptor set, policy, and rating context all from that release; nothing is ever mixed across releases. The gateway stamps the served identity into the signed usage event:
{ subjectId, compiledPlanId, commercialReleaseVersionId,
ratingContextVersionId, routeKey, descriptorSetHash, commercialSequence }
For plans authored with pricing.current(), a compatible commercial publish
does not rewrite every subscriber. If the current global release still contains
the subscriber's immutable compiled plan, the gateway serves that release and
selects its rating context by stable economic-agreement id, or by the unique
public/default context when there is no agreement. The subscriber's exact older
release remains only as a retained structural fallback when the current release
no longer contains the plan. Missing or ambiguous current context selection
fails closed; the gateway never mixes it with an artifact from the fallback.
pricing.withContractTerms() follows the same current-release path while
selecting the context for the subscriber's stable agreement id.
pricing.fixedVersion(n) never follows current G: the exact retained release
named by the subscriber remains authoritative even when current G contains the
same compiled plan.
Core rates the event under that release after verifying the signature, the append-only release log, and the persisted membership index. It never asks whether the release is current now, so a later publish or rollback cannot invalidate already-admitted work. Operations already in flight when a pointer moves complete under the release they were admitted with (bounded by lease TTL plus reap slack, about 75 seconds).
Fail-closed proof states
| State | Structure | Money | Deny code |
|---|---|---|---|
verified-active | Full verified cohort. | Normal monetary reservation under the release's rating context. | — |
verified-stale-bounded | Only the complete last-verified cohort of the same release. | Bounded emergency reservation from the last-verified descriptor; stamped releaseProof: "emergency". | — |
unprovable-closed | Deny before upstream; no partial or fallback artifacts. | No reservation. | commercial_release_unprovable (503) |
Absence is never interpreted as proof: a missing, incomplete, hash-invalid, or scope-mismatched bundle closes admission.
Rollback
Rollback appends a new release-log entry with a greater sequence that points at an older immutable release. It never rewrites a release, never decrements a sequence, and never re-rates usage that was admitted under the rolled-back release. A later deliberate roll-forward names the rolled-back release as its expected source and receives another greater sequence.
Subscriptions and releases
A release selects the contract for new subscriptions. Existing
subscriptions stay pinned to their release for structure and to their
recurring-price pin for the fee; their usagePricing binding decides whether
metered rates follow the new catalog (current()) or not (fixedVersion).
Publication, activation, and rollback never realign subscriber pins; that is a
deferred post-launch operation.
What a release is not
- Not a Stripe object. Stripe receives subscription and recurring-price identities and settles amount due; catalogs and buckets have no Stripe counterpart.
- Not a subscriber-migration mechanism. There are no bridge roles, migration batches, or plan-release legs.
- Not mutable. Fix forward by publishing a new release.
Read Plan changes for the builder workflow and Releases for the GitHub Release process.