Type to search pages and rules.

Browse pages

Plans and Entitlements

A product that sells tiers promises each plan a set of entitlements: the behavior the plan unlocks and the amounts it allows. This page states how the product records its plans, how behavior and amounts resolve to what the acting plan entitles, and how the product answers a run past its plan. A project selects it when customers buy different tiers, so a plan change moves one record instead of scattered checks.

Markdown8 provisions

Activation#

Activation scope: project.

Applicable specification kinds: None.

The project selects plans when it sells more than one tier, or gates behavior by entitlement within one offering. A single offering with no gated behavior does not select it: without tiers there is nothing to entitle.

Baseline Relationship#

This extension replaces no baseline provision. It sits beside the multitenancy extension: tenancy isolates each tenant's data, while plans state what each tenant's tier allows.

It switches on no record type: plans live as business requirements, gated behavior resolves through permissions, and gated amounts resolve through limits, which the product page, the access page, and the model page state.

Standards#

Record Each Plan Once#

ruleguidance
litespec/ext/plans#record-each-plan-once
Statement

A consumer selecting plans MUST record each plan once with its name, price, billing period, and entitlements.

Why

A plan named in two places disagrees the day one updates without the other: the price page promises what the gate refuses. One record per plan holds the name, the price, the billing period, and the entitlements, so a plan change is one edit with one owner.

Example

The monthly plan names its fee, its month period, and the use cases and amounts it unlocks.

Checka reviewer answers

The requirement pages under docs/product/ hold one record per plan with its price, billing period, and entitlements.

Marked guidance: a reviewer answers this question.

Gate Behavior Through Permissions#

ruleguidance
litespec/ext/plans#gate-behavior-through-permissions
Statement

A gated use case MUST need a permission that only an entitled plan grants.

Why

The permission chain already joins actors to use cases: the actor holds a role, the role allows a permission, and the use case needs it, as the access page states. A plan grants its permissions through that chain, so entitlement is a grant like any other instead of a second access system beside the first.

Checka reviewer answers

Each gated use case names a permission in needs that only an entitled plan grants.

Marked guidance: a reviewer answers this question.

Bound Plan Amounts in Limits#

ruleguidance
litespec/ext/plans#bound-plan-amounts-in-limits
Statement

Each amount a plan allows MUST live as a limit the gated use case names.

Why

An allowance buried in code changes only with a release, and each plan's number hides in a different branch. A limit the gated use case names holds each allowance beside the use case it bounds, so raising a tier edits the limit instead of the code.

Checka reviewer answers

Each plan allowance lives as a limit the gated use case names.

Marked guidance: a reviewer answers this question.

Refuse Runs Beyond Entitlement#

ruleguidance
litespec/ext/plans#refuse-runs-beyond-entitlement
Statement

A use case run past its plan MUST end in the refusal result the use case names for that run.

Why

A run past its plan is a refusal like any other: it ends in the named refusal result with its stable code, as the domain page states, so callers branch on one code instead of guessing from an error page. The code stays stable while prices and allowances move.

Checka reviewer answers

A run past its plan ends in the named refusal result in the use case tests.

Marked guidance: a reviewer answers this question.

Resolve the Acting Plan from Trusted Context#

ruleguidance
litespec/ext/plans#resolve-the-acting-plan-from-trusted-context
Statement

The product MUST resolve the acting plan from verified subscription state, never from caller input.

Why

The plan decides what runs, so only verified subscription state resolves it: a plan the caller supplies itself is a choice, not a fact. The multitenancy extension treats tenant identity the same way.

Checka reviewer answers

The acting plan resolves from verified subscription state, with no plan taken from caller input in code.

Marked guidance: a reviewer answers this question.

Hide Unentitled Actions on Screens#

ruleguidance
litespec/ext/plans#hide-unentitled-actions-on-screens
Statement

A screen MUST NOT offer an action the acting plan does not entitle.

Why

The server refuses what the plan does not entitle, and the screen reflects that refusal before the call: a button for an unentitled action invites a failure the product already decided. Hiding or disabling the action shows each plan only what it may run.

Checka reviewer answers

Each screen shows only actions the acting plan entitles.

Marked guidance: a reviewer answers this question.

Conventions#

Resolve the Acting Plan in the Authorization Pipeline#

conventionguidance
litespec/ext/plans#resolve-the-acting-plan-in-the-authorization-pipeline
Default

Resolve the acting plan where the pipeline authorizes the use case.

ReplacementA consumer records a plan-resolution convention naming where its use cases find the acting plan.

Why

Authorization already runs in the pipeline with the actor and the target in hand. Resolving the plan there gives every use case the same answer from the same verified state, instead of each handler querying subscriptions its own way.

Checka reviewer answers

The authorization pipeline resolves the acting plan, or the plan-resolution convention names where use cases find it.

Marked guidance: a reviewer answers this question.

Record Plan Prices as Business Requirement Values#

conventionguidance
litespec/ext/plans#record-plan-prices-as-business-requirement-values
Default

Record each plan price as values on its business requirement.

ReplacementA consumer records a plan-price convention naming where its plan prices live.

Why

A business requirement carries its values with effective dates, as the product page states, so each price shows when it holds. Recording each plan price there keeps the commercial fact with the commitment it prices.

Checka reviewer answers

Each plan price sits as values on its business requirement, or the plan-price convention names where prices live.

Marked guidance: a reviewer answers this question.

Dependencies#

Packages: None.

Related extensions: The tenancy extension owns tenant isolation when tenants buy different tiers. The audit extension owns tamper-resistant evidence when an entitlement decision needs a record.

Guides: None.

Verification#

IDMarkEvidence
litespec/ext/plans#record-each-plan-onceguidanceThe requirement pages under docs/product/ hold one record per plan with its price, billing period, and entitlements.
litespec/ext/plans#gate-behavior-through-permissionsguidanceEach gated use case names a permission in needs that only an entitled plan grants.
litespec/ext/plans#bound-plan-amounts-in-limitsguidanceEach plan allowance lives as a limit the gated use case names.
litespec/ext/plans#refuse-runs-beyond-entitlementguidanceA run past its plan ends in the named refusal result in the use case tests.
litespec/ext/plans#resolve-the-acting-plan-from-trusted-contextguidanceThe acting plan resolves from verified subscription state, with no plan taken from caller input in code.
litespec/ext/plans#hide-unentitled-actions-on-screensguidanceEach screen shows only actions the acting plan entitles.
litespec/ext/plans#resolve-the-acting-plan-in-the-authorization-pipelineguidanceThe authorization pipeline resolves the acting plan, or the plan-resolution convention names where use cases find it.
litespec/ext/plans#record-plan-prices-as-business-requirement-valuesguidanceEach plan price sits as values on its business requirement, or the plan-price convention names where prices live.