Coral extend
Add a new component to the CORAL framework itself — a new agent runtime under `coral/agent/builtin/` (claude_code/codex/cursor_agent style), a new CLI command in `coral/cli/`, a new bundled skill or subagent template under `coral/template/skills/` or `coral/template/agents/`, a new hook in `coral/hooks/`, a new field in `coral/config.py`, or a framework-level extension to the grader stack under `coral/grader/`. NOT for writing a per-task grader or adding an example task — use `coral-new-task` for that. NOT for debugging existing code — use `coral-debug`.From its SKILL.md
npx -y skills add Human-Agent-Society/CORAL --skill coral-extendAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
SKILL.md
6.3 KB, as published. Nobody here has run it
Extending the CORAL framework
For day-to-day debug / reproduce loops see the sibling coral-debug skill. For creating a new examples/<task>/ (seed + task.yaml + grader package) see coral-new-task. This skill covers adding new components to the CORAL package itself.
Extending the grader infrastructure
If you're writing a grader for a specific task, use coral-new-task. This section is only for changes to the grader framework under coral/grader/:
- New helpers on
TaskGrader(coral/grader/task_grader.py) — make sure they're useful to multiple existing example graders before adding. - New
GraderInterfaceimplementations (coral/grader/protocol.py/base.py) — the bar is high; the existing protocol covers everything we currently need. - Daemon-side changes (
coral/grader/daemon.py) — concurrency, queue caps, worktree isolation, retry policy. Cover withtests/test_grader_daemon.py. - Built-in graders under
coral/grader/builtin/—function_grader.pyis the only one today; not wired throughtask.yaml. New built-ins should justify why aTaskGradersubclass per task isn't enough.
A new agent runtime
Adding a new runtime (e.g. another coding-agent CLI) means three small files plus a registry entry.
- Create
coral/agent/builtin/<name>.pyand subclassAgentRuntime(coral/agent/runtime.py). Existing runtimes are the canonical reference —claude_code.pyis the most complete;codex.pyandcursor_agent.pyare smaller and easier to mimic. - Register the runtime in
coral/agent/registry.py:_RUNTIMES["my_runtime"] = MyRuntime _ALIASES["mine"] = "my_runtime" _DEFAULT_MODELS["my_runtime"] = "default-model-id" - Decide the runtime's native shared-state directory name (
.claudefor Claude Code,.codexfor Codex, etc.). The worktree symlink uses this; pass it throughshared_dirsogenerate_coral_md(...)renders the right paths. - If the runtime needs special config plumbing (e.g.
cursor_agent.json,opencode.json, gateway port), follow theopencodepattern: emit a per-agent config file inside the worktree at startup. - Add a smoke test in
tests/test_<runtime>.pymodeled ontests/test_cursor_agent.py.
Reference recent additions: PR #79 (cursor_agent), commit f6f266e (codex web_search config fix).
A new CLI command
CLI is an old-school argparse single-file dispatcher.
- Add a parser block in
coral/cli/__init__.py::main(). Match the existing style —_HelpOnErrorParser, an epilog withExamples:,_CommandHelpFormatter. Add the new command name to_VISIBLE_COMMANDSso "did you mean?" suggestions work. - Implement
cmd_<name>(args: argparse.Namespace) -> Nonein the most-fitting module undercoral/cli/:start.py— agent lifecycle (start/resume/stop/status)query.py— read-only inspection (log/show/notes/skills/runs)eval.py— agent-side commands that mutate the worktree (eval/wait/diff/revert/checkout)heartbeat.py— heartbeat configurationui.py— dashboardauthor.py—init/validateCreate a new module if none of those fit; keep imports lazy socoral --helpstays fast.
- Wire the function into the
commands = {...}dict at the bottom ofmain(). - If your command operates on a specific run, accept
--task/--runvia_add_run_args(parser)and resolve withcoral.cli._helpers.find_coral_dir. - Add an example to
CLAUDE.md's Commands section.
A new bundled skill or subagent template
These ship inside the package and are seeded into every run's .coral/public/skills/ (or agents/) by coral/workspace/project.py.
- Skill — create
coral/template/skills/<name>/SKILL.mdwith frontmatternameanddescription. Includescripts/andreferences/subdirs as needed; existing examples aredeep-research,organize-files,skill-creator. - Subagent — create
coral/template/agents/<name>.md(single markdown file). Existing examples aredeep-researcherandlibrarian. - Add a test in
tests/test_template.pyif the rendering pulls in new template variables.
The seed copy is one-shot per run (if not dst.exists()), so iterating on template content during development means deleting <run_dir>/.coral/public/skills/<name>/ and re-running coral start, or just editing the destination directly for that run.
A new hook
Right now there's only coral/hooks/post_commit.py. If you add another hook:
- Define a clear single entrypoint function (model on
submit_eval). - Make it pure-function over
coral_dir+ agent_id where possible. - Atomic writes to
.coral/public/only; never write to a worktree from a hook. - Add coverage to
tests/test_hooks.py.
Configuration changes
coral/config.py is dataclass-based and merged via OmegaConf. When adding a new field:
- Add it to the right dataclass (
AgentConfig,GraderConfig, ...) with a sensible default. - If it deserves runtime validation, add it to the
__post_init__of that dataclass. - Cover the new field in
tests/test_config.py. - Update
examples/<task>/task.yamlonly if the field is task-author facing — internal knobs should stay defaulted. - Mention it in
CLAUDE.mdif it changes user-visible behavior; otherwise leave the docs alone (CLAUDE.md describes invariants, not every flag).
Don't forget
- Lint + test before pushing:
uv run ruff check . && uv run ruff format . && uv run pytest tests/ -v. - Backward compatibility for run dirs. People resume old runs. Anything that reads from
.coral/public/must tolerate missing files (return defaults), not crash. - No agent-side
git. All commits go throughcoral eval→submit_eval. Don't add helpers that shell out to git from agent context.