Skip to content

Latest commit

 

History

History
179 lines (150 loc) · 9.03 KB

File metadata and controls

179 lines (150 loc) · 9.03 KB
title Key concepts
description The four nouns, the credential firewall, and how credits flow.

The four nouns

UseZombie has four primary objects. Everything else is infrastructure.

Your top-level billing and identity boundary. Created automatically on first Clerk sign-in. Carries the **credit balance** ($10 seeded on signup) and the default Stripe customer. A container for zombies and credentials. One tenant can have many workspaces (team, project, environment). Credits are **not** fragmented per workspace — all workspaces debit the same tenant wallet. A persistent, always-on agent process. One zombie has one `SKILL.md` + `TRIGGER.md`, one trigger, a set of skills, and a set of credentials (secrets it uses but never sees). Lives inside a workspace. A named tool a zombie's agent can invoke. Skills are declared in `TRIGGER.md` as bare tool names; the runtime injects the credential and executes the call outside the sandbox when the agent invokes one. Examples: `kubectl`, `docker`, `github`, `slack`. Constraint policy (which verbs the agent may use, what it must never do) lives as prose inside the zombie's `SKILL.md` — not as YAML allowlists or per-skill sub-directories.

How they relate

Tenant (wallet: $10.00)
├── Workspace: "home"
│   ├── Zombie: homelab-diagnostic
│   │   └── Tools: kubectl, docker, ssh  (read-only policy in SKILL.md)
│   └── Zombie: homebox-audit
│       └── Tools: docker, kubectl, tls-probe  (enumerate-only policy in SKILL.md)
└── Workspace: "work-sandbox"
    └── Zombie: pr-reviewer
        └── Tools: github, slack  (comment-only policy in SKILL.md)

Every run debits the same tenant balance, regardless of which workspace the zombie lives in. This is the single-wallet, multi-workspace model introduced with v2 — there are no per-workspace credit pools and no workspace-scoped top-ups.

Credits

New tenants start with $10 (1000¢) seeded at signup. There are no tokens to enter, no gates to clear — the balance lands the moment Clerk completes your first sign-in.

  • Debits happen on completed runs only. A zombie run that fails mid-execution, hits a budget ceiling, or is killed before producing output does not debit the tenant balance.
  • Top-ups are tenant-scoped. Adding credit in one workspace's billing page is a misleading frame; all credit is on the tenant. The billing UI at app.usezombie.com/billing lives at the tenant level.
  • Scale plan is usage-based. Once on Scale, completed-run billing switches from flat cost to metered compute + token consumption. The "completed run only" rule still applies.

See the Billing and cost control page for the full breakdown.

Core terminology

A persistent, always-on agent process. A zombie has a config (YAML + markdown), a trigger (how it receives events), a set of skills (what tools it can use), and a set of credentials (secrets it needs — but never sees). Once started, a zombie runs continuously, restarts on crash, and waits for events on its inbox queue. A zombie is defined by two files in a directory: `SKILL.md` (agent instructions, natural language) and `TRIGGER.md` (machine-readable config, YAML frontmatter + optional human description). The CLI uploads both files on `zombiectl up`; the server parses `TRIGGER.md` and stores the `SKILL.md` body as the agent's system prompt.
```markdown TRIGGER.md
---
name: homelab-diagnostic
trigger:
  type: webhook
  source: custom
  event: message.received
skills:
  - kubectl
  - docker
credentials:
  - kube_homelab
budget:
  daily_dollars: 5.0
  monthly_dollars: 29.0
network:
  allow:
    - k8s.home.tailnet
---

This zombie investigates homelab incidents, read-only.
```

```markdown SKILL.md
You are a homelab diagnostic agent...
```

See [Authoring skills](/zombies/skills) for the full `TRIGGER.md` reference.
How a zombie receives events. Currently supported: `webhook`. The `source` field is a human-readable label (e.g. "email", "github", "slack") — it appears in the activity stream but is not used for routing. Routing uses the zombie's unique ID. The `signature` block declares how inbound requests are authenticated — pointing at vault keys via `signature.bearer_ref` or `signature.secret_ref`. A named tool available to a zombie's agent — the only way agents interact with external services. Skills are declared in `TRIGGER.md` as bare tool names; the runtime injects the credential and executes the call outside the sandbox. Examples: `kubectl`, `docker`, `github`, `slack`.
Tool **policy** — which verbs the agent may use, which resources it must never touch —
lives as natural-language prose inside the zombie's `SKILL.md` (the system prompt the
agent reads). This is deliberate: YAML allowlists and per-skill sub-directories are
premature abstraction until a second zombie reuses the same policy. The prose is the
contract the agent reasons against today, and the contract a structural enforcer will
gate against tomorrow.
The security boundary between your secrets and the agent. Credentials are stored encrypted in the vault. When an agent invokes a skill, the firewall retrieves the secret, makes the outbound API call, and returns only the response. The agent process never receives the raw credential — not as an environment variable, not as a function argument, not in any log. If the agent is compromised, your keys are not.
For self-hosted deployments, the vault lives on the worker inside your network. The
UseZombie control plane never sees the raw secret.
An append-only record of every action a zombie takes. Every event received, every skill invoked, every response returned — timestamped and queryable. `zombiectl logs` streams the activity stream in real time. The stream is stored in Postgres and paginated by cursor for replay and debugging. The persisted state between event deliveries. After each event is processed, the zombie's agent state (conversation history, working memory) is checkpointed to Postgres. If the process crashes, the next event picks up from the last checkpoint. This is what makes zombies stateful between events — they remember context from one delivery to the next. Stop a zombie immediately from `zombiectl kill` or the web UI. The running agent process is terminated mid-action — no new events are processed, no further billing. The zombie's state is preserved so it can be restarted cleanly. Use the kill switch when an agent is misbehaving or consuming unexpected resources. Dollar ceilings declared in `TRIGGER.md`. `daily_dollars` caps spend over a rolling 24-hour window; `monthly_dollars` caps spend over the calendar month. If either ceiling is hit, the zombie stops processing new events and a budget breach is recorded in the activity stream. One bad prompt never becomes an infinite burn. Per-event token and wall-clock caps are internal runtime controls and are not user-configurable in `TRIGGER.md`. The embedded agent runtime that executes inside the sandbox. NullClaw receives the zombie's instructions, injected skill definitions, and events, then produces responses and skill invocations. It operates inside an isolated sandbox process and has no direct access to credentials or external networks — everything flows through the firewall. The sidecar process (`zombied-executor`) that owns the sandbox lifecycle. The executor spawns NullClaw agents inside isolated sandbox containers, enforces resource limits (CPU, memory, time), and reports execution results back to the event loop. The persistent process that drives a zombie. The event loop claims a zombie from the dispatch queue, loads its config and session checkpoint, waits for events on its Redis Streams inbox, delivers each event to NullClaw, checkpoints state after processing, and acknowledges the Redis message (at-least-once delivery). Events are processed sequentially — a zombie's mailbox is ordered.