Skip to content

econpotter/orchestra

Repository files navigation

Orchestra

Orchestra runs development work across many repositories unattended. You plan and promote issues; Orchestra dispatches a validator, worker, and verifier on a schedule, each running in a sandboxed harness process, then asks for human approval or intervention when policy requires it.

Status: alpha, in active development and daily use by its author.

This repository contains the public Orchestra engine, CLI, protocol, prompts, and scheduler units. It is deliberately separate from an Orchestra workspace, which contains private project registrations, queues, configuration, and runtime state.

Claude and Codex are implemented adapter targets; an installation is not rollout-supported until its exact harness version and service envelope pass the documented real canaries. A PiJsonAdapter is specified at the protocol level so the architecture remains harness-neutral, but the Pi harness implementation is deferred to a later feature.

Install from source

Clone with either SSH or HTTPS:

git clone git@github.com:econpotter/orchestra.git
# or: git clone https://github.com/econpotter/orchestra.git
cd orchestra

For development, install the locked environment and run the CLI from the checkout:

uv sync
uv run pytest
uv run orchestra --help

To put orchestra on your PATH, install an editable tool from this exact checkout:

uv tool install --force --editable "$PWD"

The editable installation keeps the executable tied to this checkout. Confirm the executable and loaded package contents before operating a workspace:

command -v orchestra
orchestra --help
orchestra engine provenance --compare "$PWD"

engine provenance exits nonzero if the loaded package differs from the checkout. Every attempt also retains this package fingerprint, the harness executable/version, and the effective execution-envelope fingerprint.

Sandboxed runs require both systemd-run and Bubblewrap (bwrap) on the host. The transient user service owns process lifetime only; Bubblewrap enforces the read-only root, writable attempt paths, and masked personal harness state. Orchestra fails dispatch explicitly if bwrap is missing. Configured sandbox.tmpfs_paths (by default ~/.cache) give each service private, writable tool caches without exposing the operator's cache. Network access remains shared so the harness can reach its model API.

Create a separate workspace

Do not put operational data in this repository. Create a separate directory for it; the path can be anywhere:

