Concepts
This page covers the building blocks of Catentio: what each object is, how they relate to each other, and the lifecycle they go through. Read this before going deep on any specific feature — the rest of the docs assume you know what an agent, a run, and a project are and how they differ.
The model
Workspace
├── Agents (named: hachimi, tora, sai, ren, fumi, iro, …)
│ └── Runs
│ ├── Child runs (delegation, linked by parent_run_id)
│ └── Events ← fine-grained execution trace, replayable
├── Workflows (versioned pipeline phase graphs)
├── Projects
│ ├── Tasks (one per phase)
│ │ └── Subtasks (agent | action | gate)
│ │ └── Attempts
│ ├── Attachments
│ └── Artifacts (versioned per phase; current + superseded)
├── Tools (per-agent, scoped capabilities)
├── Skills (versioned playbooks)
├── Memory (entries, OTP-gated mutations)
├── Heartbeats (cron-like agent triggers)
├── Integrations (BYO OpenAI / ElevenLabs / Google / GitHub …)
├── API keys
└── Output destinations
Everything is scoped to a workspace deployment — the tenancy boundary that ties a Huudis workspace to a running catentio instance. The control plane derives a customer_id from the Huudis workspace id, and every other object (agents, runs, projects, memory, tools, skills, API keys, integrations, output destinations) is scoped to that customer_id. Cross-workspace queries don't exist.
Workspace
A workspace deployment is one row per Huudis workspace that has a catentio instance behind it — the gate between a Huudis workspace and a running runtime. It has a plan:
internal— the forjio-team-operated instance; reserved for the seed row, customers can't create one.managed— catentio provisions the infrastructure (a DigitalOcean droplet + managed Postgres + Spaces bucket) on your behalf.byo— you bring your own VPS/database/Redis/object-storage credentials.
And a lifecycle status: pending → provisioning → ready (or failed); a destroyed deployment becomes archived. The portal surfaces the status, and error_code/error_message on failure.
Identifier: the Huudis workspace id itself (Huudis's own id, e.g. acc_01HX…) — there is no separate ws_…-prefixed id minted by Catentio. The runtime's customer_id is derived from it (prefix stripped, lowercased, sanitized) and is what agents, runs, and every other object are actually keyed on internally.
Agent
An agent is a named, configured Claude principal — a slug, a model, a system prompt, and a fixed list of allowed tools (not an open-ended budget: an agent can only call what's on its allow-list). The default roster includes:
- hachimi — the orchestrator; default for general work.
- tora — the implementer; ships code.
- sai, ren, fumi, iro — specialised agents (scene work, research, planning, design review & layout).
Plus a long tail of project-specific and custom (DB-backed) agents. The full list is at Dashboard → Agents.
You invoke an agent with a message (and optional context). The runtime spins up a fresh Claude CLI session under that agent's identity and allowed-tool list, and returns a run.
Run
A run is one invocation of one agent on one input. It's the durable record of:
- The original message (prompt + attached context).
- The agent's output, rendered once the run finishes — the portal polls for updates; there is no streaming/SSE/WebSocket channel.
- Child runs, if the agent delegated to another agent mid-run (each child carries
parent_run_idpointing at its parent). - Token + dollar cost (USD, per model, accumulated as the run progresses).
- Events — a fine-grained, replayable trace (model resolution, each tool call/result, state transitions).
- Artifacts produced (files, screenshots, JSON payloads).
States: queued → running → succeeded | failed | cancelled. Identifier: an unprefixed, 26-character lowercase ULID-style id (e.g. gk3n7q2fzja4bdm6xr8v1cwt5p) — there is no transport prefix on a real run id.
A run's record is immutable; retrying re-invokes the same agent with the same prompt as a new run with a new id. Inside a project, redo mechanics live at the pipeline layer instead (retry-subtask, phase retrigger).
Project
A project is a pipeline-driven workflow that strings multiple agents together with checkpoints between them. The canonical example is content production: concept → research (Fumi) → storyboard (with a human approval gate) → characters → per-scene work (Sai) → assemble → publish.
A project has:
- A workflow pin (
workflow_slug+workflow_version) — the versioned phase graph it was expanded from. See Workflows. - Tasks — one per phase, dependency-ordered (a DAG, not just a sequence).
- Subtasks under each task — the phase's steps:
agentruns, deterministicactions, andgatecheckpoints, each with a role (producer,reviewer,tester,assembler,gatekeeper,utility) and per-step tool/skill bindings. - Attempts per subtask — every execution is recorded; retries preserve history.
- Artifacts — each phase's promoted output, versioned and append-only (re-runs append versions; reverts flip the current pointer). Phases downstream of a changed artifact are marked stale under the default lazy cascade. See Artifact versioning & backtrack.
- Events — same outbox pattern as runs, but at project granularity.
States: planning, active, paused, completed, abandoned. You can pause a project mid-flight and resume later; the autodrive loop advances every active project on its own, stopping at human gates and budget caps. Identifier: <title-slug>-<8 hex chars> — the title lowercased with non-alphanumerics collapsed to dashes, plus a random 8-character hex suffix (e.g. sustainable-urban-farming-explainer-3f9a1c2b).
Tool
A tool is a typed capability an agent can call — HTTP fetch, file read/write, Discord post, browser automation, MCP-exposed primitives. Tools are scoped to agents (an agent has a fixed allow-list of tool slugs, not access to the global set) and live in the runtime, not the control plane.
The portal lets you list, get, create, update, and delete tools at Dashboard → Tools. Installing a new tool goes through a sandboxed build-and-approve flow, not a code-review PR: POST /v1/tools/{slug}/install kicks off a sandboxed build attempt, GET /v1/tools/{slug}/installs lists past attempts, and an operator approves or rejects each one (POST .../installs/{install_id}/approve|reject) before it's usable.
Skill
A skill is a named, versioned playbook for a recurring task — "review a PR", "set up a new STIA student record", "draft a Notion roadmap entry". Skills are stored as graph nodes (type: skill) in the runtime's memory store, not as files in a git-tracked directory; the runtime exposes list_skills + load_skill tools so agents can pull them on demand.
Create one directly through the portal (POST /v1/skills) — there is no PR/code-review step. Identifier: the slug.
Memory
The memory layer is the runtime's RAG store — embedded conversation history, project notes, and structured taste entries. The portal lets you:
- List entries with filters (agent, kind, date range).
- View one entry's full payload.
- Create entries directly (for seeding context).
- Update or delete entries — OTP-gated, since memory mutations are load-bearing.
Memory mutations require an OTP. The first call returns 403 with an OTP challenge; you re-send with the OTP header to commit.
Heartbeat
A heartbeat is a cron-like trigger that invokes an agent on a schedule. Use heartbeats for daily summaries, periodic check-ins, scheduled scrapes — anything that needs an agent to run on its own, without you in the loop.
You configure heartbeats per-agent at Dashboard → Heartbeats, and the portal exposes both the schedule (cron expression) and the prompt template.
Other primitives
A handful of supporting primitives round out the model. They're documented in their own portal sections:
- Integrations — BYO credentials for OpenAI, ElevenLabs, Google, GitHub, and Forjio-family products.
- Output destinations — where code and file outputs from agent runs should be written (a GitHub repo, a Google Drive folder, an output bucket).
- Feature flags — runtime-level kill switches for experimental behaviour.
- API keys — static tokens for server-to-server callers.
- Webhook gates — inbound: a pipeline step that blocks until an external system calls back to release it.
- Webhooks (outbound) — the other direction: Catentio POSTs to a URL you register when a run or project finishes. Two different features, opposite directions — see Webhooks (outbound).
- Scheduled jobs — the runtime's own internal cron (janitor, cost-stats refresh, billing reconcile, archival).
- Events — a flat projection of every outbox event across runs, projects, and agents.
Next
- Quickstart — put the model into practice.
- Workflows — the pipeline model in depth (phases, gates, bindings, artifacts).
- Portal → Tour — see the data model in the dashboard UI.
- API reference — the model exposed over REST.