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 log — app_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.