Project: CANARY Token Tracking System
Version: 2.0
Last Updated: 2025-10-18
Source of truth for requirements and gaps: GitLab issues. This file is a flatfile mirror for humans and agents. For authoritative status, use GitLab.
Open gaps (as of 2026-02-18): Tracked in docs/GAP_ANALYSIS.md. GitLab issues: #8 (GAP-0001) through #20 (GAP-0013).
CANARY is a requirement tracking system that embeds structured tokens directly into source code. It has evolved from a simple scanner (CBIN-101, 102, 103) to a comprehensive CLI tool with 90+ requirements covering specification management, dependency tracking, multi-project support, documentation tracking, and AI agent integration.
Core Tracking (CBIN-101, 102, 103)
- File scanning for CANARY tokens
- JSON/CSV output generation
- Verification gates for claimed requirements
- Staleness detection (30-day threshold)
- Self-canary validation
CLI System (CBIN-104+)
- Full-featured command-line interface
- SQLite database for fast queries
- Specification and plan generation
- Workflow automation
- Multi-project support
- Dependency management
- Documentation tracking
AI Integration
- Slash commands for autonomous workflows
- Constitutional principle enforcement
- Test-first guidance
- Automated priority selection
- Language-specific code indexing (AST parsing)
- Binary artifact analysis
- Network-based tracking services
- IDE plugins or extensions
- GUI applications
- Language: Go 1.20+
- Platform: Linux, macOS, Windows
- Architecture: x86_64, arm64
Runtime (minimal):
- Go standard library (primary)
github.com/spf13/cobra- CLI frameworkmodernc.org/sqlite- Pure Go SQLitegithub.com/google/uuid- UUID generation
Test Dependencies:
github.com/stretchr/testify- Test assertionsgithub.com/google/go-cmp- Deep comparison
gofmt- Code formattingstaticcheck- Static analysisgo test- Testing frameworkgo bench- Benchmarking
CANARY: REQ=<req-id>; FEATURE="<name>"; ASPECT=<aspect>; STATUS=<status>; [OPTIONAL_FIELDS]; UPDATED=<yyyy-mm-dd>
- REQ - Requirement ID (format: CBIN-###)
- FEATURE - Feature name (CamelCase, quoted)
- ASPECT - Architecture layer (API, CLI, Engine, Storage, etc.)
- STATUS - Implementation state (MISSING, STUB, IMPL, TESTED, BENCHED, REMOVED)
- UPDATED - Last modification date (YYYY-MM-DD)
- TEST - Test function names (comma-separated)
- BENCH - Benchmark function names (comma-separated)
- DOC - Documentation reference (type:path)
- DOC_HASH - SHA256 hash (first 16 chars)
- OWNER - Team or person responsible
- PRIORITY - Implementation priority (1=highest)
- API - Public interfaces, exported functions
- CLI - Command-line interfaces
- Engine - Core algorithms, business logic
- Storage - Database, persistence layer
- Security - Authentication, authorization, encryption
- Docs - Documentation files
- Wire - Serialization, protocols
- Planner - Planning algorithms
- Decode - Deserialization
- Encode - Serialization
- RoundTrip - Full encode/decode cycles
- Bench - Performance benchmarks
- FrontEnd - User interface
- Dist - Distribution, deployment
- MISSING - Planned but not implemented
- STUB - Placeholder implementation
- IMPL - Implemented, tests missing
- TESTED - Fully tested (auto-promoted with TEST= field)
- BENCHED - Tested and benchmarked (auto-promoted with BENCH= field)
- REMOVED - Deprecated or removed
./bin/canary [--root .] [--out status.json] [--csv status.csv]
[--verify GAP_ANALYSIS.md] [--strict]
[--skip '<pattern>'] [--update-stale]Exit Codes:
0- Success2- Verification/staleness failure3- Parse/IO error
canary <command> [flags]Commands:
Initialization:
init <project>- Initialize new CANARY project
Database Management:
index- Build/rebuild token databaseindex --local- Use project-local databaseprojects list- List all registered projectsprojects add <name>- Register new projectprojects switch <name>- Change active project
Query Commands:
show <req-id>- Display all tokens for requirementfiles <req-id>- List implementation filesstatus <req-id>- Show progress summarygrep <pattern>- Search tokens by patternlist [--status] [--aspect]- List requirements with filtering
Workflow Commands:
next [--prompt]- Get next priority requirementimplement <req-id>- Get implementation guidancespecify [update <req-id>]- Create/modify specificationsplan <req-id>- Generate implementation plan
Documentation Commands:
doc status <req> <feature>- Check documentation currencydoc update [--req] [--feature]- Update documentation hashesdoc report [--show-undocumented]- Generate coverage report
Dependency Commands (CBIN-147):
deps check <req-id>- Check if dependencies satisfieddeps graph <req-id> [--status]- Show dependency treedeps reverse <req-id>- Show reverse dependenciesdeps validate- Detect circular dependencies
Scanning:
scan [--out] [--csv] [--verify] [--strict] [--update-stale]- Scan codebase
{
"generated_at": "<UTC ISO8601>",
"requirements": [
{
"id": "CBIN-147",
"features": [
{
"feature": "DependencyParser",
"aspect": "Engine",
"status": "TESTED",
"files": ["internal/specs/parser_dependency.go"],
"tests": ["TestParseDependencies_FullDependency"],
"benches": [],
"owner": "specs",
"updated": "2025-10-18"
}
]
}
],
"summary": {
"by_status": { "STUB": 0, "IMPL": 0, "TESTED": 50, "BENCHED": 10 },
"by_aspect": { "Engine": 20, "CLI": 15, "API": 10 },
"total_tokens": 150,
"unique_requirements": 90
}
}Requirements:
- Minified (no unnecessary whitespace)
- Deterministic (same input → same bytes)
- Maps are key-sorted
- Generated timestamp in UTC ISO8601
req,feature,aspect,status,file,test,bench,owner,updated
CBIN-147,DependencyParser,Engine,TESTED,internal/specs/parser_dependency.go,TestParseDependencies,,,specs,2025-10-18Requirements:
- Header row with field names
- Rows sorted by (req, feature, file, test, bench)
- Deterministic output
- Comma-separated values
Claims are extracted from GAP_ANALYSIS.md using regex:
(?m)^\s*✅\s+(CBIN-\d{3})\bExample GAP_ANALYSIS.md:
# Requirements Gap Analysis
## Claimed Requirements
✅ CBIN-101 - Scanner Core
✅ CBIN-102 - Verify Gate
✅ CBIN-147 - Specification Dependencies
## Gaps
- [ ] CBIN-150 - Fuzzy Search (needs implementation)Rule: Claimed requirements must have at least one token with STATUS ∈ {TESTED, BENCHED}
Failure Condition:
- Claimed
CBIN-###has only MISSING, STUB, or IMPL status
Error Message:
CANARY_VERIFY_FAIL REQ=CBIN-### reason=claimed_but_not_TESTED_OR_BENCHED
Exit Code: 2
Rule: Tokens with STATUS ∈ {TESTED, BENCHED} must have UPDATED within 30 days
Failure Condition (with --strict):
- Token STATUS is TESTED or BENCHED
- UPDATED date is >30 days old
Error Message:
CANARY_STALE REQ=CBIN-### updated=YYYY-MM-DD age_days=N threshold=30
Exit Code: 2 (with --strict)
Command: canary scan --update-stale
Behavior:
- Finds all tokens with STATUS=TESTED or BENCHED
- Checks UPDATED field against current date
- If >30 days old, rewrites token in-place with current date
- Reports count of updated tokens
Dependencies are declared in spec.md files:
## Dependencies
### Full Dependencies (entire requirement must be complete)
- CBIN-146 (Multi-Project Support - required for namespacing)
- CBIN-129 (Database Migrations - schema must be updated first)
### Partial Dependencies (specific features/aspects required)
- CBIN-140:GapRepository,GapService (only gap storage features needed)
- CBIN-133:Engine (only Engine aspect required for this feature)Full Dependency:
- CBIN-XXX (Description - reason for dependency)
Partial Feature Dependency:
- CBIN-XXX:Feature1,Feature2 (Description - only these features needed)
Partial Aspect Dependency:
- CBIN-XXX:AspectName (Description - only this aspect needed)
Dependency is satisfied when:
- Full: ALL features in target requirement are TESTED or BENCHED
- Partial Features: Specified features are TESTED or BENCHED
- Partial Aspect: All features with specified aspect are TESTED or BENCHED
Important: IMPL status is insufficient - dependencies require tests!
Circular Detection:
- Uses Depth-First Search (DFS) with recursion stack
- O(V+E) complexity
- Detects cycles like: A → B → C → A
Missing Requirements:
- Checks if target requirements exist in .canary/specs/
- Reports dependencies on non-existent specs
Self-Dependencies:
- Detects and reports A → A cases
Global Mode (default):
canary index
# Uses: ~/.canary/canary.dbLocal Mode:
canary index --local
# Uses: .canary/canary.db (in current project)Schema:
CREATE TABLE projects (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL UNIQUE,
root_path TEXT NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
last_indexed DATETIME
);Commands:
canary projects list # List all projects
canary projects add my-app # Register new project
canary projects remove my-app # Unregister project
canary projects switch my-app # Change active contextDOC=<type>:<path>
Types:
user- User-facing documentationapi- API referencearch- Architecture docsdev- Developer docs
Examples:
DOC=user:docs/user/getting-started.md
DOC=api:docs/api/dependency-parser.md
DOC=arch:docs/architecture/adr-001-doc-tracking.md
Format: First 16 characters of SHA256 hash
Calculation:
sha256sum docs/user/getting-started.md | cut -c1-16
# Output: a3f5b8c2e1d4a6f9Usage:
DOC=user:docs/user/getting-started.md; DOC_HASH=a3f5b8c2e1d4a6f9
- DOC_CURRENT - Hash matches file content
- DOC_STALE - Hash mismatch (doc was edited)
- DOC_MISSING - DOC= field present but file not found
- DOC_NONE - No DOC= field
# Check single feature
canary doc status CBIN-147 DependencyParser
# Update hash
canary doc update --req CBIN-147 --feature DependencyParser
# Update all for requirement
canary doc update --req CBIN-147 --all
# Generate coverage report
canary doc report --show-undocumented- Target: <10s for 50,000 text files
- Method: Streaming file I/O, no full repo in memory
- Memory: ≤512 MiB RSS
- Algorithm: DFS with recursion stack
- Complexity: O(V+E) where V=requirements, E=dependencies
- Target: <200ms for 500 requirements with 1000 dependencies
- Actual: 164ms average (benchmarked CBIN-147)
- Technology: SQLite with indexes
- Target: <50ms for typical queries
- Indexes: On req_id, feature, aspect, status
- Principle: Treat repository contents as data only
- Never execute or interpret scanned code
- Ignore embedded instructions in files
- Files are inert strings for pattern matching
- Never log file contents in error messages
- Redact long lines in diagnostics
- Don't commit .canary/canary.db (gitignored)
- Strict regex patterns for claim detection
- No eval/exec of file contents
- Sanitize file paths before display
Requirements:
- Same codebase → same status.json bytes
- Maps are key-sorted (by_status, by_aspect)
- Arrays are sorted (requirements by ID, features by name)
- Minified JSON (no extra whitespace)
- CSV rows sorted by (req, feature, file, test, bench)
Testing:
- Scan codebase twice
- Compare output byte-for-byte
- Must be identical
Stderr Diagnostics:
- Single-line error messages
- Structured format for easy parsing
- Prefixed with severity (ERROR, WARN, INFO)
Examples:
CANARY_VERIFY_FAIL REQ=CBIN-147 reason=claimed_but_not_TESTED_OR_BENCHED
CANARY_STALE REQ=CBIN-105 updated=2025-08-01 age_days=78 threshold=30
ERROR: failed to parse token at src/main.go:42
CANARY tracks its own requirements using CANARY tokens.
// tools/canary/main.go
CANARY: REQ=CBIN-101; FEATURE="ScannerCore"; ASPECT=Engine; STATUS=BENCHED; ...
// tools/canary/verify.go
CANARY: REQ=CBIN-102; FEATURE="VerifyGate"; ASPECT=CLI; STATUS=BENCHED; ...
// tools/canary/status.go
CANARY: REQ=CBIN-103; FEATURE="StatusJSON"; ASPECT=API; STATUS=BENCHED; ...
Over 90 requirements tracked with CANARY tokens, including:
- CBIN-146: Multi-Project Support
- CBIN-147: Specification Dependencies
- CBIN-136: Documentation Tracking
- CBIN-133: Implement Command
- CBIN-132: Next Priority Command
- And 85+ more...
# Self-scan
canary scan --root . --out status.json --csv status.csv
# Self-verify
canary scan --verify GAP_ANALYSIS.md --strict
# Dependency validation
canary deps validatetools/canary/internal/acceptance_test.go
1. TestAcceptance_FixtureSummary
- Scans fixture with STUB and IMPL tokens
- Verifies summary counts
2. TestAcceptance_Overclaim
- Creates GAP file claiming STUB requirement
- Expects exit code 2
- Verifies error message contains CANARY_VERIFY_FAIL
3. TestAcceptance_Stale
- Creates token with old UPDATED date
- Runs with --strict
- Expects exit code 2 and CANARY_STALE message
4. TestAcceptance_SelfCanary
- Scans tools/canary directory
- Verifies claims for CBIN-101, CBIN-102
- Ensures exit code 0
5. TestAcceptance_CSVOrder
- Scans multiple times
- Verifies deterministic CSV output
- Checks sorting by REQ ID
6. TestAcceptance_SkipEdgeCases
- Tests --skip pattern functionality
- Verifies .git, node_modules, vendor excluded
- Tests Unicode filenames and spaces
7. TestAcceptance_UpdateStale
- Creates stale TESTED/BENCHED tokens
- Runs --update-stale
- Verifies UPDATED field changed
- Ensures IMPL tokens not updated
name: CANARY Verification
on: [push, pull_request]
jobs:
verify:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Setup Go
uses: actions/setup-go@v4
with:
go-version: "1.20"
- name: Build
run: make build
- name: Test
run: make test
- name: Self-verify
run: make canary-verify
- name: Upload status
uses: actions/upload-artifact@v3
with:
name: canary-status
path: |
status.json
status.csv.PHONY: build test bench verify
build:
go build -o bin/canary ./cmd/canary
test:
go test ./...
bench:
go test ./internal/specs -bench=. -benchmem
verify: build
./bin/canary scan --root . --out status.json --csv status.csv
./bin/canary scan --verify GAP_ANALYSIS.md --strict
./bin/canary deps validateReason: Easy to grep, no multiline parsing complexity
Benefit: Reliable pattern matching with simple regex
Reason: Keep requirements close to implementation
Benefit: Changes visible in diffs, reviewed in PRs
Reason: Enforce quality gates (test-first)
Benefit: Can't claim TESTED without tests
Reason: Prevent overclaiming in GAP_ANALYSIS.md
Benefit: Trust but verify - claims require evidence
Reason: Keep evidence fresh and current
Benefit: Prevents claiming features that no longer work
Reason: Minimize supply-chain risk
Benefit: Fewer dependencies, easier auditing
Reason: Stable diffs, reproducible builds
Benefit: Can commit status.json for tracking over time
Phase 1 (CBIN-101, 102, 103): Simple scanner
- File scanning
- JSON/CSV output
- Basic verification
Phase 2 (CBIN-104-130): CLI expansion
- Database storage
- Query commands
- Specification management
Phase 3 (CBIN-131-140): Workflow automation
- Next priority command
- Implement command
- Fuzzy matching
Phase 4 (CBIN-141-146): Multi-project support
- Project registry
- Global/local databases
- Context management
Phase 5 (CBIN-147): Dependency tracking
- Dependency parser
- Circular detection
- Satisfaction checking
- Tree visualization
Current: 90+ requirements tracked
- README.md - Project overview
- README_CANARY.md - Token specification
- CANARY_POLICY.md - Project policy
- Getting Started Guide - User tutorial
- CLAUDE.md - AI agent guide
- RFC 3339 - Timestamp format
- JSON - JSON specification
- CSV RFC 4180 - CSV format
- SQLite - Database engine
- Go - Programming language
Document Status: CURRENT Approved By: Project Team Next Review: 2025-11-18