Skip to content

danshapiro/kilroy

Repository files navigation

Kilroy

Kilroy is a local-first CLI for running StrongDM-style Attractor pipelines in a git repo.

High-level flow:

  1. Convert English requirements to a Graphviz DOT pipeline (attractor ingest).
  2. Validate graph structure and semantics (attractor validate).
  3. Execute node-by-node with coding agents in an isolated git worktree (attractor run).
  4. Resume interrupted runs from logs, CXDB, or run branch (attractor resume).

Installation

Homebrew (macOS and Linux)

brew tap danshapiro/kilroy
brew install kilroy

Go Install

go install github.com/danshapiro/kilroy/cmd/kilroy@latest

Binary Download

Download the latest release from GitHub Releases.

Platform Archive
macOS (Apple) kilroy_*_darwin_arm64.tar.gz
macOS (Intel) kilroy_*_darwin_amd64.tar.gz
Linux (x86_64) kilroy_*_linux_amd64.tar.gz
Linux (ARM64) kilroy_*_linux_arm64.tar.gz
Windows kilroy_*_windows_amd64.zip
Windows (ARM) kilroy_*_windows_arm64.zip

Build from Source

go build -o kilroy ./cmd/kilroy

What Is CXDB?

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_root and checkpoint pointers) is written into this timeline.

Short version: git branch is code history; CXDB is run history.

What Attractor Means Here

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.

StrongDM Attractor vs Kilroy Implementation

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 Provider plug-in runtime with built-ins: OpenAI, Anthropic, Google, Kimi, ZAI, Minimax
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 + create-dotfile skill

Prerequisites

  • 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
  • claude CLI for attractor ingest (or set KILROY_CLAUDE_PATH)

Quickstart

1) Build

go build -o kilroy ./cmd/kilroy

2) Generate a pipeline from English

./kilroy attractor ingest -o pipeline.dot "Solitaire plz"

Notes:

  • Ingest auto-detects skills/create-dotfile/SKILL.md from --repo (default: cwd), then falls back to paths relative to the kilroy binary (including Homebrew-style ../share/kilroy/skills/...) and Go module-cache install roots from build metadata (go install).
  • Use --skill <path> if your skill file is elsewhere.

3) Validate the pipeline

./kilroy attractor validate --graph pipeline.dot

If 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
}

4) Create run.yaml

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 an absolute path if you run kilroy outside repo root.
    command: ["/absolute/path/to/kilroy/scripts/start-cxdb.sh"]
    wait_timeout_ms: 20000
    poll_interval_ms: 250
    ui:
      enabled: true
      command: ["/absolute/path/to/kilroy/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
    kimi:
      backend: api
      api:
        protocol: anthropic_messages
        api_key_env: KIMI_API_KEY
        base_url: https://api.kimi.com/coding
        path: /v1/messages
        profile_family: openai
    zai:
      backend: api
      api:
        protocol: openai_chat_completions
        api_key_env: ZAI_API_KEY
        base_url: https://api.z.ai
        path: /api/coding/paas/v4/chat/completions
        profile_family: openai

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: false
  run_branch_prefix: attractor/run
  commit_per_node: true

runtime_policy:
  stage_timeout_ms: 0
  stall_timeout_ms: 600000
  stall_check_interval_ms: 5000
  max_llm_retries: 6

preflight:
  prompt_probes:
    enabled: true
    transports: [complete, stream]
    timeout_ms: 15000
    retries: 1
    base_delay_ms: 500
    max_delay_ms: 5000

Important:

  • Any provider referenced by a node's llm_provider must have llm.providers.<provider>.backend configured.
  • cxdb.binary_addr, cxdb.http_base_url, and modeldb.openrouter_model_info_path are required.
  • Deprecated compatibility: modeldb.litellm_catalog_* keys are still accepted for one release.
  • Config can be YAML or JSON.

5) Run the pipeline

Real run (recommended/default profile):

unset KILROY_CODEX_PATH KILROY_CLAUDE_PATH KILROY_GEMINI_PATH
./kilroy attractor run --graph pipeline.dot --config run.yaml

Explicit 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-shim

On success, stdout includes:

  • run_id=...
  • logs_root=...
  • worktree=...
  • run_branch=...
  • final_commit=...
  • cxdb_ui=... (when cxdb.autostart.ui.url is configured)

If autostart is used, startup logs are written under {logs_root}:

  • cxdb-autostart.log
  • cxdb-ui-autostart.log

Observe and intervene during long runs:

./kilroy attractor status --logs-root <logs_root>
./kilroy attractor stop --logs-root <logs_root> --grace-ms 30000 --force

CXDB Autostart Notes

  • cxdb.autostart.command is required when cxdb.autostart.enabled=true.
  • This repo includes scripts/start-cxdb.sh and scripts/start-cxdb-ui.sh launchers for local Docker-based CXDB.
  • scripts/start-cxdb.sh is idempotent: it reuses a healthy instance and starts one if missing.
  • By default scripts/start-cxdb.sh requires the named Docker container to avoid silently using a test shim on the same ports.
  • cxdb.autostart.ui.url is optional; when omitted, Kilroy auto-detects it from cxdb.http_base_url if that endpoint serves HTML UI.
  • cxdb.autostart.ui.command is optional; Kilroy starts UI when a command is provided (config or KILROY_CXDB_UI_COMMAND).
  • Kilroy injects these env vars for autostart commands:
    • KILROY_RUN_ID
    • KILROY_CXDB_HTTP_BASE_URL
    • KILROY_CXDB_BINARY_ADDR
    • KILROY_LOGS_ROOT
    • KILROY_CXDB_UI_URL (UI command only)
  • You can also set:
    • KILROY_CXDB_UI_URL to force the printed UI link.
    • KILROY_CXDB_UI_COMMAND as a shell command used to start UI by default.
    • KILROY_CXDB_ALLOW_EXTERNAL=1 to let scripts/start-cxdb.sh accept a pre-existing non-docker CXDB endpoint.
  • If CXDB is unreachable and autostart is disabled, Kilroy fails fast with a remediation hint.

