---
title: "Tenant as code"
summary: "A whole business exports as one portable YAML document that can be diffed against what is live, applied transactionally, and rolled back — so a configuration change is something you review rather than a sequence of writes you supervise."
---

# Tenant as code

A business's whole configuration — schedules, offers, resources, catalog, pricing, tiers,
pages, workflows, promotions — exports as a single portable document called a **bundle**.
A bundle can be compared against what is live, applied, and undone.

## Why this exists

Configuring a business by making fifty ordered write calls is unreviewable and
unrepeatable. A human has to supervise every call; a failure halfway leaves a half-built
business nobody can describe; and nothing can be diffed or reverted.

One document inverts all of that. It can be read before it is applied, applied atomically,
compared with what came before, and re-applied to go back. It also collapses two things
into one artefact: "what is this business?" and "make one like it" become the same file.

## Handles, not ids

Every entry in a bundle carries a **handle** derived from its natural name, and every
reference names a handle rather than an id. That is what makes a bundle portable — the
same document applies to a different business unchanged.

Where an id is unavoidably buried inside a payload the format does not own, it is
rewritten to a symbolic reference. A final pass reports any raw id that survived, so a
bundle that would not travel says so rather than looking clean.

## Configuration only

The format is an **allowlist**: a field is in a bundle because someone deliberately added
it. That means no people, no memberships, no bookings, no orders, no invoices, and no
credentials — none of it can ride along, because none of it is named.

This is the opposite of redacting. A redaction pass fails by leaking something nobody
thought of; an allowlist fails by omitting a field, which is the safer direction.

## Plan, then apply

Producing a **plan** compares a bundle against what is live and returns the minimal
difference — what would be created, which fields would change, what would be removed —
with hard-to-reverse changes flagged and explained. Planning writes nothing.

A plan can be **pinned**, which stores it exactly as shown. Applying a pinned plan either
executes that plan or refuses; it cannot quietly do something different because the
business moved underneath it. That distinction is what makes review meaningful: the thing
approved and the thing performed are the same object.

Applying lands in a history with a digest, counts, who did it and which plan it came
through — and an earlier document can be re-applied to roll back.

## Starters

Ten working businesses ship as ordinary bundles: racquet club, gym, salon, studio, restaurant, barbershop, spa, clinic, hotel and music school.
They are shaped differently on purpose, because the businesses are — one books resources
by the hour, one runs a timetable needing a room *and* a trainer, one has two appointment
lengths where the long one takes a deposit, and one is capacity-shaped rather than
resource-shaped.

Nothing about a starter is special once applied. It walks the same sections, produces the
same history and rolls back the same way.

Variables in a starter are a textual substitution, not a template language. An unset one
is refused rather than left blank — a schedule anchored to an empty timezone is wrong in
a way nobody notices until a booking lands at the wrong hour.

## Scenarios

A **scenario** runs against the real configuration with every side effect neutralised and
returns a structured verdict. Nothing is sent, charged or reserved.

Each starter ships one as its acceptance test, which is what lets an agent prove its own
work: apply a configuration, run the scenario, and get back whether the business it just
built actually functions — something to book, an offer to book it under, a customer
record to book it for.

## For agents

On the agent surface, applying a bundle is a proposal rather than an action: an agent
emits the document, and a human approves it once. See [the agent API](agent-api.md).
