Status: Accepted for bootstrap implementation
Owner: Brian / Bobsled maintainers
Last updated: 2026-08-30
Bobsled is an agent-agnostic control harness for an AI-native software development lifecycle. It gives Claude Code, OpenAI Codex, and GitHub Copilot one shared system of governance while allowing a project to choose the agent/model pair best suited to each kind of work.
The memorable rule is:
One constitution, three executors.
Agents produce work. Bobsled governs how work enters, progresses through, and leaves the lifecycle. No vendor-specific instruction file, hook, or session is the authority for workflow state or approval.
This design is faithful to the intent of Anthropic's AI-Native SDLC playbook, while treating Claude-specific mechanisms as examples of controls that belong above the agent boundary.
A user should be able to open Bobsled in a browser, register a repository, start or import an intent, and watch a governed change move through:
intent -> spec -> plan -> build + verification -> review -> deploy -> maintain
^ |
+---------------- incident / finding / control-band breach --------+
For every stage Bobsled answers:
- What artifact is being produced?
- Which runner and resolved model produced it?
- Which policies and tools were in force?
- What deterministic evidence supports it?
- Who or what is allowed to accept it?
- What exactly triggered the next stage?
Each stage ends in a committed, human-readable artifact consumed by the next
stage. The minimum chain is intent.md, spec.md, plan.md, the code diff and
verification evidence, review findings, and an incident or maintenance record.
Bobsled may store large transcripts outside Git, but committed artifacts must contain immutable references to those records.
Agents may prepare everything up to a gate. They may not approve their own artifact, merge their own change, or authorize their own production release.
The default human gates are:
| Gate | Accountable role |
|---|---|
| Intent accepted | Product owner |
| Spec accepted | Product owner; policy owners resolve conflicts |
| Plan accepted | Engineer for routine work; technical lead for higher risk |
| Pull request accepted | Code owner through branch protection |
| Production release | Named release manager |
Prompts, skills, and instructions are advisory. Requirements that must always hold are enforced by the harness through state-transition guards, sandbox and capability profiles, protected action brokers, deterministic validators, and required checks.
For higher-risk work, Bobsled must prove that the independent reviewer differs from the author according to configured constraints. Runner identity, model provider, model family, and resolved model ID are recorded separately.
If the independence constraint cannot be met, the workflow fails closed and escalates to a human. It never silently substitutes the authoring pair.
Only Bobsled can transition a run. Text written by an agent such as "approved" or "done" has no state-changing authority.
Review artifacts carry a schema-valid disposition. Bobsled may present a diff for pull-request approval only when that disposition reports no blocking finding. A blocking disposition records a bounded rework transition; the mere existence of review prose never satisfies the gate.
An approval is bound to the exact artifact digest and source commit. Editing the artifact invalidates the approval.
Planning and review are read-only. Build work happens in a disposable worktree with no production credentials. Production actions are exposed only through allowlisted, pre-approved runbooks or deployment tools.
"Tests passed" is not evidence. A verification receipt records the command, working tree and commit, start/end time, exit code, output digest, and retained log location. The same rule applies to policy checks, reviews, and deployment gates.
Routing rules, prompts, policies, schemas, capability profiles, and adapter behavior are version-controlled and regression-tested. A model or prompt change must be measured against representative tasks before becoming a default.
Monitoring and control-band detection stay deterministic. A model is invoked only after a version-controlled rule fires. The tier determines whether the agent may log, diagnose read-only, propose a pull request, or invoke an approved runbook.
Bobsled deliberately separates concepts that vendor products sometimes blend:
- Runner: the execution harness, initially
claude,codex, orcopilot. - Model: the exact model requested for the invocation.
- Resolved model: the model actually reported by the runner.
- Model provider/family: normalized identity used for independence rules.
- Role: the bounded job, such as intent writer, planner, builder, verifier, bug reviewer, security reviewer, or incident diagnostician.
- Capability profile: allowed filesystem, command, network, credential, and external-action surface for that invocation.
The routing unit is a runner/model pair plus role and capability profile.
Browser UI
|
Local control-plane API
|-- workflow state machine and gate service
|-- policy/risk engine
|-- artifact and append-only evidence ledger
|-- task/model router
|-- worktree and process supervisor
|-- controlled action broker (MCP-compatible)
|
+-- Claude adapter -> claude -p with safe read-only tools
+-- Codex adapter -> codex exec
+-- Copilot adapter -> copilot -p
The authoritative control plane runs locally with access to the target repository and installed agent CLIs. This is necessary for Git worktrees, deterministic command execution, credential isolation, and process supervision.
The browser is a friendly local interface to that control plane. The supported
product boundary is the web UI on localhost and the loopback-only control
process. Hosted UI and remote-control delivery are out of scope unless this
North Star is explicitly revised.
Canonical controls live under .bobsled/ and in Bobsled's typed configuration.
Vendor-native files are optional projections:
- Claude:
CLAUDE.md,.claude/skills, hooks, and settings. - Codex:
AGENTS.md, skills, rules, profiles, and config layers. - Copilot:
AGENTS.md,.github/copilot-instructions.md, agents, and skills.
Generated projections improve the agent's behavior. They do not replace Bobsled's enforcement.
Every change has a stable change ID and one or more runs. The initial state machine is:
draft_intent
-> awaiting_intent_approval
-> designing
-> awaiting_spec_approval
-> planning
-> awaiting_plan_approval
-> building
-> verifying
-> reviewing
-> awaiting_pr_approval
-> ready_to_deploy
-> awaiting_release_approval
-> deploying
-> monitoring
-> completed
Any stage may move to blocked, failed, cancelled, or a bounded earlier
state through a recorded rework transition. Maintenance events normally create
a new change rather than mutating a completed run.
Transitions are idempotent and require explicit guard results. Restarting the control plane must not duplicate an agent invocation or approval.
Before pull-request approval, verification must be bound to the exact merge candidate after the governed branch is synchronized with the current target branch. Evidence against an obsolete target head cannot satisfy that gate.
Target repositories use one directory per change:
.bobsled/
config.yaml
policies/
prompts/
schemas/
changes/<change-id>/
intent.md
spec.md
plan.md
review.md
approvals/
evidence/
Bobsled's own application data uses an append-only event ledger. Materialized state is a cache rebuilt from those events. Each event has an ID, run/change ID, type, actor identity, timestamp, payload, and previous-event digest.
All runner adapters implement the same logical operations:
- Probe installed version and supported capabilities.
- Start, resume, cancel, and time-bound a run.
- Select a model and capture the resolved model.
- Provide an explicit prompt/policy bundle and working directory.
- Apply the requested capability profile.
- Stream normalized lifecycle, text, tool, command, file, usage, and error events.
- Return a schema-valid final result or a typed failure.
Raw vendor events are retained. The UI and workflow engine consume normalized events.
Bobsled supports two assurance levels:
The runner can use its native edit and shell tools inside a disposable worktree with restricted credentials and network. Bobsled validates the resulting diff and evidence before it may be committed or promoted. This is the practical default for routine work.
Native mutation is disabled or sandboxed read-only. Writes, commands, GitHub operations, deployments, and runbooks go through Bobsled's controlled action broker. Every action is authorized and logged before execution. This is the high-assurance profile for regulated or sensitive work.
Configuration may pin a pair per role and may define fallbacks, budgets, and independence constraints. A representative policy is:
routes:
capture_intent: { runner: copilot, model: "${COPILOT_INTENT_MODEL}" }
design_spec: { runner: claude, model: "${CLAUDE_DESIGN_MODEL}" }
implementation_plan: { runner: codex, model: "${CODEX_PLAN_MODEL}" }
build: { runner: codex, model: "${CODEX_BUILD_MODEL}" }
routine_review: { runner: copilot, model: "${COPILOT_REVIEW_MODEL}" }
security_review: { runner: claude, model: "${CLAUDE_SECURITY_MODEL}" }
independence:
high_risk_review:
different_runner_from_author: true
different_model_family_from_author: true
unavailable: escalate_to_humanThe UI must make this mapping understandable and must display the resolved pair on every artifact and finding.
The primary interface is a control-room view, not a generic chat window.
The first release has these product surfaces:
- Mission Control: repositories, active changes, stage, risk, blocked gates, runner health, and recent events.
- Change detail: artifact chain, stage timeline, active agent output, evidence, findings, and transition history.
- Approval inbox: decisions awaiting the current human role, with artifact digest, diff, concerns, evidence, and approve/reject/rework actions.
- Routing: role-to-runner/model configuration, capability probes, budgets, fallback rules, and independence validation.
- Policies and evals: canonical controls, ownership, enforcement mode, and performance of configured pairs on representative tasks.
The interface should feel operational, calm, and legible. Status, risk, and blocked work must be apparent without opening a transcript.
- Bobsled never stores long-lived provider credentials in project files.
- Credentials are passed only to the specific adapter process that needs them.
- Target-repository code does not run in the same unrestricted credential environment as the control plane.
- Logs redact configured secrets and retain hashes when values are needed for correlation.
- Shell commands are structured argument vectors where possible, not interpolated shell strings.
- Deployment tools are deny-by-default and unavailable outside deployment stages.
- Branch protection and code-owner approval remain external hard gates.
- A web-originated approval requires authenticated identity in shared deployments; local bootstrap mode records the local operator explicitly.
Bobsled develops Bobsled through Bobsled as soon as a capability exists.
Bootstrap is necessarily manual, but it still produces:
- This accepted North Star.
- A living implementation plan.
- An intent, spec, and plan for the bootstrap milestone.
- Verification receipts tied to commits once the ledger exists.
- Adapter contract tests using all installed runners without granting write permissions until the controls are ready.
We do not fake governance. A control unavailable during bootstrap is labeled
planned, not enforced.
- Replacing GitHub branch protection, CI, identity providers, or deployment platforms.
- Building a general-purpose multi-agent chat application.
- Supporting every vendor or remote cloud agent before the three named runners work well locally.
- Autonomous production deployment.
- Treating model confidence statements as deterministic evidence.
- Hiding disagreements between independent reviewers.
Bobsled is useful when a user can:
- Start the local app and see Claude, Codex, and Copilot capability status.
- Register a Git repository and create a governed change from an intent.
- Configure a runner/model pair for each implemented role.
- Run at least plan, build, verification, and independent review stages in isolated worktrees.
- Review committed artifacts and exact evidence in the web UI.
- Approve or reject a gate, with the decision bound to an artifact digest.
- Prevent an author pair from satisfying a configured independent-review gate.
- Rebuild materialized state from the append-only ledger.
- Run adapter contract tests and policy evals without modifying the target repo.
When a design choice is unclear, prefer the option that makes these questions easier to answer after the fact:
- What happened?
- Under whose authority?
- Using which runner, model, policy, and tools?
- What evidence justified the transition?
- Could the actor have bypassed the gate?
If a feature makes the UI more impressive but weakens those answers, it is out of alignment with the North Star.