> ## Documentation Index
> Fetch the complete documentation index at: https://docs.obversa.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Obversa and Claude Code subagents

> Claude Code subagents split one session's work across specialised Claude assistants. Obversa drives Claude Code, Codex, Grok and OpenCode as a team from a TypeScript file, with reviews that send work back and a person at the gate. What each is for, and where each wins.

Choose by where the work lives. Subagents fit when you are inside that one session and want to hand
parts of a task to specialised assistants with their own tools and
prompts. Pick Obversa when the work needs more than one family of agent, a
review that sends work back with findings, a person who decides, and a
record you can read after the run.

Claude Code's own words: "Subagents are specialized AI assistants that
handle specific types of tasks." A subagent is a markdown file with a name,
a description, its tools and its model. It runs inside your Claude Code
session, under the session's permission mode, and its transcript is kept
on disk so it can be resumed. The model is one of the Claude family.

Here is the shape Obversa is for, as one file:

```ts theme={null}
import { claude } from '@obversa/engine-claude-cli';
import { codex } from '@obversa/engine-codex';
import { run } from '@obversa/runtime';
import { fromFile, person, stage, workflow } from '@obversa/teams';

/**
 * A feature, delivered the way a team delivers one. The roles are named once;
 * every stage is a small block of nouns: who does it, what it writes, who
 * reads it, where a red result goes back to. Inference happens only where a
 * role is named; every other stage is a command or a person.
 */
const team = workflow('feature-delivery', {
  brief: fromFile('briefs/triple.md'),
  options: { timeout: '10m' },

  roles: {
    analyse: claude('claude-sonnet-4-5'),
    implement: codex('gpt-5.6-luna'),
    'research-review': [codex('gpt-5.6-luna')],
    'code-review': [claude('claude-sonnet-4-5')],
    approve: person('Ship this change?'),
  },

  stages: [
    stage('research-context', {
      agent: 'analyse',
      writes: 'team-output/research-context.md',
      desc: 'Read the workspace and write down what the change touches.',
      gate: 'The context note is in the workspace and a reviewer has accepted it.',
      reviewedBy: 'research-review',
      retry: 3,
    }),

    stage('research-requirements', {
      agent: 'analyse',
      writes: 'team-output/research-requirements.md',
      desc: 'Turn the brief and the context note into requirements, one REQ-n per line.',
      gate: 'The requirements note is in the workspace and a reviewer has accepted it.',
      reviewedBy: 'research-review',
      retry: 3,
    }),

    stage('plan', {
      agent: 'analyse',
      writes: 'team-output/plan.md',
      desc: 'Write an executable plan from the requirements, one check per REQ-n.',
      gate: 'Every requirement has a check in the plan.',
      reviewedBy: 'research-review',
      retry: 3,
    }),

    stage('tests-first', {
      agent: 'implement',
      writes: 'test/triple.test.mjs',
      desc: 'Write the declared test files from the accepted plan before any implementation exists.',
      gate: 'Every declared test file exists and covers the plan.',
      reviewedBy: 'code-review',
      retry: 3,
    }),

    stage('implement', {
      agent: 'implement',
      writes: 'src/triple.mjs',
      desc: 'Write the code to the plan and the tests.',
      gate: 'The source file exists.',
      retry: 3,
    }),

    stage('test', {
      run: ['node', '--test', 'test/triple.test.mjs'],
      desc: 'Run the tests; a red run goes back to implement with the output.',
      gate: 'The test command exits 0.',
      sendsBackTo: 'implement',
    }),

    stage('review', {
      panel: 'code-review',
      agree: 1,
      desc: 'Read the change and the test result against the plan.',
      gate: 'At least one reviewer has accepted the change.',
      sendsBackTo: 'implement',
    }),

    stage('approve', {
      input: 'approve',
      desc: 'Put the verified change in front of a person.',
      gate: 'A person has said yes.',
    }),

    stage('close', {
      agent: 'analyse',
      writes: ['team-output/evidence.md', 'team-output/learning.md'],
      desc: 'Write the evidence of the run and what was learned, from the record alone.',
      gate: 'Both notes are in the workspace.',
    }),
  ],

});

const result = await run(team);
console.log(JSON.stringify(result.outcome, null, 2));
```

## Side by side

|                               | Claude Code subagents                                                       | Obversa                                                                                                                 |
| ----------------------------- | --------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| Unit of work                  | A subagent: a prompt, tools and a model, invoked from the session.          | A stage: an engine call, a command, a panel or a person, with the files it may write.                                   |
| The workers                   | Claude models, inside Claude Code.                                          | Claude Code, Codex, Grok and OpenCode, driven as engines, one fresh process per call.                                   |
| A review that sends work back | A subagent can be asked to review; sending work back is direction you give. | Built in: a review role sends the work back to the stage that owns it, with findings, up to a budget.                   |
| A person deciding             | Permission prompts at tool calls; plan mode.                                | A person role; the run pauses on the question and the answer arrives through the callbacks client.                      |
| More than one provider        | The Claude family.                                                          | Claude, OpenAI, xAI and OpenCode's providers, one per role.                                                             |
| A run that survives a crash   | Transcripts on disk; a subagent can be resumed.                             | A plain run records to a file and does not resume. The supervised runner restarts a compiled graph from its own record. |
| Where it runs                 | Inside Claude Code, on your machine.                                        | A library, no server, on your machine.                                                                                  |
| How it is written             | Markdown with front matter.                                                 | TypeScript.                                                                                                             |

## Where Claude Code subagents win

* You are already in Claude Code and the task is one session's work.
* The permission checks at every tool call are the safety net you want,
  with nothing more to install.
* One model family is enough.

## Where Obversa wins

* A review should come from a different family than the one that wrote the
  work.
* The process, reviews and returns included, should be a file under
  version control, and the run a record beside it.
* The last word should be a person's, asked as a step.

## Where to go

[A feature team, as a file](/workflows/feature-team) for the file above with
its recorded run; [what is a meta-harness](/glossary/meta-harness) for the
layer Obversa is.
