Skip to content

The Atelier Lifecycle

Every application in Atelier follows the same path: you declare it once, Atelier generates the running experience, you fork it onto each tenant, it runs in production, and you evolve it in place. You describe what the application is — its data, its actions, its surfaces — and the platform builds, wires, and serves the rest.

This page walks the full lifecycle end to end.

1. Author

You author an application as a single declaration that spans all three planes of the platform:

PlaneWhat you declareExamples
DataThe entities your application storesrecord types, fields, relationships
ExecutionThe actions users can takestate transitions, side effects, workflows
SurfaceWhere the application appearspublic portal pages, map layers, admin views

Alongside these you declare supporting concerns in the same place: aggregate views, notifications, authorization rules, and presentation config. Everything belongs to one application, identified by its own code.

You can write the declaration directly, or build it live in Atelier's authoring surfaces — the visual editors round-trip to exactly the same definitions, so there is one source of truth no matter how you author.

A small, illustrative slice:

yaml
identity:
  code: streetlight-faults
  name: Streetlight Faults
  is_active: true

entities:
  - entity_type: fault_report
    schema:
      display_name: Fault Report
      tenant_scoped: true
      fields:
        - field_key: status
          field_type:
            type: enum
            choices:
              - { value: new, label: New }
              - { value: triaged, label: Triaged }
              - { value: resolved, label: Resolved }
        - field_key: location
          field_type: { type: geometry }
        - field_key: reported_at
          field_type: { type: datetime }

actions:
  - key: triage_report
    label: Triage
    target_model: fault_report
    execution_mode: engine
    status: published
    is_active: true
    submission_criteria:
      - key: must-be-new
        criteria_type: field
        config: { field: status, operator: eq, value: new }
        order: 1
        is_active: true
    edits:
      - { key: set-triaged, field: status, value: triaged }
    side_effects:
      - { key: report_triaged, type: notification, event_type: report_triaged, event: report_triaged, order: 1, is_active: true }

That is the whole contract. You never write a controller, a migration, an admin screen, or a permissions check by hand.

2. Generate

When you import a declaration, Atelier runs it through a single, predictable pipeline — parse, validate, diff, apply — and provisions the application into the platform. Imports are idempotent: re-importing converges to the declared state rather than duplicating it, so you can iterate freely.

Two front doors lead to the same place: a direct import and the authoring-hub round-trip. Both produce the same generated application:

  • A vocabulary of types and registries that the rest of the platform reasons about.
  • A template application — a fully worked, runnable example of your application that becomes the blueprint for every tenant.

From your declaration, Atelier generates the data model, the action engine, the public and staff surfaces, the authorization policy, and the notification routing — all at once, all consistent with each other.

3. Fork

You bring a new tenant online by forking the template. In a single operation, Atelier copies every part of the application marked as forkable into the new tenant's own isolated space and rewires all the internal relationships to point within that space.

This is copy-on-create, and it is the heart of Atelier's tenancy model:

  • Each tenant gets its own independent copy of the application — its own data, its own configuration, its own surfaces.
  • Tenants are isolated by construction. One tenant's data and configuration are never visible to another.
  • Making a new part of your application forkable is a declaration, not a code change: mark a type as forkable and it travels with every fork automatically.

Because forking copies rather than links, every tenant is free to diverge — which is exactly what makes the next stage possible.

4. Run

Once forked, the generated experiences serve real traffic.

Citizens use the portal. Public-facing pages are generated directly from your surface declarations. Every public read passes through layered admissibility and row-level authorization gates and a disclosure projection before any data leaves the platform — so the portal shows precisely what you declared as public, and nothing more.

Submissions are durable from the first millisecond. When a citizen submits, Atelier writes a durable submission record before any entity exists and acknowledges immediately. A durable workflow then materializes the full record. A submission is never lost to a transient failure.

Staff use the admin console. Generated list views, detail pages, and dashboards all render through a single shared renderer — the same rendering engine drives both the citizen portal and the staff console, so a widget looks and behaves identically wherever it appears.

Actions run through one uniform engine. When a user fires an action, Atelier runs it through a consistent pipeline every time: validate the input, check authorization and preconditions, apply the change, record an audit entry, and fan out any side effects. Because every action shares this pipeline, behavior is predictable and every change is accountable.

Notifications are routed as data. When an action emits a notification event, Atelier resolves the subscribing notification rules for that tenant, applies their filters and precedence, and dispatches each one as a durable workflow. Adding or changing a notification is an authoring change, not an engineering one.

5. Evolve

Because each tenant owns its forked copy, evolving an application is a first-class, everyday operation.

Tenant admins edit their own application. A tenant administrator opens the same editors and changes their own copy directly — they own their space, so no special mode or impersonation is involved.

Platform authors evolve the template. Authors edit the template application through the same authoring surfaces. Atelier keeps preview and live identical and compiles on save: publishing a change synchronously regenerates everything that depends on it — including the authorization rules — so the reader and the writer of every surface always agree by construction. There is no moment where a published surface is visible but not yet permissioned.

This is the loop that makes Atelier productive: declare, generate, fork, run, and evolve — each tenant a living, independently-editable instance of an application you described once.

Built-in confidence

Atelier is designed so that the running system reflects your declaration and nothing else. That guarantee is backed by capabilities built into the platform rather than bolted on after the fact:

  • Idempotent, convergent imports mean re-applying a declaration always lands the system in the declared state.
  • Validation at author time catches malformed declarations before they ever reach a tenant.
  • Build-time checks verify that surfaces are correctly rooted, placements resolve, and navigation is wired — so a generated application is coherent before it serves a single request.
  • Fail-closed authorization ensures that when a policy can't be resolved, access is denied, never granted.
  • End-to-end audit records every action, giving you a complete, queryable history of what changed and who changed it.

The result is an application you can trust on day one and keep evolving with confidence — because the platform proves the system matches the declaration at every step of the lifecycle.

Atelier — declare your application, generate the product.