---
title: How it works
description: The runtime map of Foreman, covering what runs where, how the filesystem defines the agent, and the three boundaries that shape the design.
type: overview
summary: The component map, the agent directory, and the three boundaries that shape the design.
related:
  - /docs/pipeline
  - /docs/stations
  - /docs/trust-model
---

# How it works



Foreman is one eve agent with five subagents, three inbound channels, and two durable stores. Everything it can do is declared as a file under `agent/`, and eve discovers the surface from the filesystem at build time.

## What runs where

| Component        | Lives in                                                     | Responsibility                                                                       |
| ---------------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------ |
| Orchestrator     | `agent/agent.ts`, `agent/instructions.ts`                    | Routes work between stations, assembles the pull request, speaks to people           |
| Stations         | `agent/subagents/{classifier,analyst,implementer,reviewer}/` | The four-stage pipeline every work item passes through                               |
| Researcher       | `agent/subagents/researcher/`                                | Optional web research, run before the Analyst when an item turns on an external fact |
| Inbound surfaces | `agent/channels/`                                            | Turn GitHub webhooks, Linear Agent Sessions, and local dev requests into sessions    |
| GitHub tools     | `agent/extensions/github.ts`                                 | 31 allowlisted `github__*` tools, 12 of them gated                                   |
| Linear tools     | `agent/connections/linear.ts`                                | Linear's hosted MCP server, writes denied on unattended runs                         |
| Root tools       | `agent/tools/`                                               | The five memory tools, plus one that disables a framework built-in                   |
| Shared logic     | `agent/lib/`                                                 | Trust predicates, approval policies, git safety, model assignments, storage keys     |
| Skills           | `agent/skills/`                                              | Load-on-demand instruction packages for the orchestrator                             |

## The agent directory

In eve, identity comes from the filesystem rather than a `name` field. The file `agent/tools/read_factory_brain.ts` is the tool `read_factory_brain`, and the directory `agent/subagents/classifier/` lowers into the tool `classifier`. Renaming something means moving the file.

<Files>
  <Folder defaultOpen name="agent">
    <File name="agent.ts" />

    <File name="instructions.ts" />

    <File name="sandbox.ts" />

    <Folder name="channels">
      <File name="eve.ts" />

      <File name="github.ts" />

      <File name="linear.ts" />
    </Folder>

    <Folder name="connections">
      <File name="linear.ts" />
    </Folder>

    <Folder name="extensions">
      <File name="github.ts" />
    </Folder>

    <Folder name="lib">
      <File name="constants.ts" />

      <File name="factory-brain.ts" />

      <File name="models.ts" />

      <File name="trust.ts" />

      <File name="user-preferences.ts" />

      <Folder name="github">
        <File name="approval.ts" />

        <File name="bot-name.ts" />

        <File name="credentials.ts" />

        <File name="git-remote.ts" />

        <File name="repo-sandbox.ts" />
      </Folder>
    </Folder>

    <Folder name="skills">
      <Folder name="github-linear-bridging" />

      <Folder name="triaging-issues" />

      <Folder name="writing-quality" />
    </Folder>

    <Folder defaultOpen name="subagents">
      <Folder name="analyst">
        <File name="agent.ts" />

        <File name="instructions.md" />

        <File name="sandbox.ts" />
      </Folder>

      <Folder name="classifier">
        <File name="agent.ts" />

        <File name="instructions.md" />
      </Folder>

      <Folder name="implementer">
        <File name="agent.ts" />

        <File name="instructions.md" />

        <File name="sandbox.ts" />

        <Folder name="tools">
          <File name="checkout_branch.ts" />

          <File name="push_branch.ts" />
        </Folder>
      </Folder>

      <Folder name="researcher">
        <File name="agent.ts" />

        <File name="instructions.md" />
      </Folder>

      <Folder name="reviewer">
        <File name="agent.ts" />

        <File name="instructions.md" />

        <File name="sandbox.ts" />

        <Folder name="tools">
          <File name="checkout_branch.ts" />
        </Folder>
      </Folder>
    </Folder>

    <Folder name="tools">
      <File name="agent.ts" />

      <File name="clear_user_preferences.ts" />

      <File name="get_user_preferences.ts" />

      <File name="read_factory_brain.ts" />

      <File name="save_user_preferences.ts" />

      <File name="update_factory_brain.ts" />
    </Folder>
  </Folder>