Provider Setup

Provider runtime architecture:

  • Providers are protocol-driven and configured under llm.providers.<provider>.
  • Built-ins include openai, anthropic, google, kimi, zai, cerebras, and minimax.
  • Provider aliases: gemini/google_ai_studio -> google, moonshot/moonshotai -> kimi, z-ai/z.ai -> zai, cerebras-ai -> cerebras, minimax-ai -> minimax.
  • CLI contracts are built-in for openai, anthropic, and google.
  • kimi, zai, cerebras, and minimax are API-only in this release.
  • profile_family selects agent behavior/tooling profile only; API requests still route by llm_provider (native provider key).

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_profile defaults to real.
  • In real, Kilroy uses canonical binaries (codex, claude, gemini) and rejects KILROY_CODEX_PATH, KILROY_CLAUDE_PATH, KILROY_GEMINI_PATH.
  • For fake/shim binaries, set llm.cli_profile: test_shim, configure llm.providers.<provider>.executable, and run with --allow-test-shim.

API backend environment variables:

  • OpenAI: OPENAI_API_KEY (OPENAI_BASE_URL optional)
  • Anthropic: ANTHROPIC_API_KEY (ANTHROPIC_BASE_URL optional)
  • Google: GEMINI_API_KEY or GOOGLE_API_KEY (GEMINI_BASE_URL optional)
  • Kimi (Coding API key): KIMI_API_KEY
  • ZAI: ZAI_API_KEY
  • Cerebras: CEREBRAS_API_KEY
  • Minimax: MINIMAX_API_KEY (MINIMAX_BASE_URL optional)

API prompt-probe tuning (preflight):

  • KILROY_PREFLIGHT_API_PROMPT_PROBE_TIMEOUT_MS (default 30000)
  • KILROY_PREFLIGHT_API_PROMPT_PROBE_RETRIES (default 2, retries only transient failures)
  • KILROY_PREFLIGHT_API_PROMPT_PROBE_BASE_DELAY_MS (default 500)
  • KILROY_PREFLIGHT_API_PROMPT_PROBE_MAX_DELAY_MS (default 5000)

Run config policy takes precedence over env tuning:

  • runtime_policy.* controls stage timeout, stall watchdog, and LLM retry cap.
  • preflight.prompt_probes.* controls prompt-probe enablement, transports, and probe policy.

Kimi compatibility note:

  • Built-in kimi defaults target Kimi Coding (anthropic_messages, https://api.kimi.com/coding).
  • If you use Moonshot Open Platform keys instead, override kimi.api to protocol: openai_chat_completions, base_url: https://api.moonshot.ai, path: /v1/chat/completions.

Run Artifacts

Typical run-level artifacts under {logs_root}:

  • graph.dot
  • manifest.json
  • checkpoint.json
  • final.json
  • run_config.json
  • modeldb/openrouter_models.json
  • run.tgz (run archive excluding worktree/)
  • worktree/ (isolated execution worktree)

Typical stage-level artifacts under {logs_root}/{node_id}:

  • prompt.md
  • response.md
  • status.json
  • stage.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

Commands

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 status --logs-root <dir> [--json]
kilroy attractor stop --logs-root <dir> [--grace-ms <ms>] [--force]
kilroy attractor validate --graph <file.dot>
kilroy attractor ingest [--output <file.dot>] [--model <model>] [--skill <skill.md>] <requirements>
kilroy attractor serve [--addr <host:port>]

--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. Supported providers are openai, anthropic, google, kimi, zai, and minimax (aliases accepted).

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 status success, or validate succeeded
  • 1: command failed, validation error, or final status was not success

HTTP Server Mode (Experimental)

This feature is experimental and subject to breaking changes.

kilroy attractor serve starts an HTTP server that exposes pipeline management via a REST API with Server-Sent Events (SSE) for real-time progress streaming. This enables remote pipeline submission, live observability dashboards, and web-based human-in-the-loop gates.

kilroy attractor serve                    # listens on 127.0.0.1:8080
kilroy attractor serve --addr :9090       # custom address

Endpoints:

Method Path Description
GET /health Server health and pipeline count
POST /pipelines Submit a pipeline run
GET /pipelines/{id} Pipeline status
GET /pipelines/{id}/events SSE event stream
POST /pipelines/{id}/cancel Cancel a running pipeline
GET /pipelines/{id}/context Engine runtime context
GET /pipelines/{id}/questions Pending human-gate questions
POST /pipelines/{id}/questions/{qid}/answer Answer a question

The server defaults to localhost-only binding and includes CSRF protection. There is no authentication — do not expose to untrusted networks.

Skills Included In This Repo

  • skills/using-kilroy/SKILL.md: operational workflow for ingest/validate/run/resume.
  • skills/create-dotfile/SKILL.md: requirements-to-DOT generation instructions.

References

  • 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

License

MIT. See LICENSE.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 7

Languages