$git clone https://github.com/sipyourdrink-ltd/bernstein<br>
| 1 | <div align="center"> |
| 2 | |
| 3 | <picture> |
| 4 | <source media="(prefers-color-scheme: dark)" srcset="docs/assets/logo-dark.svg"> |
| 5 | <source media="(prefers-color-scheme: light)" srcset="docs/assets/logo-light.svg"> |
| 6 | <img alt="Bernstein" src="docs/assets/logo-light.svg" width="340"> |
| 7 | </picture> |
| 8 | |
| 9 | <br> |
| 10 | |
| 11 | > *"To achieve great things, two things are needed: a plan and not quite enough time."* - Leonard Bernstein |
| 12 | |
| 13 | </div> |
| 14 | |
| 15 | ### why the name? |
| 16 | |
| 17 | Bernstein is named after Leonard Bernstein, the American conductor and composer. The project orchestrates a crew of CLI coding agents the way Bernstein conducted the New York Philharmonic: every player on cue, the score deterministic, the conductor accountable for the result. He is the original orchestrator the project takes its name from. |
| 18 | |
| 19 | <div align="center"> |
| 20 | |
| 21 | ### deterministic multi-agent CLI orchestration |
| 22 | |
| 23 | [](https://github.com/sipyourdrink-ltd/bernstein/actions/workflows/ci.yml) |
| 24 | [](https://pypi.org/project/bernstein/) |
| 25 | [](https://ghcr.io/sipyourdrink-ltd/bernstein) |
| 26 | [](https://python.org) |
| 27 | [](LICENSE) |
| 28 | [](https://scorecard.dev/viewer/?uri=github.com/sipyourdrink-ltd/bernstein) |
| 29 | [](https://github.com/sipyourdrink-ltd/bernstein/actions/workflows/codeql.yml) |
| 30 | [](https://codespaces.new/sipyourdrink-ltd/bernstein?quickstart=1) |
| 31 | |
| 32 | [website](https://bernstein.run) · [docs](https://bernstein.readthedocs.io/) · [install](docs/getting-started/install.md) · [first run](docs/getting-started/first-run.md) · [glossary](docs/reference/GLOSSARY.md) · [limitations](docs/reference/KNOWN_LIMITATIONS.md) · [sponsor](https://github.com/sponsors/chernistry) |
| 33 | |
| 34 | </div> |
| 35 | |
| 36 | --- |
| 37 | |
| 38 | Bernstein is a deterministic orchestrator for CLI coding agents (Claude Code, Codex, Gemini CLI, and 40+ more). Scheduling is plain Python - no LLM in the coordination loop - so runs are reproducible end to end. Every task runs in its own git worktree behind lint/type/test gates. Results stay checkable after the fact: an always-on lineage spine and replay journal, plus an opt-in HMAC-chained audit log (`--audit`) with receipts you can verify offline. Air-gap install profile included. Apache-2.0. |
| 39 | |
| 40 | ### at a glance |
| 41 | |
| 42 | - **Deterministic scheduler**: zero LLM in the coordination loop. Plain Python decides who runs, where, with what budget. Replay yesterday's plan, get yesterday's task graph. |
| 43 | - **Per-artefact lineage** records every adapter file write, without per-adapter opt-in, as one Merkle-chained, HMAC-tagged entry in an always-on lineage spine (`.sdd/lineage/<run_id>/spine.jsonl`). The chain head hash is the run's artifact-provenance identity. CLI: `bernstein lineage verify <run_id>` (recompute the chain, distinct `NO ENTRIES` status for empty runs) and `bernstein lineage replay <run_id>`. |
| 44 | - **Always-on replay journal**: every run records into one Merkle-chained event journal (`.sdd/runs/<run_id>/journal.jsonl`) whose head hash is the run identity; no on/off flag, `BERNSTEIN_REPLAY_RETENTION` caps disk. Non-determinism surfaces as a hash mismatch: `bernstein replay <run_id> --verify` recomputes the head and reports the exact first divergent step, and `bernstein replay <run_id> --from-step N` rebuilds deterministic state. The journal head is sealed into the lineage spine so replay identity and artefact provenance share one root. Provider-side context mutations (server-side |