Anatomy of an App
What one App declaration compiles, where each rule lives, how the four App kinds differ, and which host a Customer calls.
An App is one declaration over a Product's Nouns and Verbs. SoftwareBuilder compiles every screen, route, package and plan from it, so no part carries a second copy of a rule.
Compiled from one declaration
Leaseline declares a Lease Noun, with Verbs such as Lease.renew and Lease.notify. Its App folder adds who signs in and what each Persona may call:
---
kind: saas
mount: /app
nouns: [Lease]
personas:
manager: { may: [Lease.create, Lease.renew, Lease.notify] }
resident: { may: [Lease.get] }
---Every part below compiles from that file and the records it names.
apps/portal/app.mdx and the records it names. Change the declaration, and every part follows on the next merge.Read as text
- Screens: A list and a record per Noun, a form per Verb, at leaseline.app/app, from Nouns and each Persona’s Verbs.
- API: Every Verb as a route at api.leaseline.app, from Verbs.
- SDK, CLI and MCP: The leaseline packages and MCP server, from Verbs.
- Webhooks: Every Event, signed Leaseline-Signature, from Events.
- Tenants: One per Customer, made when it accepts an Offer, from Offers.
- Sign-in and members: Passkeys, email links, single sign-on and invitations, from Personas and Access Levels.
- Plans in the App: Locked buttons, usage caps, seats and billing screens, from Offers and Entitlements.
- Admin: Every record, the data editor and Settings, from Nouns.
- Docs: leaseline.app/docs, with llms.txt and Markdown per page, from Nouns and Verbs.
- Agent renderings: Every screen as Markdown and JSON, from the same screens.
Add Lease.answer to the definition, and one merge adds its route, SDK method, CLI command, MCP tool, webhook Event and button on every Interface. A Function runs behind each Verb, written as code, run by a model, or done by a person, and the caller never sees which.
Rules live in Verbs
A rule belongs to the Verb that enforces it, never to a field or a screen. Lease.renew runs only on a lease in renewing, so its button appears only there.
A call that breaks a rule returns a refused Action that names the rule, on every Interface. So the App never holds a rule the API lacks. A person clicking and an Agent calling always agree.
App kinds
The kind key picks the App's shape. Each kind compiles the shared parts above, plus what its own users need.
kind | What it adds | Example |
|---|---|---|
saas | A Tenant per Customer, sign-in, members, and the plan inside the App | Leaseline's App for property managers |
admin | Every record across Tenants, the data editor and Settings | Leaseline's admin App, which every App gets |
directory | Public list and record pages over a Collection, with search | Ratebook's sales-tax rates by state |
commerce | A public catalog of Offers, a cart, checkout and the buyer's Orders | Kiln Bakery's weekly loaf |
saas
A saas App is private and per Customer, and no record crosses from one Tenant to another. It compiles a Tenant on each accepted Offer, with sign-in by passkey, email link or single sign-on. Invitations, and the plan's locks and caps, reach every screen.
admin
An admin App is for the people and agents who run the business. It shows every record of every Noun across Tenants, the data editor, Settings, and each Approval waiting on the reader. Every App ships one at /admin, and a Customer's admins get the same screens scoped to their own Tenant.
directory
A directory App is public. It compiles a list page and a record page for each member of a Collection, with search and filters, and readers need no account. A Verb behind an Offer, such as a bulk download, asks the reader to buy first.
commerce
A commerce App sells in public. It compiles a catalog of Offers, a cart, checkout and each buyer's Orders and receipts. A buyer signs in only to see past Orders.
Two planes
Two kinds of caller reach the same records, on two hosts.
| Caller | Host | Package and key | Sees |
|---|---|---|---|
| Leaseline's Customers and their agents | api.leaseline.app, an alias of leaseline.app/ | leaseline, LEASELINE_API_KEY | Their own Tenant, and only the Verbs their plan grants |
| Leaseline's builders: the founder and the agents | api.sb/ | startup-builder, STARTUP_BUILDER_API_KEY | Every Tenant, every Verb, and the definition itself |
Examples on these pages switch between the two with As your customer and As the builder. A Customer never sees the builder's host, packages or key names. What Customers see lists every part of that boundary.
Next
Life of a request follows one click through the parts above.