Skip to content

Compound software

The compound-software thesis — the catalog grows without breaking compositions

Atelier's commercial bet is that adding a building block never breaks an existing composition. Three independent registries make this concrete, and all three are live:

  • Any entity renders in any widget. The surface plane compiles a page_template into an ordered list of declarative Block descriptors, each dispatched to a WidgetKind by a tester/priority resolveWidget registry inside ONE presentation-only renderer. A new widget is a new registry entry with a tester; it cannot break existing pages because dispatch is by priority over known-good keys (invariant TH-08: only known-good registry-key literals reach the DOM). Entities and widgets are decoupled by the Binding between them.

  • Any action fires from any surface. An action_placement row projects an action_type onto a surface as a button or form. Read-time availability reuses the exact same gate criteria the submit lane enforces, so a CTA shown is an action permitted — they cannot drift. A new placement adds a row; the action and its gates are unchanged.

  • Any aggregate is a view; any view is a surface. Aggregates are ontology VIEWS (the only sanctioned aggregate primitive), surfaced either as Metabase cards (staff) or source_kind:view public feeds (citizen). A new KPI is a view row plus a surface row — never a bespoke endpoint.

Why the catalog can grow safely: every primitive is declared as a row class with a registry key, and the seam between authoring and rendering is Block[] + registry keys — not bespoke components. The design-system stays presentation-only; editing/authoring metadata lives in a separate host layer keyed to the same render registry (the SOTA pattern — Puck/Builder/Sanity). This is the structural reason a tenant can fork the catalog and extend its copy without the platform author's future additions colliding: additions are additive registry entries and additive rows, governed by additive-only schema evolution (the ontology never deletes a column).

Where the thesis is not yet fully true (named honestly): the admin host drives the converged renderer only for aggregate charts today — KPI cards and Metabase embeds are still bespoke, so "one renderer drives admin" is charts-only, not total. Block.children grid nesting is reserved, not shipped. And there is no single enumerable widget catalog yet (three overlapping lists: _entries, WIDGET_ENTRIES, AGGREGATE_CHART_CANDIDATES). These are convergence debt, not design breaks.

Atelier — Platform Specification. Internal canonical reference.