> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stackra.figentra.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 0335 — Editions: a product made of another product's modules, its own packs, its brand and its entitlement bundle

> Accepted · 2026-10-24

> [!NOTE]
>
> Amends, by Notes, [0109](https://docs.stackra.figentra.com/adr/0109-registry-manifests-published-by-ci.md) (the registry records
> products and editions), [0296](https://docs.stackra.figentra.com/adr/0296-runway-v3-member-requires-and-root-topology-groups.md) (the
> root runway's `product` section) and
> [0326](https://docs.stackra.figentra.com/adr/0326-app-identity-desktop-section-pwa-config-shortcuts-and-native-widgets.md) (a `brands`
> list beside `identity`). Reads with the notes of 2026-10-24 on
> [0201](https://docs.stackra.figentra.com/adr/0201-the-app-split-framework-platform-core-and-first-party-apps.md) and rule 22 of
> [0334](https://docs.stackra.figentra.com/adr/0334-final-structure-review-round-up-decided-rules-without-an-adr.md).

## Context

The owner decided on 2026-10-24, in the Muslin rethink, that commerce is a product of its own above Figentra OS, and
that Muslin is its fashion edition: the same commerce engine, with fashion packs, a brand and a plan ladder of its own.
Other verticals follow as other editions. Nothing in the ADRs says what an edition is, where it is declared, how the
registry lists it, how runway deploys it, or how its apps are built and branded. Without a rule, each edition would
become a fork of its base product, which is the thing the module model exists to prevent
([0259](https://docs.stackra.figentra.com/adr/0259-module-placement-three-homes.md), [0200](https://docs.stackra.figentra.com/adr/0200-stackra-and-figentra-os-horizontal-services-private-os-repo.md)).

## Decision

1. **An edition is a product.** An edition is a first-party product (layer 3 of
   [0201](https://docs.stackra.figentra.com/adr/0201-the-app-split-framework-platform-core-and-first-party-apps.md)) that is made of another product's
   modules, called its base, plus its own packs, its brand and its entitlement bundle. It has its own repository, its
   own app members and its own plan ladder. Muslin is an edition of Figentra Commerce (working name); Figentra Commerce is a product
   above Figentra OS and is not an edition. It is built in its own repository from its design records; the thin
   commerce reference slice planned for this repository stays a reference app under
   [0075](https://docs.stackra.figentra.com/adr/0075-stackra-ships-packages-figentra-os-ships-services.md) decision 2, proves the framework, and
   seeds no product.

2. **Declared once, in the root runway.** The edition's root `runway.yaml` declares a `product` section:
   `product: { key, edition: { of: <base product key>, version: <range> } }`. A product with no `edition` is a base
   product. The key is the product's registry key, and the base's version range names the released base manifests the
   edition builds against. This is the one place the relation is written; nothing in code repeats it.

3. **The base is consumed as released packages and clients, never as a fork.** An edition imports the base product's
   modules the way Figentra OS imports Stackra packages ([0200](https://docs.stackra.figentra.com/adr/0200-stackra-and-figentra-os-horizontal-services-private-os-repo.md)
   decision 2): released versions from the registry, a local link only in a development profile and never in CI. It
   calls the base's services through the generated clients and listens to the base's integration events. It never
   copies a base module into its own tree.

4. **Packs are ordinary modules.** An edition's own features are modules in one of the three homes of
   [0259](https://docs.stackra.figentra.com/adr/0259-module-placement-three-homes.md): the edition's service, or an edition package when two of its members
   share them. A pack that extends a base model or a base screen does it through
   [0336](https://docs.stackra.figentra.com/adr/0336-edition-additions-typed-fields-on-another-products-models-and-screens-in-its-panel-slots.md), never by
   editing the base.

5. **The registry lists editions.** The registry of [0109](https://docs.stackra.figentra.com/adr/0109-registry-manifests-published-by-ci.md) records a
   product's manifests under its key and, for an edition, the base key and version range. The marketplace lists an
   edition as an installable product. A tenant installs an edition, not a base plus packs: the base's modules that the
   edition bundles install with it.

6. **The entitlement bundle is one plan ladder.** An edition has its own plan ladder in the form of
   [0242](https://docs.stackra.figentra.com/adr/0242-commercial-model-plan-ladder-add-ons-metric-and-trial.md), and each tier's effective set
   ([0215](https://docs.stackra.figentra.com/adr/0215-entitlements.md)) bundles the module entitlements of the base that the edition sells with its own.
   A tenant on an edition plan never buys the base separately, and a base entitlement the edition does not bundle is
   not available to that tenant.

7. **One brand per edition, per-tenant branding at run time.** The edition's brand (tokens overlay, name, lang
   catalogue, store listing text) is build-time data of its app members, written once in the `identity` section of
   [0326](https://docs.stackra.figentra.com/adr/0326-app-identity-desktop-section-pwa-config-shortcuts-and-native-widgets.md). Within an edition, a tenant's
   own branding is run-time data through the experience service (receipts, lock screens, the staff app's chrome), as
   the tenant branding rules already allow. An edition therefore has one staff app codebase, published under the
   edition's name and branded per tenant at run time.

8. **Per-brand builds come from a `brands` list.** An app member that is built per retailer brand (a white-label
   shopper app) declares `brands: [...]` beside `identity` in `stackra.config.ts`; each entry carries its own
   `identity` (app id, bundle ids, names, store listing) and its brand tokens. Such an app is not our own app, so it uses the free `@stackra/ui` only ([0310](https://docs.stackra.figentra.com/adr/0310-stackra-ui-pro-private-heroui-pro-wrappers.md) as amended the same day). Gen runs the app build once per brand,
   from the same codebase, with that brand's identity in place. Content for a shopper app comes from the page builder
   ([0114](https://docs.stackra.figentra.com/adr/0114-page-builder-for-every-page.md)) per tenant; the build carries no tenant content.

9. **Shared by every edition of a base.** Pricing and Markets, the payments ledger, invoicing, identity, tenancy and
   the other OS modules stay in the OS and reach an edition through its base, by the placement rule of
   [0334](https://docs.stackra.figentra.com/adr/0334-final-structure-review-round-up-decided-rules-without-an-adr.md) rule 22.

## Consequences

* A vertical is an edition, so a new vertical is packs, a brand and a ladder, and never a second commerce engine.
* The relation to the base is one line in runway, so runway and the registry can check an edition against its base's
  released versions, and an upgrade of the base is a version bump in the edition.
* A white-label app is a brand entry and a build, not a repository.
* An edition's tenant sees one product in the marketplace and one plan ladder, and never a bill for the base.

## Enforcement

* planned — runway validator (STA-339): an `edition` whose base key is unknown to the registry, or whose version range
  matches no released base manifest, fails; a product key that collides with another product fails.
* planned — gen (STA-340): a `brands` entry without a complete `identity` fails, and two brands with the same app id
  fail; an edition member that imports a base module from source rather than a released package fails the boundary
  check.
* planned — the registry refuses an edition manifest whose bundled module entitlements are not entitlements of its
  base.

## Supersedes and sources

Supersedes: none. Amends, by Notes: [0109](https://docs.stackra.figentra.com/adr/0109-registry-manifests-published-by-ci.md),
[0296](https://docs.stackra.figentra.com/adr/0296-runway-v3-member-requires-and-root-topology-groups.md) and
[0326](https://docs.stackra.figentra.com/adr/0326-app-identity-desktop-section-pwa-config-shortcuts-and-native-widgets.md). Builds on
[0200](https://docs.stackra.figentra.com/adr/0200-stackra-and-figentra-os-horizontal-services-private-os-repo.md),
[0201](https://docs.stackra.figentra.com/adr/0201-the-app-split-framework-platform-core-and-first-party-apps.md),
[0215](https://docs.stackra.figentra.com/adr/0215-entitlements.md), [0242](https://docs.stackra.figentra.com/adr/0242-commercial-model-plan-ladder-add-ons-metric-and-trial.md),
[0259](https://docs.stackra.figentra.com/adr/0259-module-placement-three-homes.md) and
[0334](https://docs.stackra.figentra.com/adr/0334-final-structure-review-round-up-decided-rules-without-an-adr.md). Sources: the owner's Muslin rethink
decisions of 2026-10-24 (STA-451), restated in this ADR's own words.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.