These pages document master, which is unreleased and in development. The Quick Start installs the latest stable release; anything newer than that tag is marked in the text.
Pi Extension Development
Where to add things in the Pi adapter, and the gates each addition must pass. This is a map, not a re-explanation of the internals β read the referenced files for the details.
User-side project templates: this doc covers developing the CCT runtime itself. For the end-user guardrails starter (
.pi/extensions/in YOUR project β pre-write + post-execution validation gates), seepi-code init --extension-templateand the scaffolded README (source:adapters/pi/resources/extension-template/).
adapters/pi/βββ bin/pi-code launcher (bash): resolve pi, guards, arg passthroughβββ runtime/ the enforcement runtime (node --experimental-strip-types, ESM)β βββ index.ts extension entry: session_start / tool_call gates, command registrationβ βββ cli.ts pi-code diagnostic commands (doctor/config/features/β¦)β βββ capabilities.ts the runtime capability seed (drift-guarded vs pi.yaml)β βββ config/ loader, profiles, floor, lint, trust, toml, migrateβ βββ policy/ permissions, protected(-ops), sandbox, mcp, auditβ βββ workflow/ sdd, phases, classify, review, verify, checkpoint, memoryβ βββ agents/ manifest, import-claude-agents, child-session, caps, worktree, team(-status), worker-analyticsβββ resources/ GENERATED skills + prompts (do not hand-edit)βββ setup.sh enforced-mode installerAdd a runtime command (/cct:* or a diagnostic)
Section titled βAdd a runtime command (/cct:* or a diagnostic)β- Enforcement / stateful
/cct:*command: register it inruntime/index.ts(the extension activation registers commands and wires thetool_callgate). - Diagnostic (
pi-code <cmd>): add acaseinruntime/cli.tsand mirror the--jsonpattern. Keep it read-only + redacted (secrets never printed). - Add a test under
tests/pi-runtime/and, if it affects the adapter surface,tests/test-pi-adapter.sh.
Add / change a capability (FR-029)
Section titled βAdd / change a capability (FR-029)βA capability touches four files, kept in lockstep by drift guards:
shared/capabilities/catalog.yamlβ the neutral id (description, default, security level, optionalclaude_equivalent).shared/capabilities/pi.yamlβ Piβs classification (implementation_kind,runtime_status,reason,status_probe). A non-enabledstatus requires a reason.shared/capabilities/claude-code.yamlβ Claudeβs classification.runtime/capabilities.tsβ the Pi runtime seed (id + kind + status), whichtest-pi-adapter.shdrift-guards againstpi.yaml.
Then:
bash scripts/validate-capabilities.sh # every id classified by every adapter; enums; reasonsbash scripts/generate-capability-docs.sh # regenerate COMPATIBILITY.md (committed baseline)The generated shared/capabilities/COMPATIBILITY.md is a pure render of the
registry β never hand-edit it; generate-capability-docs.sh --check fails the
build on drift. If wording is weak, improve the registry reason and
regenerate.
Honesty rule: a status flips to enabled only when its acceptance gate
passes. PATH presence never implies enabled; if unsure, itβs degraded /
unsupported.
Add generated resources (skills / prompts)
Section titled βAdd generated resources (skills / prompts)βDo not edit adapters/pi/resources/ directly β it is generated. Add the source
under shared/ and run:
bash scripts/generate.sh # regenerates all adapters from shared/sync-check.yml fails on drift between shared/ and the generated resources.
Tests & gates (what must be green)
Section titled βTests & gates (what must be green)β| Suite | Runs |
|---|---|
tests/test-pi-runtime.sh |
the node runtime tests (--test-concurrency=1) β incl. the security battery |
tests/test-pi-adapter.sh |
generation goldens, capability validation + drift guards |
scripts/validate-capabilities.sh |
registry integrity |
(cd adapters/pi/runtime && npx tsc --noEmit) |
type-check (the type gate β --experimental-strip-types strips without checking) |
Conventions worth knowing:
- Editing an existing
.ts/.jsontriggers a prettier hook that reformats the whole file; checkgit diffand keep changes surgical. - New capability behavior needs a test + a drift/negative test (prove the
guard fires), and a
.cct/*.jsonthe runtime reads must reconcile its invariants on load (tamper-safe), not just sanitize fields. - Follow the
null = unavailablediscipline: never fabricate a value the source doesnβt provide.
Releases & provenance (FR-027)
Section titled βReleases & provenance (FR-027)βReleases are cut from git tags β the publish boundary is the tag + a GitHub
Release, with no external registry (the install path stays
pi install git:β¦@<tag> / scripts/setup.sh --pi).
To cut a release:
- Bump
package.jsonversion(the Pi package version β kept in sync with the tag) and regenerate the SBOM:bash scripts/generate-sbom.sh. - Add a
## [X.Y.Z]section toCHANGELOG.md. - Dry-run locally:
bash scripts/prepare-release.sh(offline β verifies the SBOM is current, checks tagβpackage.json agreement, writesdist/SHA256SUMS+dist/RELEASE_NOTES.md; publishes nothing). - Push tag
vX.Y.Zβ.github/workflows/release.ymlruns the gates, calls the sameprepare-release.sh, and creates the GitHub Release with the SBOM + checksums + notes.
Provenance (FR-027) is exposed by these artifacts + existing reports:
| Field | Where |
|---|---|
| source | the git tag / commit (GitHub Release) |
| version | the tag + package.json (kept in sync) |
| checksum | dist/SHA256SUMS (release artifact) |
| dependency status | adapters/pi/sbom.cdx.json (runtime deps: none) |
| enabled modules + security classification | pi-code features / ../../../shared/capabilities/COMPATIBILITY.md |
| scope + trust state | pi-code doctor |
A dedicated pi-code provenance command that aggregates these is a named
follow-up (the runtime has no version/checksum data source today).