Σ sigma
· coding agent

A reliable coding-agent CLI in Go: Claude Code in capability, hexagonal in philosophy, extras shipped as plugins — with a built-in A/B eval harness for testing changes with real data.

Sigma's premise: an agent becomes reliable when its output is constrained by layers you compose — sensors (observe), guides (steer), and gates (permit / deny / validate). Every layer is a small typed adapter behind a narrow port. It authenticates with an OpenAI API key from the OPENAI_API_KEY environment variable.

Install

git clone https://github.com/tacoda/sigma
cd sigma
make build          # -> bin/sigma

Requires Go 1.25+ and an OpenAI API key exported as OPENAI_API_KEY.

Quickstart

sigma auth status      # verify OPENAI_API_KEY is set
sigma init             # scaffold a starter .sigma/ charter
sigma run "fix the failing test in internal/foo"   # one-shot
sigma chat             # interactive TUI (--resume to continue)

run gates every mutating tool call for approval (--yes auto-approves); read-only tools run without prompting.

The charter — your .sigma/

A charter is the config bundle the agent loads from .sigma/ (and ~/.sigma/ for user-global). It shapes behavior without touching code:

Layers: sensors, guides, gates

Hooks can be declarative YAML, shell commands, or in-process Go callbacks — all on one bus. A Stop hook that exits non-zero makes the agent keep working until it's fixed.

Layers: a design methodology

Sigma leans into layers as its architecture — a dedicated middleware stack for an agent (Rack / Express / gRPC interceptors, but for a coding agent). The loop is a thin core; every cross-cutting concern is a typed layer wrapping one of three spines. A layer receives next and can observe, transform, short-circuit, or wrap — so a guard blocks, a cache returns early, redaction rewrites, a budget refuses.

Plugins and charters contribute layers; ordering is the lever (canon guards before the sandbox, budget outermost). The stack is introspectable — agent behavior reads as a pipeline:

$ sigma layers
turn spine (outer → inner):
  compaction → prompt-gate → loop
model spine (outer → inner):
  budget → retry → llm
tool spine (outer → inner):
  dry-run → ui → hooks → permission → exec

Because the stack is composed per charter, you can A/B a whole stack with the eval harness — measure, with statistical data, what a layer change does before and after. Sensors / guides / gates are what a layer does; the spines are where it plugs in.

Extras (plugins)

canon is enabled by default: it contributes the engineering & platform canon to the system prompt as a guide, and installs deterministic guards that block canon violations at the tool boundary — sensitive-file access, secrets or debug artifacts in written content, dangerous shell (rm -rf, force-push, reset --hard, --no-verify, piping downloads to a shell), and AI attribution in commits.

Optional bundles enabled in settings.json:

Plugins compose over the ports; they never touch the agent core.

Eval harness

A general A/B experimentation primitive: compare two variants (two charters, before/after) over a case suite, scored with programmatic checks, event-trace assertions, and an LLM judge, into a statistically-grounded HTML report.

sigma eval experiments/tighten-review/experiment.yaml         # replay (fake, free, deterministic)
sigma eval --live experiments/tighten-review/experiment.yaml  # real agent; records transcripts

Runs are fake-by-default (replay a recorded transcript); --live runs the real agent and records transcripts for future replay. The engine is generic — higher layers embed it with their own runner and scorers.

Ports & adapters throughout: the agent core depends only on narrow interfaces, wired at a single composition root. Status: early and evolving.