</Files>

## Three boundaries

Most of Foreman's behavior falls out of three structural decisions. They hold because of how the agent is wired, not because a prompt asks nicely.

### Stations inherit nothing

Every declared subagent runs in a fresh child session with none of the root's instructions, skills, connections, tools, or sandbox. That has two consequences worth internalizing.

The orchestrator must pack everything a station needs into the delegation message: the work item verbatim, plus every prior stage's output. Stations never see the conversation history, and they cannot read the [factory brain](/docs/memory), so any repository fact that matters has to be woven into the message.

The upside is that each station's blast radius is readable at a glance. Whatever sits in `agent/subagents/<id>/` is the complete list of what that station can do.

### Trust is stamped at dispatch

Every channel decides who the caller is from the signed webhook, before the model reads anything, and writes that decision into session auth. Nothing downstream re-derives trust from model-readable content, because model-readable content is exactly what an attacker controls.

`agent/lib/trust.ts` is the single authority that reads those stamps. New capabilities gate on its predicates rather than inventing their own caller check. The [trust model](/docs/trust-model) covers the caller classes and policies.

### Each station works in its own sandbox

Every eve agent gets a sandbox whether or not it asks for one, so all five subagents run in one. What separates them is what is inside it.

The Analyst, Implementer, and Reviewer each declare their own `sandbox.ts`, so each gets a separate Vercel Sandbox holding its own clone of `FACTORY_REPO`. The three declarations are functionally identical, and none is more isolated than the others. The Reviewer's copy just carries the most weight, because it fetches the pushed branch into a clean checkout and therefore reviews what was actually pushed rather than the Implementer's working tree.

The Classifier and Researcher never set one up, so they get the default: a working environment with an empty `/workspace` and no repository in it.

The three repository sandboxes share their bootstrap through `agent/lib/github/repo-sandbox.ts`. The clone and `FACTORY_SETUP_COMMAND` run once per template build, and each session pays only a fetch. Git always targets the literal `https://github.com/<FACTORY_REPO>.git` URL rather than `origin`, because remote config inside a sandbox is model-writable.

## What persists and what does not

Only two things survive a run, and both live in Vercel Blob under reserved prefixes.

| State                                     | Durable | Notes                                                 |
| ----------------------------------------- | ------- | ----------------------------------------------------- |
| Factory brain                             | Yes     | One document per target repository, read by every run |
| User preferences                          | Yes     | One document per person                               |
| Root thread checkout                      | No      | Rebuilt per session by the GitHub channel             |
| Analyst, Implementer, and Reviewer clones | No      | Rebuilt per template build, refreshed per session     |
| Conversation history                      | No      | Each webhook dispatch is a fresh session              |

The last row explains a design choice that looks odd otherwise. Because each dispatch starts clean, the red-CI fix loop counts its own earlier comments on the pull request thread to enforce its 2-attempt cap. The thread is the only durable record those runs share.

## Next steps

<Cards>
  <Card href="/docs/pipeline" title="The pipeline" description="How a work item moves through the four stations to a draft pull request." />

  <Card href="/docs/stations" title="Stations reference" description="Model, tools, sandbox, and output contract for each of the five subagents." />

  <Card href="/docs/trust-model" title="Trust model" description="Caller classes, approval policies, and the reasoning behind each gate." />

  <Card href="/docs/glossary" title="Glossary" description="Definitions for principal, parks, task mode, and the rest of the vocabulary." />
</Cards>


---

For a semantic overview of all documentation, see [/sitemap.md](/sitemap.md)

For an index of all available documentation, see [/llms.txt](/llms.txt)

For agent-facing discovery, including API and MCP surfaces, see [/agents.md](/agents.md)