loftur

Lifecycles

How the loops stay decoupled

The three loops — site code, schema, content — are not joined at the hip, and that's the point. They touch in exactly two places. Everything else runs independently.

What is independent

  • Content changes without republishing code. Editors publish records; the live site re-reads content every request. No publish_site.
  • Schema expands without touching code. New models and fields are additive and invisible to existing published queries.
  • Site code drafts freely. Write and preview all you want; only publish_site validates and snapshots.

The two coupling points

Both are about one thing: never letting a live site reference schema that isn't there.

  1. Publish-time validation. publish_site validates every GraphQL document against the live schema. You can't publish code that references a field or type the schema doesn't have.
  2. Contract-time footprint check. The guard refuses to drop schema the currently published site still queries.

Publishing new site code atomically swaps the contract (a fresh footprint). Until then, the old footprint protects the live site. That's the entire coupling mechanism — a one-way constraint checked at two moments.

Why this matters

An editor ships a typo fix while a developer is mid-refactor. The developer expands the schema without breaking live content. A bad code publish rolls back without touching a single record. Three people, three cadences, zero coordination overhead.

The alternative — one pipeline for code, schema, and content — forces every change through the slowest, riskiest common denominator. Decoupling the loops is what lets each move at its own speed while the contracts guarantee they never contradict each other. Who is allowed to turn which knob is enforced by tokens and scopes.