An agent in Company Agents is not a wrapper around a single LLM call. It is a long-lived process that checks out work, runs until done or until the orchestrator yanks it, reports back, and leaves behind a structured record. This guide is for people who want to write one. Before you do, build an accurate picture of the runtime.

The shape of an agent

An agent is three things:
  1. A process the adapter launches (Claude Code, Codex, a plain Python script, whatever). It runs on your machine, inside a fresh execution workspace, talking to a runtime service endpoint.
  2. A role defined by files in the agent’s home directory: AGENTS.md (identity and mission), TOOLS.md (what it can call), MEMORY.md (what it remembers), plus any custom files the team adds.
  3. A contract with the orchestrator: how it picks up tasks, how it reports progress, how it finishes or hands off.
The adapter handles the first part. The role files are your job. The contract is codified in the heartbeat protocol, covered in the next guide.

The life of a task

When a task is assigned to an agent:
  1. The orchestrator picks the task off the queue
  2. A fresh execution workspace is created under ~/.company-agents/instances/default/runs/{run-id}/
  3. Runtime services are started or pulled from the pool
  4. The adapter launches the agent process inside the workspace
  5. The agent reads its role files and the task context
  6. The agent acquires a lease on the task (not a lock; see below)
  7. The agent works: reads files, edits files, calls tools, talks to the orchestrator over the tool proxy
  8. The agent writes a structured checkpoint on its own cadence
  9. The agent finishes, fails, or hands off
  10. The orchestrator tears down the workspace (unless it is marked for retention) and runs the next task
The agent never picks tasks for itself. It never manages its own budget. It never writes to the audit trail directly. The orchestrator owns all of that.

Leases, not locks

Most task systems use locks: a row in a database that says “agent X owns this task.” If the agent crashes with the lock held, the task is stuck until a human clears it. Company Agents uses leases instead. A lease is a lock with an expiry. The agent renews the lease on a timer. If the agent crashes or hangs, the lease expires and the orchestrator hands the task to another agent without human intervention. Leases come with a fencing token that increments every time the task is reassigned. If an old agent comes back from the dead and tries to write, the orchestrator rejects the write because its fencing token is stale. No split-brain, no double-writes. You do not have to think about leases explicitly. The adapter and the tool proxy handle them. But you should know they exist so you understand why your agent might be told “you are no longer the owner of this task” halfway through a run.

Structured checkpoints

Every few minutes (or at natural pause points), the agent writes a checkpoint: a structured record of “what I am doing, what I have tried, what I believe, what I plan next.” Checkpoints are written by the agent using the report_progress tool and stored by the orchestrator in the task’s run record. Checkpoints are for two audiences:
  • Future you (the agent itself, on its next context reload). The checkpoint is how the agent survives context compaction. When the adapter compresses the conversation to fit the token window, the checkpoint is the part that definitely survives.
  • The human reviewing the run. Checkpoints make it possible to see what the agent was thinking at each step without reading the raw conversation.
A good checkpoint is short, structured, and factual: here is what I believe about the state of the task, here is what I tried, here is what I will try next. A bad checkpoint is a conversation dump.

Loop detection

The orchestrator watches the agent’s output for loops. If the same tool call with the same arguments repeats more than N times in a window, or the same output appears more than M times in a row, the orchestrator marks the run as looping and kills it. This is implemented via output-hash dedup, not by watching the agent’s internal state. You do not need to instrument your agent for loop detection. But if you are writing a tool that returns the same value on purpose (for example, a status check that polls), you need to make sure the output changes over time (even just a timestamp) so the dedup does not flag you as looping.

Memory scopes

Agents have four memory scopes, in order of longevity:
  • Task memory — scratch, lives only for one task run
  • Agent memory — lives for the life of the agent
  • Project memory — shared across all tasks in one project
  • Client memory — shared across all projects for one client
  • Company memory — shared across all clients in the company
Memory moves between scopes on promotion: a note written in task memory can be promoted to agent memory at the end of the task if the agent decides it is worth keeping. Promotion is explicit: the agent has to call promote_memory with the scope and the key. Memory is plain text files under .company-agents/memory/ in the workspace, mapped to the correct scope directory on promotion. You can read and edit memory directly for debugging, but at runtime only the agent writes to it.

What the orchestrator does for you

If you are coming from writing raw LLM pipelines, it is worth spelling out what you do not have to write anymore:
  • Task checkout and assignment
  • Lease renewal, expiry, and reassignment
  • Process group isolation (your agent is already in a sandbox)
  • Loop detection
  • Cost tracking and budget enforcement
  • Checkpoint storage and retrieval
  • Tool permission checks
  • Audit trail writing
  • Memory scope management
If you are writing an adapter, most of this is also already handled by the adapter SDK. You only have to worry about how your particular CLI hooks into the tool proxy.

What you still have to do

  • Write the role files (AGENTS.md, TOOLS.md, MEMORY.md)
  • Write the skills the agent will call
  • Decide when to checkpoint and what to put in the checkpoint
  • Decide when to escalate vs. when to keep trying
  • Decide when to write to memory and at what scope
  • Handle your own errors from the tools your agent calls

Next