Contributing to Chief
July 6, 2026 · View on GitHub
Thanks for your interest! Chief is small on purpose — the whole brain fits in your head after an afternoon of reading. This document gets you productive in five minutes.
Dev setup
git clone https://github.com/SmileLikeYe/agent-chief && cd agent-chief
uv sync --dev # Python 3.12+, https://docs.astral.sh/uv/
make test lint # 218 tests + ruff, fully offline — no keys needed
make demo # the offline day-of-engineer replay
The test suite needs no network, no API keys, and no real ~/.chief —
tests point CHIEF_HOME at a tmpdir and use the deterministic fixtures
judge. If your change needs a key to test, it's designed wrong; add a cassette
(see judge/fixtures.py and the httpx MockTransport tests).
The rules of the house
- Tests first. Every behavior change lands with the test that pins it.
The demo routing table (
tests/test_demo_routing.py) is a full-table regression — if your change legitimately re-routes a demo event, update the fixture table deliberately and say why in the PR; never loosen the test. SPEC.md §13is a hard no. No arbitrary shell execution (the shell executor is a query-only argv whitelist — nevershell=True), no mic/screen/geofencing, no web UI, no cloud sync, no telemetry.- Ambiguity → simpler option + a one-line ADR in
docs/decisions.md. - No prompt change merges without an eval diff report. Prompts are
versioned Jinja2 templates under
judge/templates/<version>/. To change one: copy the current version dir to a new version, edit there, runchief eval --compare <old> <new>against a real backend, and attach the generatedeval/reports/compare-*.md(agreement delta + flipped samples) to the PR. - Keep the core dependency-light. Embeddings default to the
dependency-free
HashEmbedder; heavyweight deps go behind optional extras. - Green on every commit:
make lint testmust pass.
Commit style
feat(scope): add per-topic dispatch propensity
fix: telegram poller surfaces HTTP errors
docs: clarify quiet-hours semantics
Pull requests
- One logical change per PR; small is beautiful.
- Explain why in the description; the diff explains what.
- CI (ruff + pytest on 3.12) must be green.
Good first areas
- New scene providers (
context/providers/) — e.g. OS focus/lock state. - New judge backends (
judge/) — subclass the HTTP judge, ~40 lines. - New ingest sources (
ingest/sources/) — subclassPoller, ~60 lines. - New delivery channels (
delivery/) — but checkROADMAP.mdfirst; Slack/Discord/WeChat are deliberately v2.
Questions
Open a discussion or issue — unpolished questions welcome.