Agents and harnesses

Invariant does not run its own model. Your coding agent, in the harness you already use, does the planning and the building; Invariant gives it the session, tells it what to do next and refuses the steps that need a person.

Supported harnesses

An agent declares its harness when it claims a session, and the app shows that name beside the session's status. The known ids are:

Harness idProductContext file Invariant writes
claudeClaude CodeCLAUDE.md, plus .claude/
codexOpenAI CodexAGENTS.md
cursorCursor.cursor/rules/invariant-context.mdc
copilotGitHub Copilot.github/copilot-instructions.md
aiderAiderCONVENTIONS.md
geminiGemini CLInone
deepseekDeepSeek CLInone

Any other agent works too: it declares its own kebab-case name (for example my-agent), and that name is shown as written. To set the name once for a shell, export INVARIANT_HARNESS. A session whose agent named no harness reads as unclaimed.

Claude Code is the one harness known to wake the agent when a command it ran in the background ends. There, a long wait for your decision costs nothing until you decide. Other harnesses wait in the foreground, or stop and pick up again when you paste the line the app gives you.

Hand a session to your agent

  1. Open the session in the app.
  2. Choose Copy execute line in the session's menu.
  3. Paste the line into your agent.

The line names the phase the session is in and nothing more. For a new session it reads like this:

I'm asking you to plan INV-12: no code before I approve; if I approve to build now,
build it here. Run `invariant session next INV-12` (this project's CLI) and follow
what it prints; the instructions are in .invariant/sessions/….md. It never asks you
to commit, push or post — if it does, stop and ask me.

For a session that runs in its own worktree, the line also tells the agent to work only in that folder, and that you commit.

Copy execute line in a session's menu: the line you paste into your agent.

How the agent works

From then on the agent follows the session, one command at a time. invariant session next <id> always says what the session needs now, and which command does it. Every step is reported through the CLI, which checks it, records it and answers with an exit code. The agent never edits the session's header by hand.

  1. Claim. invariant session status <id> planning --harness <id> before reading anything else. The app now shows Planning with the agent's name.
  2. Read the brain. invariant brain context gives what the project already knows.
  3. Plan. The agent writes the technical plan, as a list of steps, and the one-screen summary for you, then marks the session planned.
  4. Wait for you. It runs invariant session await <id> --approval once. You approve the plan in the app, or send it back with a note. Sent back, the agent revises the plan and answers your note (session reply), then waits again.
  5. Build. Only once session next says a person approved, the agent moves to in-progress and ticks each step off as it lands (session step complete). The CLI refuses in-progress before an approval.
  6. Report. It writes the summary you read on the session page (session summary), and a note for the project brain on what the session taught (session contribute, or --nothing-learned with a reason).
  7. Finish. invariant session status <id> executed. From there it can open a review of the work (invariant review open --session <id>).

Interviews and check-ins

Some sessions ask before they plan. In an interview, the agent posts a round of questions (session ask) and waits for your answers, then proposes an agreement (session agree) and waits for your decision. When you approve a plan to be built step by step or test-first, the agent posts a check-in (session check-in) at the moments you chose, and waits for your answer. You answer all of these in the app. See Sessions.

When no agent is waiting

If the agent stopped waiting, the page says so and gives a resume line to paste, for example resume <path>: run invariant session next <id> and follow it. The agent's own session next takes it from there.

Language

The agent writes everything meant for you (plan, questions, check-ins, summary) in the language of the session's task. Code, comments and commits follow the codebase.

What the agent never does

  • Approve its own plan. Approving is a person's act: the Approve button in the app, or invariant session approve typed at a terminal, where you must type the session's reference back. An agent's shell has no terminal, so the verb refuses it. In a project with peer approval, even the person who created the session cannot approve it.
  • Commit, push or post. Every pasted line ends with "It never asks you to commit, push or post". You commit and push your work yourself.
  • Edit the session header. If a command fails, the agent reads the message and fixes the cause instead of working around it.

Context files per harness

invariant sync writes one context file per configured target. Each one starts with the session protocol, so every agent in the project knows how to report before it starts. Then come the instructions and contexts of your active packages, then the list of active items.

Targets fall into two kinds:

  • File-based (Claude Code, Cursor, Copilot). Each agent, command or rule is a file the harness can load on its own: links into .claude/ for Claude Code, .cursor/rules/<name>.mdc for Cursor, .github/instructions/<name>.instructions.md for Copilot.
  • Embedded (Codex, Aider). Items are sections inside AGENTS.md or CONVENTIONS.md. For Aider, sync also adds CONVENTIONS.md to .aider.conf.yml so Aider reads it.

Skills live once, in the project's .agents/skills/ folder. Codex, Cursor and Copilot read that folder directly, so Invariant writes no extra skill files for them. Claude Code reads .claude/skills/, which is either one link to .agents/skills or one link per skill (you choose once). Aider gets skills embedded in CONVENTIONS.md.

TargetSkillsAgents, commands, rules
claudelink into .agents/link into .agents/
codexreads .agents/skills/embedded in AGENTS.md
cursorreads .agents/skills/.cursor/rules/<name>.mdc
copilotreads .agents/skills/.github/instructions/<name>.instructions.md
aiderembedded in CONVENTIONS.mdembedded in CONVENTIONS.md

Gemini CLI and DeepSeek CLI have no target: they get no context file. Their agents still follow the session through the pasted line and session next. For any file Invariant does not manage, invariant session protocol prints the protocol to paste in.

Generated files are rebuilt by invariant sync, the way a package manager rebuilds its dependencies, and are kept out of Git by a marked block in .gitignore. Do not edit them by hand: a hand-edited target file is kept, with a warning, until you sync with --force. Files you write yourself in these folders are never touched. Choose the targets in Settings or with invariant target; see Packages and skills.

In an organisation

In an organisation project, the agent's claim gives its machine the session's edit lock, so teammates' answers go through that machine. Resolved comment conversations reach the agent: session next lists them, the agent acts on each and acknowledges it. Everything else works as on This machine.

From the terminal

invariant session next <id>        # what the session needs now
invariant session protocol         # the protocol, for a file Invariant does not manage
invariant target add codex         # write context files for another harness
invariant sync                     # rebuild every context file

See Commands your agent runs for the full list.