orchid 1.0.0-beta.1 · bash + git + jq

Your coding agents, as one dev team.

orchid turns the agent CLIs you already subscribe to into a team that plans, implements, reviews and merges. Independent engines check each other's work, your own tests decide what passes, and your phone buzzes only when a human decision is needed.

brew install bilal-/tap/orchid
View on GitHub
  • Works with
  • Claude Code
  • Codex
  • Antigravity
  • Hermes
  • OpenClaw
13m19s
clone to accepted, in the release rehearsal
0
API keys. Billing stays on your plans
3
dependencies: bash, git and jq
1
git commit per state change, with its evidence
What makes it different

A small kernel, not an agent framework.

Models do the judgment. Everything else is a bash state machine you can read in an afternoon, and every decision it makes is a file in git.

Runs on the subscriptions you already pay for

Engines are vendor CLIs in their own headless modes. orchid never holds an API key, never meters tokens and never proxies a request.

Nobody signs off on their own work

A different engine, or at least a fresh session, reviews every candidate. Research shows models favour their own output.

Your tests are the only judge

orchid verify runs the command you configure. An engine saying "tests pass" is a diagnostic, never evidence.

Files are the truth

No daemon, no database. Tasks, reviews, the journal: committed on the integration branch.

Crash anywhere, resume from files

Durable state is single-writer and epoch-fenced. A crash loses at most the tick in flight.

Any engine, any role, enforced

Roles are capability requirements, not vendor names. A new binding stays disabled until the capability suite proves it, and orchid doctor says so.

Watch every job

orchid jobs ls is the process table: each job's task, role, engine, state and budget. Liveness is computed, never read off a file.

One task's journey

Every step is a verb. Every verb wants evidence.

A transition is refused unless its gate holds: a passing verify log, review envelopes bound to this exact commit, a journaled reason. Pick a state to see what moves it on.

implementing

The implementer engine (codex by default) edits a worktree of its own. The adapter, not the engine, commits.

Moves on with
runners/orchid-launch
Only if
An ok envelope and a real candidate: a new HEAD, or a recorded candidate ahead of base. An ok with nothing changed is refused.
Who runs whom

Runners launch. Verbs decide. Engines only hand back files.

Every engine gets a request document and leaves a result envelope. The kernel reads both and commits the outcome, and nothing an engine says is taken at face value.

You install a heartbeat or start a session. The pump wakes a tick, the tick runs a deterministic drive, and the drive calls tier-1 verbs and asks orchid-launch to start engines. Each engine gets a request document and leaves a result envelope in the spool; verbs reconcile it and commit every state change to the integration branch. A question for you goes to the outbox and on to your phone.youtier 2 · runnerstier 1 · verbsenginesfiles in gitorchid service installorchid run startverbs onlyrequest documentresult envelopeorchid jobs reconcileepoch-fenced commitsorchid notifyyouterminal · phoneorchid-pumpheartbeat · launchd / cronorchid-tickone bounded tickorchid drivedeterministic, no modelorchid-launchthe one engine spawnertask · run · jobs · verify · merge · notifytier-1 verbs: deterministic state transitionsclaudeorchestrator · judgmentcodeximplementeragyreviewerhermesreviewerclaudefallbackorchid/integrationtasks · journal · reviewsruntime/spool/result envelopesruntime/outbox/one question → your phone

This is source-level mediation, not OS containment: a shell-capable engine is still a process on your machine. The README says exactly what is enforced and what is policy. Architecture, in five diagrams

Getting started

Point it at a repository. Write what you want.

  1. 1

    Check the machine

    orchid doctor names what is missing, like a verify= line or an engine CLI, and how each role resolves.

    ❯ orchid doctorWARN: unattended trust (headless execution gated): deniedok: plugin discovery: no collisionsok: plugin manifests: validate cleanok: git repositoryok: jqok: worktree supportok: verify command configuredok: role orchestrator -> claude, codexok: role implementer -> codex, claudeok: role reviewer -> agyok: role arbiter -> claude, codexok: role plan_critic -> codex, claudeok: notify return leg: no notify channel configured (notify.channel unset)ok: integration branch exists or creatableok: no split-brain checkout stateok: task files: none on disk yet (nothing to check)ok: no stale integration checkout state
  2. 2

    Give it a branch of its own

    orchid init creates an integration branch and installs a pre-push guard. Your own branches are never touched.

    ❯ orchid initpre-push guard installed: ~/acme/api/.git/hooks/pre-push (integration branch: orchid/integration)initialized: orchid/integrationintegration branch: orchid/integrationnext: git worktree add ../api-orchid orchid/integration && cd ../api-orchid
  3. 3

    Say what done means

    Write requirements.md: the goal, constraints and acceptance criteria. A second engine critiques the plan before it becomes work. One command does the rest of the setup:

    ❯ orchid start requirements.md --verify "npm test"
  4. 4

    Let it run

    Stay in the session, or review the repository and install a heartbeat so it runs without a terminal open. Come back to merged, verified code with every decision journaled.

    ❯ orchid trust unattended "$PWD" --reason "reviewed for unattended runs"
    ❯ orchid service install
The blocker round trip

One message when it needs you. Nothing when it doesn't.

A design fork, an exhausted rework budget, something orchid won't do on its own: one message reaches your phone over Telegram or WhatsApp, with the exact command to answer it.

  • The message is the interface. Any agent, or you in a terminal, can run the reply as written.
  • Nonce-verified. A reply that doesn't match the question's nonce, or comes from outside the allowlist, is refused.
  • The phone is optional. Without a channel, BLOCKERS.md and the terminal do the same job.
orchid · acme/apivia hermes · Telegram
14:02

q-4-7f2a: Sign-in: keep magic links, or move to passkeys?task: T003 — sign-in with passkeysattempt: 2choices: magic-links | passkeysreply: ORCHID_REPO="/Users/sam/acme/api" orchid answer q-4-7f2a <choice> --nonce 9c1e04b7d2a85f36

passkeys

nonce checked · answer recorded

Any engine, any role

Roles are config lines, not vendors.

An engine can hold any role its declared capabilities satisfy. The tested defaults are what orchid's own suite and dogfood runs exercise; anything else is labelled unverified until orchid plugins test passes it.

Which built-in engines can hold which roles
Engineorchestratorimplementerreviewerarbiterplan_critic
claudeshell, git, workspace writedefaulteligibleeligibledefaulteligible
codexshell, git, workspace writeeligibledefaulteligibleeligibledefault
codex-reviewworkspace read, git––eligible–eligible
agystructured text––default––
hermesstructured text––eligible–eligible
Said plainly

What it does not do.

No push, no deploy

orchid's verbs have no push, deploy or publish. Engines are told to raise external changes as a blocker, and moving the branch to origin stays yours.

Not a sandbox

Plugins are trusted code. Vendor sandbox flags are a real second layer; full OS containment is on the roadmap, not claimed.

No hosted version, ever

No server, no dashboard, no accounts. orchid status --html writes a local file.

Done is not accepted

A merged task is a fact about one commit. Accepting the run is a separate decision, and it is yours.

Write requirements. Come back to merged code.

macOS and Linux, Bash 3.2 or newer. Install pins to v1.0.0-beta.1; upgrade with the next version's pinned line.

brew install bilal-/tap/orchid

orchid is the third of shellbell and sous. Read the README or star it on GitHub.