Kilroy is a local-first CLI for running StrongDM-style Attractor pipelines in a git repo.
High-level flow:
- Convert English requirements to a Graphviz DOT pipeline (
attractor ingest). - Validate graph structure and semantics (
attractor validate). - Execute node-by-node with coding agents in an isolated git worktree (
attractor run). - Resume interrupted runs from logs, CXDB, or run branch (
attractor resume).
CXDB is the execution database Kilroy uses for observability and recovery.
- Kilroy records typed run events (run started, stage finished, checkpoint saved, run completed/failed) to CXDB.
- Kilroy stores artifacts (logs, outputs, archives) in CXDB blobs.
- Resume-from-CXDB works because run metadata (like
logs_rootand checkpoint pointers) is written into this timeline.
Short version: git branch is code history; CXDB is run history.
An Attractor pipeline is a digraph where:
- Nodes are stages (
start,exit, codergen tasks, conditionals, human gates, tool steps, parallel/fan-in). - Edges define control flow and optional conditions/retry behavior.
- The engine checkpoints after each stage and routes to the next stage deterministically.
In this repo, each completed node also creates a git checkpoint commit on a run branch.
This implementation is based on the Attractor specification by StrongDM at https://github.com/strongdm/attractor. Here's how Kilroy differs
| Area | From StrongDM Attractor Specs | Kilroy-Specific in This Repo |
|---|---|---|
| Graph DSL + engine semantics | DOT schema, handler model, edge selection, retry, conditions, context fidelity | Concrete Go engine implementation details and defaults |
| Coding-agent loop | Session model, tool loop behavior, provider-aligned tool concepts | Local tool execution wiring and CLI/API backend routing choices |
| Unified LLM model | Provider-neutral request/response/tool/streaming contracts | Concrete provider adapters and environment wiring |
| Provider support | Conceptual provider abstraction | v1 provider set: OpenAI, Anthropic, Google |
| Backend selection | Spec allows flexible backend choices | Backend is mandatory per provider (api/cli), no implicit defaults |
| Checkpointing + persistence | Attractor/CXDB contracts | Required git branch/worktree/commit-per-node and concrete artifact layout |
| Ingestion | Ingestor behavior described in spec docs | attractor ingest implementation: Claude CLI + english-to-dotfile skill |
- Go 1.25+
- Git repo with at least one commit
- Clean working tree before
attractor run/resume - CXDB reachable over binary + HTTP endpoints (or configure
cxdb.autostart) - Provider access for any provider used in your graph
claudeCLI forattractor ingest(or setKILROY_CLAUDE_PATH)
go build -o kilroy ./cmd/kilroy./kilroy attractor ingest -o pipeline.dot "Solitaire plz"Notes:
- Ingest auto-detects
skills/english-to-dotfile/SKILL.mdunder--repo(default: cwd). - Use
--skill <path>if your skill file is elsewhere.
./kilroy attractor validate --graph pipeline.dotIf you want to author a graph manually instead of using ingest, this minimal example is valid:
digraph Simple {
graph [
goal="Run tests and summarize results",
model_stylesheet="
* { llm_provider: openai; llm_model: gpt-5.2-codex; }
"
]
start [shape=Mdiamond]
exit [shape=Msquare]
run_tests [shape=box, prompt="Run tests and write status.json"]
summarize [shape=box, prompt="Summarize outcomes and write status.json"]
start -> run_tests -> summarize -> exit
}version: 1
repo:
path: /absolute/path/to/target/repo
cxdb:
binary_addr: 127.0.0.1:9009
http_base_url: http://127.0.0.1:9010
autostart:
enabled: true
# argv form; use "sh -lc" if you need shell features.
command: ["sh", "-lc", "./scripts/start-cxdb.sh"]
wait_timeout_ms: 20000
poll_interval_ms: 250
ui:
enabled: true
command: ["sh", "-lc", "./scripts/start-cxdb-ui.sh"]
url: "http://127.0.0.1:9020"
llm:
cli_profile: real
providers:
openai:
backend: cli
anthropic:
backend: api
google:
backend: api
modeldb:
openrouter_model_info_path: /absolute/path/to/kilroy/internal/attractor/modeldb/pinned/openrouter_models.json
openrouter_model_info_update_policy: on_run_start
openrouter_model_info_url: https://openrouter.ai/api/v1/models
openrouter_model_info_fetch_timeout_ms: 5000
git:
require_clean: true
run_branch_prefix: attractor/run
commit_per_node: trueImportant:
- Any provider referenced by a node's
llm_providermust havellm.providers.<provider>.backendconfigured. cxdb.binary_addr,cxdb.http_base_url, andmodeldb.openrouter_model_info_pathare required.- Deprecated compatibility:
modeldb.litellm_catalog_*keys are still accepted for one release. - Config can be YAML or JSON.
Real run (recommended/default profile):
unset KILROY_CODEX_PATH KILROY_CLAUDE_PATH KILROY_GEMINI_PATH
./kilroy attractor run --graph pipeline.dot --config run.yamlExplicit test-shim run (for local fake-provider testing only):
llm:
cli_profile: test_shim
providers:
openai:
backend: cli
executable: /absolute/path/to/fake-codex./kilroy attractor run --graph pipeline.dot --config run.yaml --allow-test-shimOn success, stdout includes:
run_id=...logs_root=...worktree=...run_branch=...final_commit=...cxdb_ui=...(whencxdb.autostart.ui.urlis configured)
If autostart is used, startup logs are written under {logs_root}:
cxdb-autostart.logcxdb-ui-autostart.log
cxdb.autostart.commandis required whencxdb.autostart.enabled=true.cxdb.autostart.ui.urlis optional; when omitted, Kilroy auto-detects it fromcxdb.http_base_urlif that endpoint serves HTML UI.cxdb.autostart.ui.commandis optional; Kilroy starts UI when a command is provided (config orKILROY_CXDB_UI_COMMAND).- Kilroy injects these env vars for autostart commands:
KILROY_RUN_IDKILROY_CXDB_HTTP_BASE_URLKILROY_CXDB_BINARY_ADDRKILROY_LOGS_ROOTKILROY_CXDB_UI_URL(UI command only)
- You can also set:
KILROY_CXDB_UI_URLto force the printed UI link.KILROY_CXDB_UI_COMMANDas a shell command used to start UI by default.
- If CXDB is unreachable and autostart is disabled, Kilroy fails fast with a remediation hint.
CLI backend command mappings:
openai->codex exec --json --sandbox workspace-write ...anthropic->claude -p --output-format stream-json ...google->gemini -p --output-format stream-json --yolo ...
Execution policy:
llm.cli_profiledefaults toreal.- In
real, Kilroy uses canonical binaries (codex,claude,gemini) and rejectsKILROY_CODEX_PATH,KILROY_CLAUDE_PATH,KILROY_GEMINI_PATH. - For fake/shim binaries, set
llm.cli_profile: test_shim, configurellm.providers.<provider>.executable, and run with--allow-test-shim.
API backend environment variables:
- OpenAI:
OPENAI_API_KEY(OPENAI_BASE_URLoptional) - Anthropic:
ANTHROPIC_API_KEY(ANTHROPIC_BASE_URLoptional) - Google:
GEMINI_API_KEYorGOOGLE_API_KEY(GEMINI_BASE_URLoptional)
Typical run-level artifacts under {logs_root}:
graph.dotmanifest.jsoncheckpoint.jsonfinal.jsonrun_config.jsonmodeldb/openrouter_models.jsonrun.tgz(run archive excludingworktree/)worktree/(isolated execution worktree)
Typical stage-level artifacts under {logs_root}/{node_id}:
prompt.mdresponse.mdstatus.jsonstage.tgz- CLI backend extras:
cli_invocation.json,stdout.log,stderr.log,events.ndjson,events.json,output_schema.json,output.json - API backend extras:
api_request.json,api_response.json,events.ndjson,events.json
kilroy attractor run [--allow-test-shim] [--force-model <provider=model>] --graph <file.dot> --config <run.yaml> [--run-id <id>] [--logs-root <dir>]
kilroy attractor resume --logs-root <dir>
kilroy attractor resume --cxdb <http_base_url> --context-id <id>
kilroy attractor resume --run-branch <attractor/run/...> [--repo <path>]
kilroy attractor validate --graph <file.dot>
kilroy attractor ingest [--output <file.dot>] [--model <model>] [--skill <skill.md>] <requirements>
--force-model can be passed multiple times (for example, --force-model openai=gpt-5.2-codex --force-model google=gemini-3-pro-preview) to override node model selection by provider.
Additional ingest flags:
--repo <path>: repo root to run ingestion from (default: cwd)--no-validate: skip post-generation DOT validation
Exit codes:
0: run/resume finished with final statussuccess, or validate succeeded1: command failed, validation error, or final status was notsuccess
skills/using-kilroy/SKILL.md: operational workflow for ingest/validate/run/resume.skills/english-to-dotfile/SKILL.md: requirements-to-DOT generation instructions.
- StrongDM Attractor specs:
docs/strongdm/attractor/ - Attractor spec:
docs/strongdm/attractor/attractor-spec.md - Coding Agent Loop spec:
docs/strongdm/attractor/coding-agent-loop-spec.md - Unified LLM spec:
docs/strongdm/attractor/unified-llm-spec.md - Kilroy metaspec:
docs/strongdm/attractor/kilroy-metaspec.md - Ingestor spec:
docs/strongdm/attractor/ingestor-spec.md - CXDB project: https://github.com/strongdm/cxdb
MIT. See LICENSE.