canary¶
Scan, update, create, verify and manage CANARY tokens across
repositories, emit status.json / status.csv, and verify GAP claims.
Now with full spec-kit integration! Initialize projects with .canary/ workflow structure including slash commands, constitutional principles, and AI agent integration.
Build¶
go build -o ./bin/canary ./cmd/canary
# Install system-wide (optional)
sudo cp ./bin/canary /usr/local/bin/
# The binary is self-contained with embedded templates
# No additional files needed for installation
CLI Commands¶
Canary provides spec-kit-inspired commands for managing CANARY tokens.
Quick Reference:
canary init <project> # Initialize with full workflow
canary constitution # Create/view project principles
canary specify "feature" # Create requirement spec
canary plan RKEY-<ASPECT>-XXX # Generate implementation plan
canary implement RKEY-<ASPECT>-XXX # Show implementation locations (reduces context!)
canary create RKEY-<ASPECT>-XXX # Generate CANARY token
canary scan # Scan for tokens and generate reports
# Migration from spec-kit or legacy canary
canary detect # Detect existing system type
canary migrate-from spec-kit --dry-run # Preview migration
canary migrate-from spec-kit # Execute migration
# Advanced: Structured Storage & Priority Management
canary migrate all # Run database migrations
canary index # Build SQLite database from tokens
canary list --status STUB # List tokens with filtering
canary search "keyword" # Search by keywords
canary prioritize RKEY-<ASPECT>-XXX Feature 1 # Set priority (1=highest)
canary checkpoint "name" # Create state snapshot
canary rollback 1 # Roll back last migration
Key Features:
- canary implement shows exact file:line locations, reducing agent context by ~95%
- canary index + list/search enable priority-driven development with SQLite storage
See CLI_COMMANDS.md for complete agent reference documentation.
Migrating from spec-kit or Legacy CANARY¶
Already have a spec-kit or legacy CANARY project? Migrate it easily:
# 1. Detect what system you have
canary detect
# Detects: spec-kit, legacy-canary, migrated, or unknown
# 2. Preview migration (no changes)
canary migrate-from spec-kit --dry-run
# 3. Execute migration
canary migrate-from spec-kit
# Creates .canary/ structure with templates and slash commands
# 4. Start using the unified system
canary index
canary list
Features: - Auto-detects spec-kit, legacy CANARY, or already-migrated systems - Prevents double-migration (detects if already using unified system) - Creates files from embedded templates (constitution, slash commands) - Preserves existing files (status.json, GAP_ANALYSIS.md) - Dry-run mode for safe preview
See MIGRATION_GUIDE.md for complete migration instructions.
Initialize a New Project¶
canary init <project-name>
# Creates:
# - .canary/ directory with full workflow structure
# - .canary/memory/constitution.md - Project governing principles
# - .canary/templates/commands/ - Slash commands for AI agents
# - .canary/templates/ - Spec and plan templates
# - .canary/scripts/ - Automation scripts
# - README_CANARY.md - Token format specification
# - GAP_ANALYSIS.md - Requirements tracking template
# - CLAUDE.md - AI agent integration guide
Create a New Requirement Token¶
canary create RKEY-<ASPECT>-105 "FeatureName" --aspect API --status IMPL --owner team
# Outputs a properly formatted CANARY token ready to paste
Scan for Tokens¶
canary scan --root . --out status.json --csv status.csv
canary scan --root . --verify GAP_ANALYSIS.md --strict
canary scan --root . --update-stale # Auto-update stale TESTED/BENCHED tokens
Filtering Scanned Files¶
The scanner supports two methods for excluding files from scans:
1. .canaryignore file (gitignore-style patterns)
Create a .canaryignore file in your project root to exclude template files, documentation, test fixtures, and generated content:
# Template directories
base/
embedded/
.canary/
.claude/
# Documentation with example tokens
docs/
*_SUMMARY*.md
IMPLEMENTATION_*.md
# Test data
testdata/
*_test.go
# Build artifacts
dist/
*.db
The .canaryignore file uses standard gitignore syntax:
- # for comments
- / for directory separators
- * for wildcards, ** for recursive wildcards
- ! to negate patterns (whitelist)
- Patterns are relative to the project root
2. --skip regex flag
For one-off exclusions, use the --skip flag with a regex pattern:
canary scan --root . --skip '(^|/)(.git|node_modules|vendor)(/|$)'
When to use each:
- .canaryignore: Permanent project-specific exclusions (templates, docs, test fixtures)
- --skip: Temporary or command-specific exclusions (build artifacts, directories)
Exit Codes¶
- Exit 0: OK
- Exit 2: Verification/staleness failed
- Exit 3: Parse or IO error
Legacy Usage¶
The standalone scanner is still available at tools/canary:
go run ./tools/canary --root . --out status.json
Token format
Example template (replace with actual values):
CANARY: REQ=RKEY-<ASPECT>-101; FEATURE="MyFeature"; ASPECT=API; STATUS=IMPL; TEST=TestCANARY_RKEY-<ASPECT>_101_API_MyFeature; BENCH=BenchmarkCANARY_RKEY-<ASPECT>_101_API_MyFeature; OWNER=team; UPDATED=2025-10-15
Valid ASPECT values: API, CLI, Engine, Planner, Storage, Wire, Security, Docs, Encode, Decode, RoundTrip, Bench, FrontEnd, Dist
Valid STATUS values: MISSING, STUB, IMPL, TESTED, BENCHED, REMOVED
Supported comment styles: //, #, --, <!-- (Python, Go, Bash, SQL, Markdown, etc.)
Status Auto-Promotion¶
The scanner auto-promotes statuses based on evidence references:
| From | Evidence Condition | To |
|---|---|---|
| IMPL | ≥1 test (TEST=) | TESTED |
| IMPL/TESTED | ≥1 benchmark (BENCH=) | BENCHED |
Notes:
- Promotion is applied in-memory; original source comments remain unchanged.
- BENCHED dominates TESTED in summary counts.
--strictstill validates staleness on TESTED/BENCHED after promotion.- A future
--no-promoteflag may allow raw status reporting.
Example: if a feature is marked STATUS=IMPL and has a TEST=TestCANARY_REQ_GQL_030_TxnCommit, the report will show it as TESTED.
Testing¶
cd tools/canary
go test -v
CANARY at a glance¶
Policy excerpt (see docs/CANARY_POLICY.md). Example tokens:
CANARY: REQ=RKEY-<ASPECT>-101; FEATURE="ScannerCore"; ASPECT=Engine; STATUS=TESTED; TEST=TestCANARY_RKEY-<ASPECT>_101_Engine_ScanBasic; BENCH=BenchmarkCANARY_RKEY-<ASPECT>_101_Engine_Scan; OWNER=canary; UPDATED=2025-09-20
CANARY: REQ=RKEY-<ASPECT>-102; FEATURE="VerifyGate"; ASPECT=CLI; STATUS=TESTED; TEST=TestCANARY_RKEY-<ASPECT>_102_CLI_Verify; BENCH=BenchmarkCANARY_RKEY-<ASPECT>_102_CLI_Verify; OWNER=canary; UPDATED=2025-09-20
Structured Storage & Priority Management¶
Canary now includes SQLite-based structured storage with proper migrations for advanced token management.
Database Migrations¶
Automatic migration: All database commands automatically detect and run migrations when needed. You don't need to manually migrate!
# Database commands auto-migrate before running
canary index # Detects DB version, migrates if needed, then indexes
canary list # Auto-migrates, then lists
canary search # Auto-migrates, then searches
# Manual migration (rarely needed)
canary migrate all # Force migration
canary rollback 1 # Roll back 1 migration
Migration system:
- Automatic detection: Checks database version on startup
- Auto-upgrade: Migrates from old versions automatically
- User feedback: Shows migration progress (e.g., "🔄 Migrating database from version 0 to 1...")
- Uses golang-migrate/migrate for version control
- Pure Go SQLite driver (modernc.org/sqlite) - no CGO required
- Migration files in internal/storage/migrations/
- Cross-platform compatible (Linux, macOS, Windows)
Example auto-migration:
$ canary list
🔄 Migrating database from version 0 to 1...
✅ Database migrated to version 1
Found 10 tokens:
...
Index and Query Tokens¶
# Build/rebuild database from codebase (auto-runs migrations)
canary index --root . --db .canary/canary.db
# List tokens with filtering and priority ordering
canary list --status STUB --limit 10
canary list --phase Phase1 --owner backend
canary list --order-by "priority ASC, updated_at DESC"
# Search by keywords
canary search "authentication"
canary search "oauth jwt"
# Update priorities (1=highest, 10=lowest)
canary prioritize RKEY-<ASPECT>-001 JWTGeneration 1
Extended Metadata¶
Tokens can now include: - PRIORITY: 1-10 (affects ordering) - PHASE: Phase0, Phase1, Phase2, Phase3 - KEYWORDS: Comma-separated tags for search - SPEC_STATUS: draft, approved, in-progress, completed, archived - DEPENDS_ON: Comma-separated requirement IDs - BLOCKS: Requirement IDs this blocks - RELATED_TO: Related requirement IDs - Git Integration: Automatic commit hash and branch tracking
Checkpoints¶
Create state snapshots for tracking progress:
canary checkpoint "phase1-complete" "All Phase 1 features implemented"
canary checkpoint "v1.0.0" "Release 1.0.0 snapshot"
Checkpoints capture: - Token counts by status (STUB, IMPL, TESTED, BENCHED) - Git commit hash and timestamp - Full JSON snapshot of all tokens
Spec-Kit Integration¶
Canary includes a full spec-kit-inspired workflow for requirement-driven development:
AI Agent Integration¶
After running canary init, AI agents can use slash commands:
/canary.constitution- Create/update project governing principles/canary.specify- Create requirement specification from feature description/canary.plan- Generate technical implementation plan for a requirement/canary.scan- Scan codebase for CANARY tokens and generate reports/canary.verify- Verify GAP_ANALYSIS.md claims against actual implementation/canary.update-stale- Auto-update UPDATED field for stale tokens (>30 days)
Constitutional Governance¶
Projects initialized with canary init include a constitution (.canary/memory/constitution.md) with 9 articles:
- Requirement-First Development - Every feature starts with a CANARY token
- Specification Discipline - Focus on WHAT before HOW
- Token-Driven Planning - Trackable, verifiable units of work
- Test-First Imperative - Non-negotiable TDD approach
- Simplicity and Anti-Abstraction - Minimal complexity, prefer standard library
- Integration-First Testing - Real environments over mocks
- Documentation Currency - CANARY tokens ARE the documentation
- Continuous Improvement - Metrics-driven development
- Amendment Process - How to evolve the constitution
Workflow Example¶
# Initialize project with full workflow
canary init my-project
cd my-project
# Use AI agent slash commands (in Claude Code, Cursor, etc.)
# /canary.constitution
# /canary.specify "Add user authentication with OAuth2"
# /canary.plan RKEY-<ASPECT>-001 "Use Go standard library"
# Find implementation points (reduces context!)
canary implement RKEY-<ASPECT>-001 --status STUB
# Shows exact locations of unimplemented features
# Get context for specific feature
canary implement RKEY-<ASPECT>-001 --feature JWTGeneration --context
# Shows file:line with surrounding code
# Track progress
canary implement RKEY-<ASPECT>-001
# Shows: Progress: 67% (2/3)
# Scan and verify
canary scan --root . --out status.json --csv status.csv
canary scan --root . --verify GAP_ANALYSIS.md --strict
Project Structure¶
.canary/
├── memory/
│ └── constitution.md # Project principles
├── scripts/
│ └── create-new-requirement.sh # Automation
├── templates/
│ ├── commands/ # Slash command definitions
│ ├── spec-template.md # Requirement template
│ └── plan-template.md # Implementation plan template
└── specs/
└── RKEY-<ASPECT>-XXX-feature/ # Individual requirements
├── spec.md
└── plan.md
GAP_ANALYSIS.md # Requirement tracking
CLAUDE.md # AI agent integration guide
README_CANARY.md # Token specification
status.json # Scanner output