Validate Project Template
Comprehensive validation checklist for project templates. Run each check against the template directory and report pass/fail.
Step 1: Determine Template Level
Read stack.json from the template root and classify:
cat stack.json | python3 -c "import sys,json; d=json.load(sys.stdin); print(f'Level: {d[\"level\"]}, Stack: {d.get(\"stack\",\"none\")}, Parent: {d.get(\"parent\",\"none\")}')"
| Level | Indicator |
|---|---|
| 0 | level: 0, parent: null, stack: null |
| 1 | level: 1, parent: "project-template", stack filled |
| 1.5 | level: 1.5, parent is a Level 1 template |
| 2 | level: 2, parent is a Level 1 template |
If stack.json is missing or invalid, flag as critical error and stop.
Step 2: Validate stack.json
- Valid JSON (parseable)
-
stackfield present (nullat L0, non-empty string at L1+) -
versionpresent and in semver format (X.Y.Z) -
levelis 0, 1, 1.5, or 2 -
parentisnullat L0, non-empty string at L1+ -
layersobject withdata,logic,interfacekeys (all arrays) -
layersarrays empty at L0, at least one non-empty at L1+ -
pluginsobject withtechnology,process,stackkeys (all arrays) -
plugins.technologynon-empty at L1+ (at least one tech plugin)
Step 3: Check Required Files — All Levels
Root Files
-
stack.jsonexists -
CLAUDE.mdexists -
README.mdexists -
.env.exampleexists -
.mcp.json.exampleexists -
.gitignoreexists -
.gitignoreexcludes.env,.env.local,.mcp.json,node_modules
.claude/ Directory
-
.claude/settings.local.json.exampleexists
Core Skills (inherited from Level 0)
-
.claude/skills/brainstorming/SKILL.mdexists -
.claude/skills/planning/SKILL.mdexists -
.claude/skills/tdd/SKILL.mdexists -
.claude/skills/debugging/SKILL.mdexists -
.claude/skills/verification/SKILL.mdexists -
.claude/skills/project-config/SKILL.mdexists
Core Commands
-
.claude/commands/init-stack.mdexists -
.claude/commands/commit.mdexists -
.claude/commands/pr.mdexists -
.claude/commands/plan.mdexists -
.claude/commands/review.mdexists -
.claude/commands/sync.mdexists
Core Agent
-
.claude/agents/code-reviewer.mdexists
Core Rules
-
.claude/rules/safety.mdexists -
.claude/rules/search-before-building.mdexists -
.claude/rules/project-conventions.mdexists
Documentation
-
docs/architecture.mdexists -
docs/code-style.mdexists -
docs/api-conventions.mdexists
Step 4: Check Level-Specific Requirements
Level 1+ Additional Checks
- At least one stack-specific skill beyond the core set (e.g.,
new-page,new-component) -
.env.examplehas stack-specific variables uncommented -
CLAUDE.mdhas filled Tech Stack section (no[e.g.,placeholders) -
CLAUDE.mdhas filled Installed Plugins section
Level 1.5 Additional Checks
- Has application source code (
src/or equivalent) - Has sample data or seed scripts
- Has deployment config (Dockerfile, docker-compose.yml, or equivalent)
Level 2 Additional Checks
-
project-config/SKILL.mdhas actual resource IDs (no empty tables) -
.envor.env.localexists locally (warn if missing, but don't fail — it's gitignored) -
.mcp.jsonexists locally (warn if missing — it's gitignored)
Step 5: Check CLAUDE.md Quality
- Total line count under 100
- Has
## Tech Stacksection - Has
## Architecturesection (with@docs/architecture.mdreference) - Has
## Installed Pluginssection - Has
## Quick Commandssection - Has
## Critical Rulessection - No placeholder text remaining: grep for
\[e\.g\.,,\[Project Name\],TODO,TBD,fill in,<!-- .*-->with empty content around it - At L1+: Tech Stack lists actual technologies (not
[e.g., NocoDB, Supabase, Directus]) - At L1+: Installed Plugins lists actual plugins with descriptions
Step 6: Check Consistency
- Technologies in
stack.jsonlayersmatch CLAUDE.md Tech Stack section - Plugins in
stack.jsonpluginsmatch CLAUDE.md Installed Plugins section - Environment variables in
.env.examplecover what.mcp.json.examplereferences - Commands listed in CLAUDE.md Quick Commands exist as
.claude/commands/*.mdfiles - Skills referenced in CLAUDE.md exist as
.claude/skills/*/SKILL.mddirectories -
AGENTS.mdexists and is in sync withCLAUDE.md(or has sync reminder)
Step 7: Check Security
- No
.envfile committed (checkgit statusand.gitignore) - No
.mcp.jsonfile committed (check.gitignore) - No hardcoded API keys or tokens in any tracked file: grep for patterns like
sk-,Bearer,token: ",key: "with actual-looking values - No real service URLs in
.env.exampleor.mcp.json.example(only placeholders) -
.claude/settings.local.jsonis gitignored - No
.env.localcommitted
Git-Tracked Secrets (Critical)
The .gitignore check above only verifies RULES — it does not catch files that were committed BEFORE the gitignore rule was added. Run git ls-files to find actually tracked sensitive files:
# Check for tracked secrets that should be gitignored
git ls-files | grep -E '\.env\.local$|\.env$|settings\.local\.json$|\.mcp\.json$'
-
git ls-filesreturns NO matches for.env,.env.local,.mcp.json, orsettings.local.json - If matches found: flag as CRITICAL — these files contain real credentials and are being tracked by git. Fix:
git rm --cached <file>and rotate all exposed tokens - Check
.claude/settings.local.json.examplefor real URLs or tokens (should contain only placeholders likehttps://your-instance.example.com)
Output Format
Present validation results as:
## Template Validation Report: {template-name}
**Level:** {0 / 1 / 1.5 / 2}
**Stack:** {stack name or "universal base"}
**Parent:** {parent name or "none"}
### Results
| Category | Status | Details |
|----------|--------|---------|
| stack.json | PASS / FAIL | {details} |
| Required Files | PASS / FAIL | {missing files count} |
| Core Skills | PASS / FAIL | {missing skills} |
| Core Commands | PASS / FAIL | {missing commands} |
| Level-Specific | PASS / FAIL / N/A | {details} |
| CLAUDE.md Quality | PASS / WARN / FAIL | {details} |
| Consistency | PASS / FAIL | {mismatches} |
| Security | PASS / FAIL | {issues} |
### Issues Found
1. {issue description and how to fix}
2. ...
### Overall: VALID / {N} issues to fix