Code Cannon is designed to be configured, not forked. All project-specific behavior is controlled through .codecannon.yaml and a few optional extension points.
Code Cannon organizes skills into domain-specific bundles called skill groups. Each group lives in its own directory under skills/ (e.g. skills/github-agile/). A project enables exactly one group via the required skill_group: setting in .codecannon.yaml:
skill_group: github-agileSync errors out if skill_group is missing, empty, or names a directory that doesn't exist. There is no default — the choice is always explicit.
To add a new group, create a sibling directory under skills/ containing the new skill markdown files. Two groups may freely define skills with the same name (e.g. both a github-agile and a jira-agile start skill); only one is active per project, so there is no collision.
Skills in skills/<group>/ use {{PLACEHOLDER}} tokens wherever behavior needs to vary between projects. When you run sync.py, it reads your .codecannon.yaml, substitutes each placeholder with your project's value, and writes the generated skill files.
For example, the /submit-for-review skill contains:
Run:
{{CHECK_CMD}}If your .codecannon.yaml has CHECK_CMD: npm run lint && npm test, the generated file will contain npm run lint && npm test in place of the token.
See the full list of available placeholders in the config reference.
# Trunk-based (simplest)
BRANCH_PROD: main
BRANCH_DEV: ""
BRANCH_TEST: ""
# Two-branch with QA gate
BRANCH_PROD: main
BRANCH_DEV: development
# Three-branch with staging
BRANCH_PROD: main
BRANCH_DEV: development
BRANCH_TEST: stagingSee branching models for a full explanation of each mode.
CHECK_CMD: make check # must pass before /submit-for-review proceeds
DEV_CMD: make dev # suggested to user after /start writes code
DEPLOY_PREVIEW_CMD: make deploy-preview
DEPLOY_PROD_CMD: make deploy-prodThese can be any shell command. If your project uses npm scripts:
CHECK_CMD: npm run lint && npm test
DEV_CMD: npm run dev
DEPLOY_PREVIEW_CMD: npm run deploy:staging
DEPLOY_PROD_CMD: npm run deploy:production# AI review blocks merge on critical findings (default)
REVIEW_GATE: "ai"
# AI review posts findings but never blocks merge
REVIEW_GATE: "advisory"
# No AI review at all — /submit-for-review merges immediately after checks pass
REVIEW_GATE: "off"# Labels the agent can choose from when creating issues
TICKET_LABELS: "bug,enhancement,documentation,good first issue"
# Allow the agent to create new labels on the fly
TICKET_LABEL_CREATION_ALLOWED: "true"
# Pin all new issues to a specific milestone
DEFAULT_MILESTONE: "Sprint 4"QA_READY_LABEL: "ready-for-qa"
QA_PASSED_LABEL: "qa-passed"
QA_FAILED_LABEL: "qa-failed"The review agent prompt is generated to the path in REVIEW_AGENT_PROMPT. Two config keys make it project-aware:
Infrastructure and framework rules that are easy to get wrong and hard to catch in tests. These are injected into the review agent's "Platform Compliance" section.
PLATFORM_COMPLIANCE_NOTES: |
- Postgres: use parameterized queries via the ORM; never raw string interpolation
- Redis: TTLs required on all keys written in request handlers
- Next.js: server components must not import client-only modulesNon-obvious team rules that differ from common defaults. Injected into the review agent's "Conventions" section.
CONVENTIONS_NOTES: |
- API logic in services/, UI in app/ — no business logic in components
- Use the design system tokens — no hardcoded hex values
- Feature flags via the flags/ module only; no ad-hoc env var checksThese are the primary way Code Cannon becomes project-aware rather than a generic tool. Until set, both sections default to an HTML comment (invisible to agents, visible to you as a nudge).
After running sync, add project-specific sections to AGENTS.md below the separator line — architecture notes, coding conventions, platform gotchas. These are not managed by Code Cannon sync and won't be overwritten.
The AGENTS.md template provides the structure. Your additions live alongside the generated content and give agents broader context about your project beyond what the skill placeholders cover.
Every generated file includes a hash comment in its header:
<!-- generated by CodeCannon/sync.py | skill: start | adapter: claude | hash: 24909c1a | DO NOT EDIT -->
When you run sync.py, it computes the expected hash for each file. If the file on disk has a different hash (because you edited it manually), sync.py warns and skips that file. This protects intentional customizations.
To overwrite anyway: sync.py --force.
To regenerate only specific skills: sync.py --skill start,submit-for-review.
./CodeCannon/sync.py [options]
Options:
--config path Project config file (default: .codecannon.yaml)
--force Overwrite customized files without prompting
--dry-run Preview what would be written, no changes made
--skill name,... Sync only specific skill(s), comma-separated
The version-related placeholders control how /deploy reads and bumps versions:
VERSION_READ_CMD: "cat VERSION" # prints current version
BUMP_PATCH_CMD: make bump-patch # bump + commit + tag
BUMP_MINOR_CMD: make bump-minor
BUMP_MAJOR_CMD: make bump-major
SET_VERSION_CMD: "make set-version V=" # arbitrary version (value appended)SET_VERSION_CMD is concatenated with the version with no implicit separator, so it must include its own trailing separator: = for kwarg-style ("make set-version V="), or a trailing space for positional-style ("npm version ").
These commands are expected to handle the commit and tag creation themselves. /deploy calls them and then pushes.