Canon V1 is an AI-native programming language with a working foundation. This plan addresses the gaps between the current implementation and the full V1 specification.
Working:
- CLI commands: validate, policy, gen, test, build
- Core IR types and JSON loading
- Schema validation, reference checking, basic type checking
- TypeScript codegen for most node types
- Golden test runner with effect mocking
- OPA/Rego policy engine integration
Gaps to Address:
- Missing codegen for
matchnodes - Incomplete type validation (struct fields, list ops, custom calls)
- Missing capability scope enforcement
- Missing DAG cycle detection
- Incomplete policy deny message extraction
- No unit tests for Go packages
- Runtime effects are stubs (deny-all only)
File: pkg/codegen/typescript.go
- Add case in
generateNode()switch for "match" - Generate JS switch statement or chained ternaries
- Handle enum/variant pattern matching
File: pkg/validate/typecheck.go
- For
struct.make: verify field count/names match struct type definition - For
struct.get: verify field exists in struct type - Look up struct definitions from
prog.Types
File: pkg/validate/typecheck.go
list.map: input is List[T], mapper returns List[U]list.filter: input is List[T], predicate returns Boollist.fold: input is List[T], initial is A, reducer is (A,T)->A
File: pkg/validate/typecheck.go
- For non-intrinsic calls, look up function definition
- Verify argument count matches params
- Verify argument types match param types
File: pkg/validate/references.go
- Build adjacency list from node inputs
- Run DFS to detect back edges
- Report error with cycle path if found
File: pkg/validate/effects.go
- Parse
scopefield from CapabilityDef - For
effect.invokewithcap_id:- Extract attrs (e.g., host for HTTP, path for FS)
- Check attrs fall within capability scope constraints
- Example: HTTP capability with
scope.hosts: ["api.example.com"]should reject calls to other hosts
File: pkg/ir/types.go
- Define CapabilityScope struct with typed fields:
Hosts []stringfor Net capabilitiesPaths []stringfor FS capabilitiesTables []stringfor DB capabilitiesActions []stringfor allowed operations
File: pkg/policy/opa.go
- Store policy module content after compilation
- Extract deny messages from evaluation result properly
- Return specific violation reasons, not generic "denied"
Files: policies/default.rego, policies/safety.rego
- Add secret access requires capability rule
- Add AI confidence threshold for production (0.8)
- Add shell execution forbidden rule
- Verify existing rules work correctly
New files:
pkg/ir/types_test.go- IR struct testspkg/ir/load_test.go- JSON loading testspkg/validate/schema_test.go- Schema validation testspkg/validate/typecheck_test.go- Type checking testspkg/validate/references_test.go- Reference integrity testspkg/codegen/typescript_test.go- Codegen testspkg/policy/opa_test.go- Policy engine tests
New file: cmd/canon/integration_test.go
- Test full pipeline on example files
- Test policy violations are caught
- Test type errors are caught
File: runtime-ts/effects.ts
- Add
makeHttpHost()that performs real HTTP requests - Respect timeout attrs
- Return response body/status
File: runtime-ts/effects.ts
- Add
makeLoggingHost()that actually logs - Support log levels from attrs
File: runtime-ts/effects.ts
- Allow combining handlers (e.g., HTTP + logging)
- Add
composeHosts(...hosts)function
New file: examples/policy-demo/violation.canon.json
- Program that violates default policies
- Document expected error output
New file: examples/data-pipeline/pipeline.canon.json
- Uses list.map, list.filter, list.fold
- Demonstrates struct operations
- Shows conditional logic with
if
New file: examples/enum-demo/enum.canon.json
- Defines enum type with variants
- Uses
matchto handle cases - Shows type-safe exhaustive matching
| File | Changes |
|---|---|
| pkg/codegen/typescript.go | Add match node codegen |
| pkg/validate/typecheck.go | Struct/list/call validation |
| pkg/validate/references.go | DAG cycle detection |
| pkg/validate/effects.go | Capability scope checking |
| pkg/ir/types.go | CapabilityScope struct |
| pkg/policy/opa.go | Fix deny message extraction |
| runtime-ts/effects.ts | Real effect handlers |
| policies/default.rego | Additional safety rules |
| policies/safety.rego | Additional safety rules |
| File | Purpose |
|---|---|
pkg/ir/types_test.go |
Unit tests |
pkg/ir/load_test.go |
Unit tests |
pkg/validate/schema_test.go |
Unit tests |
pkg/validate/typecheck_test.go |
Unit tests |
pkg/validate/references_test.go |
Unit tests |
pkg/codegen/typescript_test.go |
Unit tests |
pkg/policy/opa_test.go |
Unit tests |
cmd/canon/integration_test.go |
Integration tests |
examples/policy-demo/violation.canon.json |
Example |
examples/data-pipeline/pipeline.canon.json |
Example |
examples/enum-demo/enum.canon.json |
Example |
- Phase 1 - Complete validation (struct fields, list ops, custom calls, match codegen, DAG detection)
- Phase 2 - Capability scope enforcement (security-critical)
- Phase 4.1 - Go unit tests (verify correctness as we go)
- Phase 3 - Policy engine improvements
- Phase 5 - Runtime effect handlers
- Phase 6 - Additional examples
V1 is complete when:
- All node types generate correct TypeScript (including
match) - Type checking catches struct field mismatches
- Type checking catches list operation type errors
- Capability scopes are enforced (unauthorized hosts rejected)
- DAG cycles are detected and rejected
- Policy violations report specific reasons
- Unit tests pass for all packages
- All examples build and test successfully