Documentation
ReferenceArchitecture

Core concepts

Tabbify is an office for your AI: you describe an outcome in chat, the AI writes the code, and the platform runs it as a real service. This page is the mental model that ties the pieces together — what an office holds, how an app becomes a running process, how those processes find each other, and where the human stays in the loop.

Offices and apps

An office is the bounded namespace you own: its apps, services, secrets, and approvals. The chat is your control plane; everything below is runtime.

An app is a workload identified by a UUID v7. You publish it with the CLI, which uploads artifacts to object storage and stamps the identity into a tabbify.lock:

tcli push ./my-app

A single tabbify.toml is the source of truth — [app] metadata, [build], [runtime] defaults, and [[deploy]] targets.

Runtimes

The runtime is chosen at deploy time per target, not baked at build time. The same image can run three ways:

[[deploy]]
supervisor = "thinkpad"
runtime    = "firecracker"   # overrides [runtime].type for this target

wasm-http runs in-process (wasmtime), docker runs a container, firecracker runs a microVM. Supervisors advertise what they can actually run as mesh tags (docker if the daemon answers, firecracker only with /dev/kvm), and the node validates a target before placement. See Runtimes and The Runtime.

The private mesh

Apps do not listen on the open internet. They join a WireGuard overlay where each app gets a deterministic IPv6 address derived from its UUID:

fd5a:1f02:<blake3(uuid)>::1

The address is stable across restarts and host migrations, so one service always finds another at the same place — no discovery dance. A supervisor spawns a detached runner per app on this address; the node proxies your requests to it. Full detail in Private Mesh and Routing.

Events and approvals

State changes are recorded as an append-only event logapp_registered, app_started, secret_registered. The log is the source of truth: recovery is replay, and every API mutation flows through it for audit.

Two honest caveats today: the event stream is fire-and-forget (a subscriber that connects late misses an event; recent ones sit in a ring buffer), and the approval card — the chat widget that lists requested capabilities like telegram:send before anything runs — is designed but not yet wired in the frontend. Secrets never reach the prompt: they live in an encrypted store and are injected as environment, never written to the log. See Services & capabilities.