Adding A Coding-Agent
June 18, 2026 · View on GitHub
Use this checklist to add a new quorum Coding-Agent target. Keep the shape narrow: one target name, one YAML config, one launcher/HOWTO, one provisioning adapter when needed, and one normalizer.
For running existing targets, use coding-agent-care-and-feeding.md.
Before You Start
Confirm the CLI can run headlessly in a terminal and produce inspectable session evidence. A desktop-only IDE integration cannot satisfy quorum.
Decide:
- Target name, e.g.
myagent, used in--coding-agent myagent. - Required credentials, and whether they use environment variables, OAuth files, or both.
- Where the CLI stores config and sessions when
HOMEis a throwaway directory. - How Superpowers is installed or staged from
SUPERPOWERS_ROOT. - Which raw logs prove behavior and normalize into ATIF.
Do not add public-CI live runs. Live evals are trusted-maintainer operations.
Step 0 — Install The CLI In The Eval Container
The eval container (container/Dockerfile, ubuntu:26.04) bundles every
agent CLI so quorum can launch the target headlessly. A new target's CLI must
be installed here before any live run. (A desktop-only IDE integration with no
headless CLI cannot be containerized and cannot be a quorum target.)
Source the install recipe, don't guess one. In priority order:
- Harbor (
/tmp/harbor-inspect/src/harbor/agents/installed/<agent>.py, pinned — seedocs/superpowers/reference/porting-harbor-converters.md): itsinstall()method is the authoritative, tested recipe for every agent Harbor supports. Read it for the package name, version, and any pre-reqs. - The vendor's official installer (npm package, PyPI package,
uv tool, acurl … | shinstaller, or a signed apt repo).
Verify the package/URL actually exists before editing (npm view <pkg> version,
curl -fsSIL <url> | head -1) — never commit an unverified install.
Match the existing Dockerfile patterns:
- npm-distributed CLI → add the package to the existing
npm install -gblock. - Python CLI →
uv tool install <pkg>(grouped with the other uv-tool installs), or, for a heavy one, a dedicateduv venv+ a small wrapper script in/usr/local/bin. - Single binary → download +
install -m 0755(see goose). - apt-distributed → add a signed keyring + repo, then
apt-get install.
End every install block with a --version/--help check so a bad recipe fails
the build, and symlink the entrypoint into /usr/local/bin if the install dir
isn't already on PATH. Then update:
test/container-dockerfile.test.ts— add the install-intent token(s).container/bin/evals-tool-versions— add the CLI's command name.
Build and smoke it locally (the build is the real gate; the static test only checks the Dockerfile mentions the install):
orb start # ensure the OrbStack docker daemon is up
scripts/evals-container build # multi-stage; resolves the gauntlet build-context
docker run --rm superpowers-evals:local bash -lc '<cmd> --version'
Gotchas (each cost a failed build — watch for them):
- Meta-package / restructured CLI. A package can install but expose no
console script or a moved entrypoint (openhands 1.x is a meta-package with no
openhands.core.main). Pin a known-good version whose layout matches the normalizer, or skip the agent. - Package-relative data dir. A tool that resolves a
CONFIG_DIRrelative to its own package and asserts it exists breaks under a normal install (the data dir is left in the repo). Use an editable install (uv pip install -e) so the package resolves from the checkout (swe-agent). - Installers that self-link as root. A
curl | shinstaller run as root may already place its binary onPATH(FHS layout). Adding your own symlink then clobbers it with a dangling link (hermes — drop the manualln). - Auth-gated version check. Some subcommands require login even for
--version. Verify with the auth-free top-level command (acli --version, notacli rovodev --version); real auth is supplied at run time. - Per-installer
$HOMEpaths. As root, an installer's$HOME/.foo/binis/root/.foo/bin— symlink the binary from there (mimo), or rely on the installer's own PATH linking.
Files To Add
-
Add
coding-agents/<name>.yaml.Include the CLI command, required environment variables, concurrency limits,
home_config_subdir, and the session-log directory pattern used by capture. -
Add
coding-agents/<name>-context/HOWTO.md.This is what the Gauntlet-Agent reads. It should explain how to launch the generated agent command, how to observe the session log, and when the run is complete. Keep it factual and target-specific.
-
Add
coding-agents/<name>-context/launch-agentwhen the target needs a custom launcher.The launcher must run from the scenario workdir, use
$QUORUM_HOME_ENVto pinHOME, XDG dirs, andTMPDIR, and avoid reading the operator's real home-relative state. -
Add or update
src/agents/<name>.ts.Use the provisioning adapter for target-specific config seeding, auth-file copying, preflight checks, plugin staging, and launcher substitutions. Route subprocesses through
src/agents/command-runner.tsso tests can fake them. -
Register the target in
src/agents/index.tsand update the agent config schema if the target needs new fields. -
Add
src/normalize/<name>.ts.Convert the raw session evidence into ATIF
Trajectoryrows. Transcript checks read the normalized trace at<run>/trajectory.json. -
Wire capture/economics behavior only where the shared path cannot cover the new target.
Prefer the existing snapshot/diff capture path. Add target-specific export code only when the CLI stores sessions in a database or hidden state that must be materialized first.
-
Add a bootstrap scenario gated to the new agent.
Use a
# coding-agents: <name>directive inchecks.shand check provisioning and behavioral evidence when possible. -
Update docs.
Add the target to coding-agent-care-and-feeding.md and update README's agent list. If the target has unusual auth, capture, or safety behavior, document that in the care guide.
Implementation Rules
- Keep each run's agent state under
<run>/home; never symlink or read the operator's real~/.<agent>at runtime. - Seed credentials into the run home before launch, with chmod
0600for secret-bearing files. - Use
SUPERPOWERS_ROOTas the plugin/skill source. A globally installed plugin must not satisfy the eval accidentally. - Fail closed when provisioning evidence or expected transcripts are missing.
- Treat empty normalized traces as capture failures for strict backends.
- Keep target-specific behavior in the target adapter and normalizer; do not put agent conditionals in scenarios.
Verification
Run static checks first:
bun run check
bun run quorum check
Then run a live bootstrap smoke for the new target:
bun run quorum run scenarios/<name>-superpowers-bootstrap --coding-agent <name>
bun run quorum show <run-dir>
For a useful smoke, verify:
- The CLI launched under
<run>/home, not the operator's real home. - Superpowers was installed or staged from
SUPERPOWERS_ROOT. - Raw session evidence exists where the config says it should.
<run>/trajectory.jsoncontains the expected skill/tool rows.- Secret-bearing files remain inside
results/and are not committed.