Context
Without app folders (0436), a product repository needs one agreed place for what Runway and the brand kit read: icons, splash screens, store listings, landing seeds and brand sources. Each product repository today has abrand/ folder made by the OS brand kit, mixing hand-made sources,
design exploration and generated files. The root runway.yaml already declares the product
(0335 decision 2)
and has no way to name surfaces or mobile apps. Runway, which must run the brand kit in CI, is Stackra and may not
depend on Figentra code, so the owner split the brand kit on 2026-10-26 (amending decision D17): the generic generator
moves to Stackra and Figentra keeps only its own kit.
Decision
-
Every product repository has a root
assets/tree. Each folder has aREADME.mdsaying what goes there (sizes, formats, names) and a.gitkeep. The Stackra product template scaffolds it. -
No
apps/folder by default. Surfaces and mobile apps are declared in the root runway (decision 3), not in app members. -
The root runway names surfaces and mobile apps. Beside
product, the rootrunway.yamlgainssurfaces(per surface: the shell line, the packages, the host;contributesfor the ops console; for landing,content, the product’s own domain per environment and which host is canonical, as 0440 decision 6 sets),mobile(per app: the template line, packages,assetsandstorepaths, identity, capabilities, store accounts, EAS project) andassets(the tree’s root, when not the default). Runway builds and publishes the bundles, registers platform hosts and theirhost:andwellknown:rows (0437), imports landing seeds once (0440) and builds mobile apps (0439). -
Brand sources live in
assets/brand. A product’sbrand/folder moves toassets/brand/and keeps only sources: the marks, the kit configuration (kit.json: the symbol, the theme file and the colour roles of icons, splash screens and store frames, beside the owner’s concept, logo rules and asset manifest), decisions, the Arabic review and the version history. The product’s accent layer stays in@figentra/brand(0340 decision 11), so the family separation test still sees every product. Fonts stay the OS design record’s (0340 decision 11 refuses per-product type exceptions); a product kit keeps only the licence notes for fonts it already uses until the owner decides otherwise. -
The brand kit is split: a Stackra generator and Figentra’s own kit.
- The generic generator is the Stackra package
@stackra/brand-kit. It reads a kit configuration (assets/brand/kit.json) and the theme file the kit names (a@stackra/tokenstheme, committed beside the kit so CI needs no Figentra package; how a product exports it from@figentra/brandis open) and generates tokens, HeroUI CSS, app icons and adaptive icons, splash screens, favicons and the web manifest, and the frames for store screenshots. It holds no Figentra identity and no colour logic of its own. - Figentra’s parent kit, its marks and its endorsement rules stay in
figentra/os/tools/brand-kit, as data the generator reads. - A product’s sources stay in its
assets/brand(decision 4). - Runway runs
@stackra/brand-kitas a CI step. Its outputs are build artefacts, never committed (owner decision of 2026-10-26). Runway depends on no Figentra code.
- The generic generator is the Stackra package
-
Exploration is archived. Once a direction is picked, the exploration (directions, book drafts, the comparison
page) moves to
assets/brand/versions/as a record and is never deleted, as the kits already keep retired identities. -
Store screenshots are captured. A CI job runs the built app on a simulator with demo data and the product theme,
captures each screen per locale, and the brand kit adds frames and captions from
assets/store. The job runs on a CI runner, never on a developer’s machine.
Consequences
- One layout for every product; Runway and the brand kit know where everything is without per-repo config.
- Brand changes are reviewed as source changes; the generated set is reproducible from sources in every build.
- Every product repository has a one-time move of
brand/intoassets/brand/. - The generator becomes Stackra work (
@stackra/brand-kit, published like any@stackra/*package), carrying 0340 decision 10’s determinism check and literal scan, which now gate a CI step;figentra/os/tools/brand-kitshrinks to Figentra’s parent kit, marks and endorsement rules. - Store screenshots need a simulator lane on a CI runner.
Enforcement
- planned — Runway’s schema validates
surfaces,mobileandassets, and refuses paths outsideassets/. - planned — a repository check fails when generated brand outputs are committed (the kit’s asset manifest lists them).
- planned — the product template’s scaffold check fails when an
assets/folder lacks itsREADME.md. - planned — the validator refuses a
@figentra/*dependency in@stackra/brand-kitand in@stackra/runway.
Supersedes and sources
Supersedes: none. Sources: stackra-notes handover/app-shells/app-shells-edge-and-extension.md sections 8, 15
(point 1) and 16 (point 9), owner decisions D16, D17 (as amended on 2026-10-26), D18 and D19, and
handover/app-shells/review-runway-2026-10-26.md (“Owner decision taken since the drafts”).