mkdir -p ~/workspace/{projects,queue,prompts,.orchestra}
cp config.example.yaml ~/workspace/config.yaml
cp prompts/*.md ~/workspace/prompts/
printf '# Projects\n' > ~/workspace/PROJECTS.md
orchestra workspace set ~/workspace
orchestra workspace show

The workspace owns:

  • config.yaml: harness, role, workflow, review, and concurrency policy;
  • PROJECTS.md: registered repositories and their queue paths;
  • queue/: Orchestra-managed issue state;
  • projects/: project checkouts, when you choose to keep them under the workspace;
  • prompts/: optional workspace overrides of the packaged prompts; and
  • .orchestra/: runtime handles, logs, results, locks, and worktrees.

Register an existing repository, then verify the workspace can be read:

orchestra project add example --path projects/example --branch main \
  --purpose "Describe what this project owns"
orchestra status
orchestra guide

To scaffold instead, set template_path in the workspace's config.yaml to a compatible project template and run:

orchestra new-project example --lang python --stage development

new-project creates the checkout beneath the workspace, initializes Git, adds the PROJECTS.md entry, and creates its queue. The template is workspace data and is not bundled into the Orchestra engine repository.

Paths in PROJECTS.md are resolved from the workspace. The engine checkout may live inside the workspace (for example, projects/orchestra) without becoming the workspace root. Workspace resolution order is explicit --root, ORCHESTRA_ROOT, ~/.config/orchestra/settings.yaml, then upward discovery from the current directory. Use orchestra workspace show after moving either directory.

Configure a harness

Start from config.example.yaml. Each role names a supervised harness and model. Orchestra's Codex and Claude adapters own the required structured-event and native-result-schema flags; do not copy CLI argument vectors into configuration. Harness executables must already be installed and available on the scheduler's PATH.

The example uses an isolated Codex state directory. Prepare and authenticate it, then require a successful doctor report before resuming unattended dispatch:

orchestra harness setup codex
# Run the exact CODEX_HOME=... codex login command that setup prints.
orchestra harness doctor codex

Orchestra never copies or symlinks personal Codex authentication into this directory. Dispatch preflights authentication in the configured CODEX_HOME and records authentication_failure without launching a model when credentials are unavailable. If project AGENTS.md files rely on a separate global coding contract, set harnesses.<name>.environment.instructions_file; setup installs that file as the isolated CODEX_HOME/AGENTS.md, and doctor/dispatch fail loudly when it is missing or has drifted.

A current Claude process configuration is:

harnesses:
  claude:
    kind: claude
    executable: claude
    reasoning_effort: high
    sandbox: danger-full-access
    environment: {policy: isolated, state_dir: .orchestra/homes/claude}
    attempts_cap: 3

Set roles.<role>.harness: claude, roles.<role>.instruction_policy: explicit_bundle, and choose the corresponding Claude model. Isolated Claude uses --safe-mode, disabling native customization and instruction discovery while Orchestra supplies the recorded project bundle exactly once. Run orchestra harness setup claude, authenticate with the printed CLAUDE_CONFIG_DIR=... claude auth login command, and require orchestra harness doctor claude to pass. The dedicated config directory plus the outer home mask prevents personal plugins, skills, integrations, and sessions from entering the run. The adapter preflights the installed CLI and fails loudly if required protocol flags are missing. The danger-full-access setting is appropriate only inside an execution boundary you trust; enable the workspace's outer sandbox when filesystem confinement is required.

The supervised adapters and evidence contract are documented in protocol/HARNESS-RELIABILITY.md. Do not configure Pi as if it were an implemented, verified harness.

Run Orchestra

Create work in a registered project, then promote it:

orchestra issue add example --title "Implement the change" \
  --plan docs/plans/change.md \
  --accept "The requested behavior is covered by tests"
orchestra tick
orchestra status

The plan or spec must be committed to the project’s base branch before dispatch. See protocol/ISSUE-GUIDE.md for issue-writing guidance and protocol/STATES.md for lifecycle semantics.

Key commands include issue add, issue list, issue show, status, logs, diff, approve, reject, hold, release, kill, project add, pause, resume, dispatch, reconcile, and tick. Use orchestra attempt explain ATTEMPT_ID for retained failure and provenance evidence. Run orchestra guide or orchestra <command> --help for the live interface.

Install the scheduler

The shipped systemd user units call the installed CLI, which resolves the workspace saved by orchestra workspace set:

mkdir -p ~/.config/systemd/user
cp systemd/orchestra.service systemd/orchestra.timer ~/.config/systemd/user/
loginctl enable-linger "$USER"
systemctl --user daemon-reload
systemctl --user enable --now orchestra.timer
systemctl --user start orchestra.service
systemctl --user status orchestra.service orchestra.timer
journalctl --user -u orchestra.service -n 50

Before relying on unattended runs, confirm that the PATH in ~/.config/systemd/user/orchestra.service includes orchestra, the selected harness CLI, and tools used by project checks. The one-shot scheduler service intentionally uses KillMode=process so detached harness processes survive the tick that launched them. See protocol/OPERATIONS.md for scheduler details and a cron fallback.

Workflow and policy

  • A tick runs dispatch and then reconcile; reconciliation is the sole automated lifecycle writer, while explicit operator commands perform intentional transitions.
  • Structural validation is deterministic by default. Set validate.semantic: true to add an LLM validator stage.
  • hold_network_issues: true parks unapproved network issues before validation. Held issues are sticky and return to open only through explicit release.
  • review.autoapprove: false stops verifier-approved work for human review; true merges it during reconciliation.
  • slots limits in-flight Orchestra roles, not subagents created inside a harness run.
  • pause and resume control new dispatch without stopping in-flight agents.
  • Worktree-Seed in PROJECTS.md supports path (copy), path:link (writable symlink), and path:ro-link (Bubblewrap-enforced read-only sharing).

The public engine does not own any particular workspace's queue, project portfolio, private notes, local prompts, or agent instructions. Keep those in the workspace and contribute only reusable engine behavior and documentation here.

About

Provider-agnostic multi-project agent workflow engine

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages