Skip to content

codebase-checkpoints

Codebase Checkpoints (automation contract)

Section titled “Codebase Checkpoints (automation contract)”

Opt-in per-project state machine that ties recurring housekeeping checkpoints — project-naming drift, design-doc identity, and (worked example) Cocos playable feel/build-size/parameter passes — to a single inspectable state file, re-evaluated whenever the codebase changes.

Setup (per project, not done by this module)

Section titled “Setup (per project, not done by this module)”
  1. Declare project identity in project-info.json at the REPO ROOT (project.canonicalName, project.client) — see § Identity SSOT below. Do NOT put it in the checkpoints config.
  2. Copy .claude/data/checkpoints.config.example.json to .claude/checkpoints/checkpoints.config.json in the consumer project and fill in project.expected / observed / staleTokens — commit it.
  3. Add .claude/checkpoints/checkpoints-state.json to the project’s own .gitignore (config is committed, runtime status is per-machine and not shipped by any kit mechanism).
  4. Trim or replace the game-feel / build-size / parameter-audit checkpoints in the copied config — they are a worked example for a Cocos playable-ad project (theonekit-cocos playable module); a non-Cocos or non-playable project deletes them, or swaps in its own engine’s polish/perf skills.

Identity SSOT — project-info.json, not the checkpoints config

Section titled “Identity SSOT — project-info.json, not the checkpoints config”

project.canonicalName and project.client are shipping facts: they outlive this tooling, and a project that uninstalls this module must not lose its own name with it. They therefore live in project-info.json at the repo root — NOT inside .claude/, which is kit-managed territory that t1k modules update may overwrite and which no module.json claims for an instance config.

What stays in .claude/checkpoints/checkpoints.config.json is the audit machinery itself: the expected vs observed drift fields, staleTokens, protectedTerms, and the checkpoint list.

checkpoints-core.cjs exposes resolveIdentity(), which reads project-info.json first and falls back to canonicalName/client keys in the checkpoints config so a pre-inversion install keeps working. That fallback is reported, never silent — loadConfig() records project._identitySource, and t1k-checkpoints.cjs status prints an identity LEGACY source=<file> (migrate to project-info.json) line until the declaration moves. Resolution happens once, inside loadConfig(), so no call site needs to know where the name lives.

checkpoints-turn-tracker (PostToolUse, Edit|Write|MultiEdit) queues the mutated path. checkpoints-stop (Stop) drains the queue once per turn, unions it with a git working-tree mtime snapshot (so edits made outside Claude’s own tools — an external editor, an engine editor rewriting a scene/prefab — are not invisible to “whenever the codebase changes”), re-evaluates every checkpoint in checkpoints.config.json, and reports.

Advisory by design: it prints a frame and exits 0. It never blocks the turn and never writes to Plane — board writes stay on the guarded t1k-plane path (t1k-plane-binding.cjs); this feature only reports which items SHOULD exist (t1k-checkpoints.cjs plane-plan) so an agent can create them through the normal guarded flow. Silent on turns that mutated nothing, so a long-lived red checkpoint (e.g. naming stays red until the rename actually lands) does not reprint forever.

Two checkpoint modes:

  • deterministic — a pure text/structure audit or identity probe, run directly by the hook. No LLM judgement (rules/ai-driven-design.md). project-naming (this module’s audit-naming.cjs) is engine-agnostic in its text scan and Cocos-shaped in its structural checks (skipped cleanly when a config omits the Cocos-dir fields — see below); design-doc is fully optional, delegating to t1k-cocos-base-system-design’s probe-design-doc.cjs when that skill is installed and mapping to unknown (never a false green) when it is not.
  • skill — cannot be run by a hook; staleness is the signal, a reasoning agent invokes the named skill and marks the checkpoint green via node .claude/scripts/t1k-checkpoints.cjs mark <id> green.

Engine coupling — why this lives in t1k-engine-bridge, not a generic core module

Section titled “Engine coupling — why this lives in t1k-engine-bridge, not a generic core module”

The naming audit’s three structural checks (cocos-dir, package-name, script-namespace) assume a nested engine-project directory holding assets/scripts/<namespace> — a Cocos Creator project shape. checkpoints-core.cjs also soft-depends on two Cocos-base skill scripts (t1k-cocos-base-knowledge-sweep/scripts/detect-cocos-project.cjs for directory auto-discovery, t1k-cocos-base-system-design/scripts/probe-design-doc.cjs for the design-doc checkpoint) — both resolved via fs.existsSync first and degrading to null/unknown when the Cocos kit is not installed, exactly like this module’s other Cocos-conditional hooks (cocos-doc-drift-stop.cjs, cocos-prior-art-reminder.cjs). A config that omits project.observed.cocosDir skips the three structural checks entirely and runs only the generic staleTokens text scan — see .claude/data/checkpoints.config.example.json’s _cocosDirComment.

The one hard (not soft) dependency is Plane: checkpoints-core.cjs’s probePlane() shells out to t1k-plane-binding.cjs status, which ships in core’s always-installed t1k-plane module.

T1K_SKIP_CHECKPOINTS=1 disables both hooks for the current invocation.

  • doc-sync-cocos.md (project rule, theonekit-cocos) — the sibling automation contract for this same module’s cocos-doc-drift-stop / cocos-doc-turn-tracker pair; same queue-then-drain shape.
  • rules/ai-driven-design.md — the deterministic-vs-skill split this feature follows.
  • rules/green-that-proves-nothing.md — why the naming audit’s structural checks compare observed !== expected rather than testing existsSync alone (a completed rename must be able to reach green, not report itself as still outstanding under its own new, correct name).
  • t1k-plane-binding.cjs (module t1k-plane) — the guarded Plane binding/gate CLI this feature reads through, never writes to directly.