feat(context): Context Engineering Configurator + consolidated guide (v3.34.0)
New: interactive configurator at cc.bruniaux.com/context/ that generates a personalized CLAUDE.md starter kit based on team size, stack, and current setup. Multi-step flow (profile, current state, stack, results) with maturity scoring (Level 1-5), copy-to-clipboard artifacts, localStorage persistence. Guide content: - guide/core/context-engineering.md (1,188 lines, 8 sections): context budget, 150-instruction ceiling, modular architecture, team assembly, ACE pipeline, quality measurement, context reduction techniques - examples/context-engineering/ (10 templates): assembler.ts, profile-template.yaml, skeleton-template.md, canary-check.sh, ci-drift-check.yml, eval-questions.yaml, context-budget-calculator.sh, rules/knowledge-feeding.md, rules/update-loop-retro.md - tools/context-audit-prompt.md (543 lines): 8-dimension scoring /100 Navigation: guide/README.md, machine-readable/reference.yaml (24 new entries) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
318ba915de
commit
fe28f89574
19 changed files with 3545 additions and 15 deletions
20
CHANGELOG.md
20
CHANGELOG.md
|
|
@ -6,6 +6,26 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [3.34.0] - 2026-03-11
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- **Context Engineering Configurator** (`cc.bruniaux.com/context/`) — Interactive multi-step configurator that generates a personalized CLAUDE.md starter kit. 5-screen flow: profile (team size, AI tools), current state (existing CLAUDE.md, rules files), stack (language, frontend), results (generated artifacts + maturity assessment). Features: generated CLAUDE.md preview with copy-to-clipboard, Profile YAML for team setups, maturity badge (Level 1-5), personalized next-steps roadmap, localStorage persistence. Vanilla JS, no framework. Nav: added "Context" to landing header dropdown.
|
||||||
|
|
||||||
|
- **`guide/core/context-engineering.md`** — New consolidated reference (1,188 lines) covering all context engineering concepts. 8 sections: (1) What is Context Engineering (Karpathy's definition, prompt vs. context engineering distinction, three-layer model); (2) The Context Budget (token math, 150-instruction ceiling, HumanLayer 15-25% adherence data, path-scoping efficiency, overload signs); (3) Configuration Hierarchy (global/project/session split, decision tree for rule placement, override semantics); (4) Modular Architecture (path-scoping, skills vs. rules distinction, progressive disclosure, anti-pattern: monolithic CLAUDE.md); (5) Team Assembly (N×M×P problem, profile YAML, assembly workflow, CI drift detection, module library structure); (6) Context Lifecycle (instruction debt, update loop, knowledge feeding, ACE pipeline, session retrospective); (7) Quality Measurement (self-evaluation questions, canary checks, adherence tracking, context debt score formula); (8) Context Reduction Techniques (path-scoping -40-50%, negative constraints +15-25%, rule compression, deduplication, archive pattern).
|
||||||
|
|
||||||
|
- **`examples/context-engineering/`** — 10 production-ready templates: `README.md` (overview + quick start), `profile-template.yaml` (developer profile for context assembly), `skeleton-template.md` (CLAUDE.md skeleton with filled placeholders), `assembler.ts` (~240-line TypeScript script for profile-based assembly with @import resolution, dry-run support, token estimation), `eval-questions.yaml` (20 self-evaluation questions across 4 dimensions), `canary-check.sh` (5-check behavioral regression script), `ci-drift-check.yml` (weekly GitHub Actions drift detection with auto-issue creation), `context-budget-calculator.sh` (measures always-on token cost), `rules/knowledge-feeding.md` (proactive context update protocol), `rules/update-loop-retro.md` (session retrospective template).
|
||||||
|
|
||||||
|
- **`tools/context-audit-prompt.md`** — Self-contained context audit prompt (543 lines) following `audit-prompt.md` pattern. Scores context engineering setup /100 across 8 dimensions: Size & Budget (15 pts), Structure (15 pts), Path-Scoping (12 pts), Rule Quality (15 pts), Freshness (12 pts), Team Readiness (10 pts), Conflict Detection (11 pts), Knowledge Loop (10 pts). Includes 3 bash scan phases, report format with context budget breakdown, 5-level maturity ladder, and ready-to-use paste improvements.
|
||||||
|
|
||||||
|
- **`src/data/context-data.ts`** (landing) — TypeScript data file with all configurator types, option arrays (team size, AI tools, stack, frontend), maturity level definitions (5 levels: Starter/Modular/Team-Ready/Measured/Adaptive), and template generators (`generateClaudeMd`, `generateProfileYaml`, `calculateMaturityLevel`).
|
||||||
|
|
||||||
|
### Updated
|
||||||
|
|
||||||
|
- **`guide/README.md`** — Added `core/context-engineering.md` row to Core Reference table.
|
||||||
|
- **`machine-readable/reference.yaml`** — Added 24 context engineering entries with paths to guide, examples, tools, and landing configurator.
|
||||||
|
- **`src/components/global/Header.astro`** (landing) — Added "Context" to moreLinks dropdown.
|
||||||
|
|
||||||
## [3.33.1] - 2026-03-10
|
## [3.33.1] - 2026-03-10
|
||||||
|
|
||||||
### Updated
|
### Updated
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
<p align="center">
|
<p align="center">
|
||||||
<a href="https://github.com/FlorianBruniaux/claude-code-ultimate-guide/stargazers"><img src="https://img.shields.io/github/stars/FlorianBruniaux/claude-code-ultimate-guide?style=for-the-badge" alt="Stars"/></a>
|
<a href="https://github.com/FlorianBruniaux/claude-code-ultimate-guide/stargazers"><img src="https://img.shields.io/github/stars/FlorianBruniaux/claude-code-ultimate-guide?style=for-the-badge" alt="Stars"/></a>
|
||||||
<a href="./CHANGELOG.md"><img src="https://img.shields.io/badge/Updated-Mar_10,_2026_·_v3.33.1-brightgreen?style=for-the-badge" alt="Last Update"/></a>
|
<a href="./CHANGELOG.md"><img src="https://img.shields.io/badge/Updated-Mar_11,_2026_·_v3.34.0-brightgreen?style=for-the-badge" alt="Last Update"/></a>
|
||||||
<a href="./quiz/"><img src="https://img.shields.io/badge/Quiz-271_questions-orange?style=for-the-badge" alt="Quiz"/></a>
|
<a href="./quiz/"><img src="https://img.shields.io/badge/Quiz-271_questions-orange?style=for-the-badge" alt="Quiz"/></a>
|
||||||
<a href="./examples/"><img src="https://img.shields.io/badge/Templates-204-green?style=for-the-badge" alt="Templates"/></a>
|
<a href="./examples/"><img src="https://img.shields.io/badge/Templates-204-green?style=for-the-badge" alt="Templates"/></a>
|
||||||
<a href="./guide/security/security-hardening.md"><img src="https://img.shields.io/badge/🛡️_Threat_DB-15_vulnerabilities_·_655_malicious_skills-red?style=for-the-badge" alt="Threat Database"/></a>
|
<a href="./guide/security/security-hardening.md"><img src="https://img.shields.io/badge/🛡️_Threat_DB-15_vulnerabilities_·_655_malicious_skills-red?style=for-the-badge" alt="Threat Database"/></a>
|
||||||
|
|
@ -872,7 +872,7 @@ See [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
*Version 3.33.1 | Updated daily · Mar 10, 2026 | Crafted with Claude*
|
*Version 3.34.0 | Updated daily · Mar 11, 2026 | Crafted with Claude*
|
||||||
|
|
||||||
<!-- SEO Keywords -->
|
<!-- SEO Keywords -->
|
||||||
<!-- claude code, claude code tutorial, anthropic cli, ai coding assistant, claude code mcp,
|
<!-- claude code, claude code tutorial, anthropic cli, ai coding assistant, claude code mcp,
|
||||||
|
|
|
||||||
2
VERSION
2
VERSION
|
|
@ -1 +1 @@
|
||||||
3.33.1
|
3.34.0
|
||||||
|
|
|
||||||
78
examples/context-engineering/README.md
Normal file
78
examples/context-engineering/README.md
Normal file
|
|
@ -0,0 +1,78 @@
|
||||||
|
# Context Engineering Templates
|
||||||
|
|
||||||
|
Context engineering is the practice of deliberately designing what information Claude receives at session start — treating your `CLAUDE.md` and supporting files as a production system, not a one-time setup. These templates give you everything to build, measure, and maintain that system.
|
||||||
|
|
||||||
|
## Files
|
||||||
|
|
||||||
|
| File | Description |
|
||||||
|
|------|-------------|
|
||||||
|
| `profile-template.yaml` | Developer profile for per-person context assembly |
|
||||||
|
| `skeleton-template.md` | Annotated `CLAUDE.md` skeleton with section-by-section guidance |
|
||||||
|
| `assembler.ts` | TypeScript script to build `CLAUDE.md` from profile + modules |
|
||||||
|
| `eval-questions.yaml` | 20 self-evaluation questions to audit your `CLAUDE.md` |
|
||||||
|
| `canary-check.sh` | Behavioral regression test script (structural validation) |
|
||||||
|
| `ci-drift-check.yml` | GitHub Actions workflow for weekly context drift detection |
|
||||||
|
| `context-budget-calculator.sh` | Measures always-on token cost of your context configuration |
|
||||||
|
| `rules/knowledge-feeding.md` | Rule template for proactive context updates after sessions |
|
||||||
|
| `rules/update-loop-retro.md` | Session retrospective template to capture learnings |
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
**New project — get a working `CLAUDE.md` in 3 steps:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Copy the skeleton and fill in your project details
|
||||||
|
cp examples/context-engineering/skeleton-template.md CLAUDE.md
|
||||||
|
|
||||||
|
# 2. Check your context budget (keep it under 10K tokens)
|
||||||
|
bash examples/context-engineering/context-budget-calculator.sh .
|
||||||
|
|
||||||
|
# 3. Run canary checks to validate structure
|
||||||
|
bash examples/context-engineering/canary-check.sh .
|
||||||
|
```
|
||||||
|
|
||||||
|
**Existing project — audit and improve:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Run the structural check
|
||||||
|
bash examples/context-engineering/canary-check.sh .
|
||||||
|
|
||||||
|
# Then use eval-questions.yaml to score your CLAUDE.md manually
|
||||||
|
# Target: 16+ / 20
|
||||||
|
```
|
||||||
|
|
||||||
|
**Team setup — per-developer profiles:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install dependencies for the assembler
|
||||||
|
npm install js-yaml @types/js-yaml ts-node typescript
|
||||||
|
|
||||||
|
# Copy the profile template and customize
|
||||||
|
cp examples/context-engineering/profile-template.yaml .claude/profiles/yourname.yaml
|
||||||
|
# Edit .claude/profiles/yourname.yaml with your stack and preferences
|
||||||
|
|
||||||
|
# Assemble your CLAUDE.md
|
||||||
|
ts-node examples/context-engineering/assembler.ts \
|
||||||
|
--profile .claude/profiles/yourname.yaml \
|
||||||
|
--modules .claude/modules \
|
||||||
|
--output CLAUDE.md
|
||||||
|
```
|
||||||
|
|
||||||
|
**Ongoing maintenance:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Weekly: run canary checks
|
||||||
|
bash examples/context-engineering/canary-check.sh .
|
||||||
|
|
||||||
|
# After sessions: use the retro template
|
||||||
|
# See rules/update-loop-retro.md
|
||||||
|
|
||||||
|
# Add the CI workflow for automated drift detection
|
||||||
|
cp examples/context-engineering/ci-drift-check.yml .github/workflows/context-drift.yml
|
||||||
|
```
|
||||||
|
|
||||||
|
## Guide Section
|
||||||
|
|
||||||
|
Full methodology and principles: `guide/core/context-engineering.md`
|
||||||
|
|
||||||
|
The templates here are the operational layer — the guide explains the reasoning behind each design decision.
|
||||||
243
examples/context-engineering/assembler.ts
Normal file
243
examples/context-engineering/assembler.ts
Normal file
|
|
@ -0,0 +1,243 @@
|
||||||
|
#!/usr/bin/env ts-node
|
||||||
|
/**
|
||||||
|
* Context Assembler
|
||||||
|
*
|
||||||
|
* Assembles CLAUDE.md from a developer profile YAML + shared module markdown files.
|
||||||
|
* Supports @import resolution, module exclusions, and per-developer overrides.
|
||||||
|
*
|
||||||
|
* Usage:
|
||||||
|
* ts-node assembler.ts --profile .claude/profiles/alice.yaml --output CLAUDE.md
|
||||||
|
* ts-node assembler.ts --profile .claude/profiles/alice.yaml --modules .claude/modules --output CLAUDE.md --dry-run
|
||||||
|
*
|
||||||
|
* Dependencies:
|
||||||
|
* npm install js-yaml @types/js-yaml ts-node typescript
|
||||||
|
*/
|
||||||
|
|
||||||
|
import fs from 'fs'
|
||||||
|
import path from 'path'
|
||||||
|
import yaml from 'js-yaml'
|
||||||
|
|
||||||
|
// ── Types ────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
interface ProfileTools {
|
||||||
|
primary_lang: string
|
||||||
|
frontend?: string
|
||||||
|
backend?: string
|
||||||
|
database?: string
|
||||||
|
cloud?: string
|
||||||
|
test_framework?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
interface ProfileStyle {
|
||||||
|
verbosity: 'verbose' | 'concise' | 'minimal'
|
||||||
|
comment_style: 'none' | 'inline' | 'jsdoc'
|
||||||
|
test_coverage: 'none' | 'optional' | 'required'
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Profile {
|
||||||
|
profile: {
|
||||||
|
name: string
|
||||||
|
role: string
|
||||||
|
seniority: string
|
||||||
|
tools: ProfileTools
|
||||||
|
style: ProfileStyle
|
||||||
|
}
|
||||||
|
modules: {
|
||||||
|
include: string[]
|
||||||
|
exclude: string[]
|
||||||
|
}
|
||||||
|
overrides: {
|
||||||
|
custom_rules: string[]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interface AssemblyResult {
|
||||||
|
content: string
|
||||||
|
totalChars: number
|
||||||
|
estimatedTokens: number
|
||||||
|
modulesLoaded: number
|
||||||
|
modulesMissing: string[]
|
||||||
|
importsResolved: number
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Helpers ──────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
function loadProfile(profilePath: string): Profile {
|
||||||
|
if (!fs.existsSync(profilePath)) {
|
||||||
|
throw new Error(`Profile not found: ${profilePath}`)
|
||||||
|
}
|
||||||
|
const content = fs.readFileSync(profilePath, 'utf8')
|
||||||
|
return yaml.load(content) as Profile
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveImports(content: string, baseDir: string, depth = 0): string {
|
||||||
|
if (depth > 5) {
|
||||||
|
console.warn(' Warning: @import depth limit reached (5) — circular imports?')
|
||||||
|
return content
|
||||||
|
}
|
||||||
|
return content.replace(/^@(.+)$/gm, (_, importPath) => {
|
||||||
|
const fullPath = path.resolve(baseDir, importPath.trim())
|
||||||
|
if (!fs.existsSync(fullPath)) {
|
||||||
|
return `<!-- @import ${importPath} — FILE NOT FOUND -->`
|
||||||
|
}
|
||||||
|
const imported = fs.readFileSync(fullPath, 'utf8')
|
||||||
|
return resolveImports(imported, path.dirname(fullPath), depth + 1)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadModule(
|
||||||
|
modulePath: string,
|
||||||
|
modulesDir: string,
|
||||||
|
result: AssemblyResult
|
||||||
|
): string {
|
||||||
|
const fullPath = path.resolve(modulesDir, modulePath)
|
||||||
|
if (!fs.existsSync(fullPath)) {
|
||||||
|
console.warn(` Warning: module not found — ${fullPath}`)
|
||||||
|
result.modulesMissing.push(modulePath)
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
const raw = fs.readFileSync(fullPath, 'utf8')
|
||||||
|
const resolved = resolveImports(raw, path.dirname(fullPath))
|
||||||
|
const importsInFile = (raw.match(/^@.+$/gm) || []).length
|
||||||
|
result.importsResolved += importsInFile
|
||||||
|
result.modulesLoaded++
|
||||||
|
return resolved
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildHeader(profile: Profile): string {
|
||||||
|
const { name, role, seniority, tools, style } = profile.profile
|
||||||
|
return [
|
||||||
|
`# CLAUDE.md`,
|
||||||
|
`# Assembled for: ${name} | Role: ${role} | Seniority: ${seniority}`,
|
||||||
|
`# Generated: ${new Date().toISOString().split('T')[0]}`,
|
||||||
|
`# Stack: ${tools.primary_lang}${tools.frontend !== 'none' ? ` + ${tools.frontend}` : ''}${tools.backend !== 'none' ? ` + ${tools.backend}` : ''}`,
|
||||||
|
`# Style: verbosity=${style.verbosity}, comments=${style.comment_style}, tests=${style.test_coverage}`,
|
||||||
|
'',
|
||||||
|
].join('\n')
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildOverrides(rules: string[]): string {
|
||||||
|
if (rules.length === 0) return ''
|
||||||
|
return [
|
||||||
|
'\n## Personal Rules',
|
||||||
|
'',
|
||||||
|
...rules.map((r) => `- ${r}`),
|
||||||
|
'',
|
||||||
|
].join('\n')
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Core ─────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
function assemble(
|
||||||
|
profilePath: string,
|
||||||
|
outputPath: string,
|
||||||
|
modulesDir: string,
|
||||||
|
dryRun: boolean
|
||||||
|
): AssemblyResult {
|
||||||
|
const profile = loadProfile(profilePath)
|
||||||
|
const result: AssemblyResult = {
|
||||||
|
content: '',
|
||||||
|
totalChars: 0,
|
||||||
|
estimatedTokens: 0,
|
||||||
|
modulesLoaded: 0,
|
||||||
|
modulesMissing: [],
|
||||||
|
importsResolved: 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
const sections: string[] = [buildHeader(profile)]
|
||||||
|
|
||||||
|
for (const modulePath of profile.modules.include) {
|
||||||
|
if (profile.modules.exclude.includes(modulePath)) {
|
||||||
|
console.log(` Skipped (excluded): ${modulePath}`)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
const content = loadModule(modulePath, modulesDir, result)
|
||||||
|
if (content) {
|
||||||
|
sections.push(`\n<!-- ── Module: ${modulePath} ── -->\n`)
|
||||||
|
sections.push(content.trim())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const overrides = buildOverrides(profile.overrides.custom_rules)
|
||||||
|
if (overrides) sections.push(overrides)
|
||||||
|
|
||||||
|
result.content = sections.join('\n')
|
||||||
|
result.totalChars = result.content.length
|
||||||
|
result.estimatedTokens = Math.round(result.totalChars / 4)
|
||||||
|
|
||||||
|
if (!dryRun) {
|
||||||
|
fs.mkdirSync(path.dirname(path.resolve(outputPath)), { recursive: true })
|
||||||
|
fs.writeFileSync(outputPath, result.content)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── CLI ───────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
function parseArgs(): {
|
||||||
|
profilePath: string
|
||||||
|
outputPath: string
|
||||||
|
modulesDir: string
|
||||||
|
dryRun: boolean
|
||||||
|
} {
|
||||||
|
const args = process.argv.slice(2)
|
||||||
|
const get = (flag: string, fallback: string): string => {
|
||||||
|
const idx = args.indexOf(flag)
|
||||||
|
return idx !== -1 && args[idx + 1] ? args[idx + 1] : fallback
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
profilePath: get('--profile', '.claude/profiles/default.yaml'),
|
||||||
|
outputPath: get('--output', 'CLAUDE.md'),
|
||||||
|
modulesDir: get('--modules', '.claude/modules'),
|
||||||
|
dryRun: args.includes('--dry-run'),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function main() {
|
||||||
|
const { profilePath, outputPath, modulesDir, dryRun } = parseArgs()
|
||||||
|
|
||||||
|
console.log('Context Assembler')
|
||||||
|
console.log('=================')
|
||||||
|
console.log(`Profile: ${profilePath}`)
|
||||||
|
console.log(`Modules: ${modulesDir}`)
|
||||||
|
console.log(`Output: ${outputPath}${dryRun ? ' (dry-run — not written)' : ''}`)
|
||||||
|
console.log('')
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = assemble(profilePath, outputPath, modulesDir, dryRun)
|
||||||
|
|
||||||
|
console.log('')
|
||||||
|
console.log('Summary:')
|
||||||
|
console.log(` Modules loaded: ${result.modulesLoaded}`)
|
||||||
|
console.log(` Modules missing: ${result.modulesMissing.length}`)
|
||||||
|
console.log(` @imports resolved: ${result.importsResolved}`)
|
||||||
|
console.log(` Output size: ${result.totalChars} chars (~${result.estimatedTokens} tokens)`)
|
||||||
|
|
||||||
|
if (result.modulesMissing.length > 0) {
|
||||||
|
console.log('')
|
||||||
|
console.log('Missing modules (create these files or remove from profile):')
|
||||||
|
for (const m of result.modulesMissing) {
|
||||||
|
console.log(` - ${m}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.estimatedTokens > 10000) {
|
||||||
|
console.log('')
|
||||||
|
console.log(
|
||||||
|
`Warning: ~${result.estimatedTokens} tokens is on the heavy side (target <10K).`
|
||||||
|
)
|
||||||
|
console.log(' Consider splitting into per-task @imports instead of always-on.')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dryRun) {
|
||||||
|
console.log('')
|
||||||
|
console.log(`Done: ${outputPath}`)
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`Error: ${(err as Error).message}`)
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main()
|
||||||
285
examples/context-engineering/canary-check.sh
Executable file
285
examples/context-engineering/canary-check.sh
Executable file
|
|
@ -0,0 +1,285 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Context Engineering Canary Check
|
||||||
|
#
|
||||||
|
# Runs structural validation tests against your CLAUDE.md configuration.
|
||||||
|
# Catches common drift issues: missing files, broken imports, bloated size, conflicting rules.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# ./canary-check.sh # Check current directory
|
||||||
|
# ./canary-check.sh /path/to/project # Check specific project
|
||||||
|
#
|
||||||
|
# Exit codes:
|
||||||
|
# 0 — all checks passed
|
||||||
|
# N — number of issues found
|
||||||
|
#
|
||||||
|
# Run this weekly, or add it to your pre-commit hook for critical projects.
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
PROJECT_DIR="${1:-.}"
|
||||||
|
PROJECT_DIR="$(cd "$PROJECT_DIR" && pwd)" # Resolve to absolute path
|
||||||
|
|
||||||
|
PASS=0
|
||||||
|
FAIL=0
|
||||||
|
WARN=0
|
||||||
|
RESULTS=()
|
||||||
|
|
||||||
|
# ── Result tracking ───────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
log_pass() {
|
||||||
|
local test="$1"
|
||||||
|
local detail="${2:-}"
|
||||||
|
RESULTS+=("PASS $test${detail:+: $detail}")
|
||||||
|
PASS=$((PASS + 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
log_fail() {
|
||||||
|
local test="$1"
|
||||||
|
local detail="${2:-}"
|
||||||
|
RESULTS+=("FAIL $test${detail:+: $detail}")
|
||||||
|
FAIL=$((FAIL + 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
log_warn() {
|
||||||
|
local test="$1"
|
||||||
|
local detail="${2:-}"
|
||||||
|
RESULTS+=("WARN $test${detail:+: $detail}")
|
||||||
|
WARN=$((WARN + 1))
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Check 1: CLAUDE.md exists and is non-trivial ──────────────────────────────
|
||||||
|
|
||||||
|
check_claude_md_exists() {
|
||||||
|
local file="$PROJECT_DIR/CLAUDE.md"
|
||||||
|
if [ ! -f "$file" ]; then
|
||||||
|
log_fail "CLAUDE.md exists" "Not found at $file"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
log_pass "CLAUDE.md exists" "$file"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
check_claude_md_size() {
|
||||||
|
local file="$PROJECT_DIR/CLAUDE.md"
|
||||||
|
[ ! -f "$file" ] && return
|
||||||
|
|
||||||
|
local lines
|
||||||
|
lines=$(wc -l < "$file" | tr -d ' ')
|
||||||
|
|
||||||
|
if [ "$lines" -lt 10 ]; then
|
||||||
|
log_fail "CLAUDE.md has content" "Only $lines lines — too sparse to be useful"
|
||||||
|
elif [ "$lines" -gt 500 ]; then
|
||||||
|
log_warn "CLAUDE.md size" "$lines lines exceeds 500 — consider modularizing with @imports"
|
||||||
|
else
|
||||||
|
log_pass "CLAUDE.md size" "$lines lines (healthy: 10-500)"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Check 2: Broken @imports ──────────────────────────────────────────────────
|
||||||
|
|
||||||
|
check_imports() {
|
||||||
|
local file="$PROJECT_DIR/CLAUDE.md"
|
||||||
|
[ ! -f "$file" ] && return
|
||||||
|
|
||||||
|
local broken=0
|
||||||
|
local resolved=0
|
||||||
|
|
||||||
|
while IFS= read -r line; do
|
||||||
|
if [[ "$line" =~ ^@([^[:space:]].+)$ ]]; then
|
||||||
|
local import_path="${BASH_REMATCH[1]}"
|
||||||
|
local full_path="$PROJECT_DIR/$import_path"
|
||||||
|
if [ ! -f "$full_path" ]; then
|
||||||
|
log_fail "Broken @import" "@$import_path — file not found"
|
||||||
|
broken=$((broken + 1))
|
||||||
|
else
|
||||||
|
resolved=$((resolved + 1))
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done < "$file"
|
||||||
|
|
||||||
|
if [ "$broken" -eq 0 ]; then
|
||||||
|
if [ "$resolved" -gt 0 ]; then
|
||||||
|
log_pass "@import resolution" "All $resolved @imports resolve"
|
||||||
|
else
|
||||||
|
log_pass "@import resolution" "No @imports (not using modular setup)"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Check 3: Rule count ───────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
check_rule_count() {
|
||||||
|
local file="$PROJECT_DIR/CLAUDE.md"
|
||||||
|
[ ! -f "$file" ] && return
|
||||||
|
|
||||||
|
local rules
|
||||||
|
rules=$(grep -cE "^[[:space:]]*[-*] |^[[:space:]]*[0-9]+\. " "$file" 2>/dev/null || echo "0")
|
||||||
|
|
||||||
|
if [ "$rules" -gt 150 ]; then
|
||||||
|
log_warn "Rule count" "$rules rules (adherence ceiling is ~150 — Claude may drop rules)"
|
||||||
|
else
|
||||||
|
log_pass "Rule count" "$rules rules"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Check 4: Conflicting always/never rules ───────────────────────────────────
|
||||||
|
|
||||||
|
check_conflicts() {
|
||||||
|
local file="$PROJECT_DIR/CLAUDE.md"
|
||||||
|
[ ! -f "$file" ] && return
|
||||||
|
|
||||||
|
local conflicts=0
|
||||||
|
local topics=("comments" "tests" "types" "imports" "exports" "logging" "errors")
|
||||||
|
|
||||||
|
for topic in "${topics[@]}"; do
|
||||||
|
local always_count never_count
|
||||||
|
always_count=$(grep -ciE "always[[:space:]]+[a-z ]*$topic|$topic[a-z ]*[[:space:]]+always" "$file" 2>/dev/null || echo "0")
|
||||||
|
never_count=$(grep -ciE "never[[:space:]]+[a-z ]*$topic|$topic[a-z ]*[[:space:]]+never" "$file" 2>/dev/null || echo "0")
|
||||||
|
|
||||||
|
if [ "$always_count" -gt 0 ] && [ "$never_count" -gt 0 ]; then
|
||||||
|
log_warn "Potential conflict: $topic" "Both 'always' and 'never' rules found — verify they don't contradict"
|
||||||
|
conflicts=$((conflicts + 1))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "$conflicts" -eq 0 ]; then
|
||||||
|
log_pass "Conflict check" "No obvious always/never contradictions detected"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Check 5: Git tracking and freshness ───────────────────────────────────────
|
||||||
|
|
||||||
|
check_git_tracking() {
|
||||||
|
local file="$PROJECT_DIR/CLAUDE.md"
|
||||||
|
[ ! -f "$file" ] && return
|
||||||
|
|
||||||
|
if ! command -v git &>/dev/null; then
|
||||||
|
log_warn "Git tracking" "git not available — skipping"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! git -C "$PROJECT_DIR" rev-parse --git-dir &>/dev/null 2>&1; then
|
||||||
|
log_warn "Git tracking" "Not a git repo — skipping"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if tracked
|
||||||
|
if ! git -C "$PROJECT_DIR" ls-files --error-unmatch CLAUDE.md &>/dev/null 2>&1; then
|
||||||
|
log_fail "CLAUDE.md in git" "File exists but is not tracked — run: git add CLAUDE.md"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check freshness
|
||||||
|
local last_updated
|
||||||
|
last_updated=$(git -C "$PROJECT_DIR" log --format="%ar" -- CLAUDE.md 2>/dev/null | head -1)
|
||||||
|
|
||||||
|
if [ -z "$last_updated" ]; then
|
||||||
|
log_warn "CLAUDE.md freshness" "No git history for this file"
|
||||||
|
else
|
||||||
|
log_pass "CLAUDE.md freshness" "Last updated: $last_updated"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Check 6: Required sections ────────────────────────────────────────────────
|
||||||
|
|
||||||
|
check_required_sections() {
|
||||||
|
local file="$PROJECT_DIR/CLAUDE.md"
|
||||||
|
[ ! -f "$file" ] && return
|
||||||
|
|
||||||
|
local missing=0
|
||||||
|
local -a required_sections=("Overview\|Purpose\|Description" "Architecture\|Stack\|Tech" "Standards\|Conventions\|Style")
|
||||||
|
|
||||||
|
for pattern in "${required_sections[@]}"; do
|
||||||
|
if ! grep -qiE "^#+ ($pattern)" "$file" 2>/dev/null; then
|
||||||
|
local display="${pattern//\\|/ or }"
|
||||||
|
log_warn "Missing section" "No heading matching: $display"
|
||||||
|
missing=$((missing + 1))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ "$missing" -eq 0 ]; then
|
||||||
|
log_pass "Required sections" "Overview, Architecture, and Standards sections found"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Check 7: Token budget estimate ───────────────────────────────────────────
|
||||||
|
|
||||||
|
check_token_budget() {
|
||||||
|
local file="$PROJECT_DIR/CLAUDE.md"
|
||||||
|
[ ! -f "$file" ] && return
|
||||||
|
|
||||||
|
local chars
|
||||||
|
chars=$(wc -c < "$file" | tr -d ' ')
|
||||||
|
local tokens=$((chars / 4))
|
||||||
|
|
||||||
|
# Sum up @imports too
|
||||||
|
local import_tokens=0
|
||||||
|
while IFS= read -r line; do
|
||||||
|
if [[ "$line" =~ ^@([^[:space:]].+)$ ]]; then
|
||||||
|
local import_path="${BASH_REMATCH[1]}"
|
||||||
|
local full_path="$PROJECT_DIR/$import_path"
|
||||||
|
if [ -f "$full_path" ]; then
|
||||||
|
local import_chars
|
||||||
|
import_chars=$(wc -c < "$full_path" | tr -d ' ')
|
||||||
|
import_tokens=$((import_tokens + import_chars / 4))
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done < "$file"
|
||||||
|
|
||||||
|
local total=$((tokens + import_tokens))
|
||||||
|
|
||||||
|
if [ "$total" -lt 2000 ]; then
|
||||||
|
log_pass "Token budget" "~$total tokens (lean)"
|
||||||
|
elif [ "$total" -lt 10000 ]; then
|
||||||
|
log_pass "Token budget" "~$total tokens (healthy)"
|
||||||
|
elif [ "$total" -lt 25000 ]; then
|
||||||
|
log_warn "Token budget" "~$total tokens (heavy — consider trimming)"
|
||||||
|
else
|
||||||
|
log_fail "Token budget" "~$total tokens (overloaded — Claude will likely ignore some rules)"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Run all checks ────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
echo "Context Engineering Canary Check"
|
||||||
|
echo "================================="
|
||||||
|
echo "Project: $PROJECT_DIR"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
check_claude_md_exists || true
|
||||||
|
check_claude_md_size
|
||||||
|
check_imports
|
||||||
|
check_rule_count
|
||||||
|
check_conflicts
|
||||||
|
check_git_tracking
|
||||||
|
check_required_sections
|
||||||
|
check_token_budget
|
||||||
|
|
||||||
|
# ── Summary ───────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Results:"
|
||||||
|
echo "--------"
|
||||||
|
for result in "${RESULTS[@]}"; do
|
||||||
|
echo " $result"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Score: $PASS passed, $WARN warnings, $FAIL failed"
|
||||||
|
|
||||||
|
if [ "$FAIL" -gt 0 ]; then
|
||||||
|
echo "Status: ISSUES FOUND"
|
||||||
|
echo ""
|
||||||
|
echo "Next steps:"
|
||||||
|
echo " - Fix failing checks above"
|
||||||
|
echo " - Run ./eval-questions.yaml audit for deeper analysis"
|
||||||
|
echo " - See guide/core/context-engineering.md for remediation guidance"
|
||||||
|
exit "$FAIL"
|
||||||
|
elif [ "$WARN" -gt 0 ]; then
|
||||||
|
echo "Status: PASSED WITH WARNINGS"
|
||||||
|
echo " Address warnings to improve context quality"
|
||||||
|
exit 0
|
||||||
|
else
|
||||||
|
echo "Status: ALL CHECKS PASSED"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
216
examples/context-engineering/ci-drift-check.yml
Normal file
216
examples/context-engineering/ci-drift-check.yml
Normal file
|
|
@ -0,0 +1,216 @@
|
||||||
|
name: Context Drift Check
|
||||||
|
|
||||||
|
# Detects structural degradation in CLAUDE.md on a weekly schedule.
|
||||||
|
# Opens a GitHub issue automatically when problems are found.
|
||||||
|
#
|
||||||
|
# Setup:
|
||||||
|
# 1. Copy this file to .github/workflows/context-drift.yml
|
||||||
|
# 2. Make sure canary-check.sh is committed and executable
|
||||||
|
# 3. Adjust the cron schedule and threshold values as needed
|
||||||
|
#
|
||||||
|
# The workflow checks:
|
||||||
|
# - Structural validity (broken @imports, size, conflicts)
|
||||||
|
# - CLAUDE.md size trend (warns when exceeding threshold)
|
||||||
|
# - Broken @import references
|
||||||
|
|
||||||
|
on:
|
||||||
|
schedule:
|
||||||
|
- cron: '0 9 * * 1' # Every Monday at 9:00 AM UTC
|
||||||
|
workflow_dispatch: # Allow manual trigger from GitHub UI
|
||||||
|
inputs:
|
||||||
|
project_dir:
|
||||||
|
description: 'Project directory to check (relative to repo root)'
|
||||||
|
required: false
|
||||||
|
default: '.'
|
||||||
|
|
||||||
|
env:
|
||||||
|
# Customize these thresholds for your project
|
||||||
|
CLAUDE_MD_MAX_LINES: 500
|
||||||
|
CLAUDE_MD_WARN_LINES: 400
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
drift-check:
|
||||||
|
name: Check CLAUDE.md for drift
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
issues: write # Required to open issues on failure
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
fetch-depth: 0 # Full history needed for git log checks
|
||||||
|
|
||||||
|
- name: Make canary script executable
|
||||||
|
run: chmod +x ./examples/context-engineering/canary-check.sh
|
||||||
|
|
||||||
|
- name: Run structural canary checks
|
||||||
|
id: canary
|
||||||
|
run: |
|
||||||
|
PROJECT_DIR="${{ github.event.inputs.project_dir || '.' }}"
|
||||||
|
./examples/context-engineering/canary-check.sh "$PROJECT_DIR"
|
||||||
|
continue-on-error: true # Capture exit code without stopping workflow
|
||||||
|
|
||||||
|
- name: Check CLAUDE.md size against thresholds
|
||||||
|
id: size_check
|
||||||
|
run: |
|
||||||
|
FILE="CLAUDE.md"
|
||||||
|
if [ ! -f "$FILE" ]; then
|
||||||
|
echo "::warning::CLAUDE.md not found at repo root"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
CURRENT=$(wc -l < "$FILE" | tr -d ' ')
|
||||||
|
echo "current_lines=$CURRENT" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
if [ "$CURRENT" -gt "$CLAUDE_MD_MAX_LINES" ]; then
|
||||||
|
echo "::error::CLAUDE.md has $CURRENT lines (max: $CLAUDE_MD_MAX_LINES). Consider modularizing with @imports."
|
||||||
|
echo "size_status=fail" >> "$GITHUB_OUTPUT"
|
||||||
|
elif [ "$CURRENT" -gt "$CLAUDE_MD_WARN_LINES" ]; then
|
||||||
|
echo "::warning::CLAUDE.md has $CURRENT lines (warn threshold: $CLAUDE_MD_WARN_LINES). Getting large."
|
||||||
|
echo "size_status=warn" >> "$GITHUB_OUTPUT"
|
||||||
|
else
|
||||||
|
echo "CLAUDE.md size: $CURRENT lines (OK)"
|
||||||
|
echo "size_status=ok" >> "$GITHUB_OUTPUT"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Check for stale @imports
|
||||||
|
id: import_check
|
||||||
|
run: |
|
||||||
|
FILE="CLAUDE.md"
|
||||||
|
if [ ! -f "$FILE" ]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
BROKEN=0
|
||||||
|
while IFS= read -r line; do
|
||||||
|
if [[ "$line" =~ ^@([^[:space:]].+)$ ]]; then
|
||||||
|
IMPORT="${BASH_REMATCH[1]}"
|
||||||
|
if [ ! -f "$IMPORT" ]; then
|
||||||
|
echo "::error::Broken @import in CLAUDE.md: @$IMPORT"
|
||||||
|
BROKEN=$((BROKEN + 1))
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
done < "$FILE"
|
||||||
|
|
||||||
|
echo "broken_imports=$BROKEN" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
if [ "$BROKEN" -gt 0 ]; then
|
||||||
|
echo "::error::Found $BROKEN broken @import(s) in CLAUDE.md"
|
||||||
|
else
|
||||||
|
echo "All @imports resolve correctly"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Check CLAUDE.md is git-tracked and recent
|
||||||
|
id: freshness_check
|
||||||
|
run: |
|
||||||
|
FILE="CLAUDE.md"
|
||||||
|
if [ ! -f "$FILE" ]; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check if tracked
|
||||||
|
if ! git ls-files --error-unmatch "$FILE" > /dev/null 2>&1; then
|
||||||
|
echo "::warning::CLAUDE.md is not tracked in git"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get days since last update
|
||||||
|
LAST_COMMIT_DATE=$(git log -1 --format="%cd" --date=format:"%Y-%m-%d" -- "$FILE")
|
||||||
|
TODAY=$(date +%Y-%m-%d)
|
||||||
|
DAYS_OLD=$(( ($(date -d "$TODAY" +%s 2>/dev/null || date -j -f "%Y-%m-%d" "$TODAY" +%s) - $(date -d "$LAST_COMMIT_DATE" +%s 2>/dev/null || date -j -f "%Y-%m-%d" "$LAST_COMMIT_DATE" +%s)) / 86400 ))
|
||||||
|
|
||||||
|
echo "days_old=$DAYS_OLD" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "last_updated=$LAST_COMMIT_DATE" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
if [ "$DAYS_OLD" -gt 90 ]; then
|
||||||
|
echo "::warning::CLAUDE.md was last updated $DAYS_OLD days ago ($LAST_COMMIT_DATE). Consider reviewing for stale rules."
|
||||||
|
else
|
||||||
|
echo "CLAUDE.md freshness: last updated $DAYS_OLD days ago ($LAST_COMMIT_DATE) — OK"
|
||||||
|
fi
|
||||||
|
|
||||||
|
- name: Collect check results
|
||||||
|
id: summary
|
||||||
|
if: always()
|
||||||
|
run: |
|
||||||
|
CANARY_STATUS="${{ steps.canary.outcome }}"
|
||||||
|
BROKEN_IMPORTS="${{ steps.import_check.outputs.broken_imports || 0 }}"
|
||||||
|
SIZE_STATUS="${{ steps.size_check.outputs.size_status || 'ok' }}"
|
||||||
|
CURRENT_LINES="${{ steps.size_check.outputs.current_lines || 0 }}"
|
||||||
|
DAYS_OLD="${{ steps.freshness_check.outputs.days_old || 0 }}"
|
||||||
|
LAST_UPDATED="${{ steps.freshness_check.outputs.last_updated || 'unknown' }}"
|
||||||
|
|
||||||
|
ISSUES=0
|
||||||
|
[ "$CANARY_STATUS" = "failure" ] && ISSUES=$((ISSUES + 1))
|
||||||
|
[ "$BROKEN_IMPORTS" -gt 0 ] && ISSUES=$((ISSUES + BROKEN_IMPORTS))
|
||||||
|
[ "$SIZE_STATUS" = "fail" ] && ISSUES=$((ISSUES + 1))
|
||||||
|
|
||||||
|
echo "total_issues=$ISSUES" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "summary_lines=$CURRENT_LINES" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "summary_days=$DAYS_OLD" >> "$GITHUB_OUTPUT"
|
||||||
|
echo "summary_updated=$LAST_UPDATED" >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
|
- name: Open issue on failure
|
||||||
|
if: always() && steps.summary.outputs.total_issues > 0
|
||||||
|
uses: actions/github-script@v7
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const issues = parseInt('${{ steps.summary.outputs.total_issues }}');
|
||||||
|
const lines = '${{ steps.summary.outputs.summary_lines }}';
|
||||||
|
const daysOld = '${{ steps.summary.outputs.summary_days }}';
|
||||||
|
const lastUpdated = '${{ steps.summary.outputs.summary_updated }}';
|
||||||
|
const runUrl = `${context.serverUrl}/${context.repo.owner}/${context.repo.repo}/actions/runs/${context.runId}`;
|
||||||
|
|
||||||
|
// Check if there's already an open issue for drift
|
||||||
|
const openIssues = await github.rest.issues.listForRepo({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
labels: 'ai-context,maintenance',
|
||||||
|
state: 'open',
|
||||||
|
});
|
||||||
|
|
||||||
|
if (openIssues.data.length > 0) {
|
||||||
|
// Add a comment to the existing issue instead of opening a new one
|
||||||
|
const existingIssue = openIssues.data[0];
|
||||||
|
await github.rest.issues.createComment({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
issue_number: existingIssue.number,
|
||||||
|
body: `Weekly check still finding issues (${issues} problem(s)).\n\nRun: ${runUrl}\nCLAUDE.md: ${lines} lines, last updated: ${lastUpdated} (${daysOld} days ago)`,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await github.rest.issues.create({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
title: `Context Drift Detected — CLAUDE.md needs review`,
|
||||||
|
body: [
|
||||||
|
`The weekly context drift check found **${issues} problem(s)** in \`CLAUDE.md\`.`,
|
||||||
|
``,
|
||||||
|
`## Details`,
|
||||||
|
`- File size: ${lines} lines`,
|
||||||
|
`- Last updated: ${lastUpdated} (${daysOld} days ago)`,
|
||||||
|
`- Workflow run: ${runUrl}`,
|
||||||
|
``,
|
||||||
|
`## Action Required`,
|
||||||
|
`1. Review the workflow logs for specific issues`,
|
||||||
|
`2. Run \`./examples/context-engineering/canary-check.sh .\` locally for details`,
|
||||||
|
`3. Fix broken @imports, reduce file size, or update stale rules`,
|
||||||
|
`4. Close this issue once CLAUDE.md is back in good shape`,
|
||||||
|
``,
|
||||||
|
`_This issue was opened automatically by the context drift check workflow._`,
|
||||||
|
].join('\n'),
|
||||||
|
labels: ['ai-context', 'maintenance'],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
- name: Final status
|
||||||
|
if: always()
|
||||||
|
run: |
|
||||||
|
ISSUES="${{ steps.summary.outputs.total_issues }}"
|
||||||
|
if [ "$ISSUES" -gt 0 ]; then
|
||||||
|
echo "Context drift check: FAILED ($ISSUES issues)"
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
echo "Context drift check: PASSED"
|
||||||
|
fi
|
||||||
188
examples/context-engineering/context-budget-calculator.sh
Executable file
188
examples/context-engineering/context-budget-calculator.sh
Executable file
|
|
@ -0,0 +1,188 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# Context Budget Calculator
|
||||||
|
#
|
||||||
|
# Measures the always-on token cost of your CLAUDE.md configuration.
|
||||||
|
# Accounts for: global CLAUDE.md, project CLAUDE.md, and all @imported modules.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# ./context-budget-calculator.sh # Check current directory
|
||||||
|
# ./context-budget-calculator.sh /path/to/project # Check specific project
|
||||||
|
#
|
||||||
|
# Token estimation: ~4 chars per token (approximate, varies by content type)
|
||||||
|
#
|
||||||
|
# Budget guide:
|
||||||
|
# < 2K tokens — lean (excellent)
|
||||||
|
# 2K-10K tokens — healthy (good range for most projects)
|
||||||
|
# 10K-25K tokens — heavy (review for trimming opportunities)
|
||||||
|
# > 25K tokens — overloaded (Claude will likely deprioritize some rules)
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
PROJECT_DIR="${1:-.}"
|
||||||
|
PROJECT_DIR="$(cd "$PROJECT_DIR" && pwd)"
|
||||||
|
GLOBAL_CLAUDE="$HOME/.claude/CLAUDE.md"
|
||||||
|
PROJECT_CLAUDE="$PROJECT_DIR/CLAUDE.md"
|
||||||
|
|
||||||
|
# ── Helpers ───────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
estimate_tokens() {
|
||||||
|
local file="$1"
|
||||||
|
if [ ! -f "$file" ]; then
|
||||||
|
echo "0"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
local chars
|
||||||
|
chars=$(wc -c < "$file" | tr -d ' ')
|
||||||
|
echo $((chars / 4))
|
||||||
|
}
|
||||||
|
|
||||||
|
count_lines() {
|
||||||
|
local file="$1"
|
||||||
|
if [ ! -f "$file" ]; then
|
||||||
|
echo "0"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
wc -l < "$file" | tr -d ' '
|
||||||
|
}
|
||||||
|
|
||||||
|
count_rules() {
|
||||||
|
local file="$1"
|
||||||
|
if [ ! -f "$file" ]; then
|
||||||
|
echo "0"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
grep -cE "^[[:space:]]*[-*] |^[[:space:]]*[0-9]+\. " "$file" 2>/dev/null || echo "0"
|
||||||
|
}
|
||||||
|
|
||||||
|
format_assessment() {
|
||||||
|
local tokens="$1"
|
||||||
|
if [ "$tokens" -lt 2000 ]; then
|
||||||
|
echo "LEAN — well under budget, headroom available"
|
||||||
|
elif [ "$tokens" -lt 10000 ]; then
|
||||||
|
echo "HEALTHY — good range for most projects"
|
||||||
|
elif [ "$tokens" -lt 25000 ]; then
|
||||||
|
echo "HEAVY — consider trimming or deferring to @imports"
|
||||||
|
else
|
||||||
|
echo "OVERLOADED — Claude will likely deprioritize some rules"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Collect @imports from a file ──────────────────────────────────────────────
|
||||||
|
|
||||||
|
collect_imports() {
|
||||||
|
local file="$1"
|
||||||
|
local base_dir="$2"
|
||||||
|
local -n imports_ref="$3" # nameref to array
|
||||||
|
|
||||||
|
[ ! -f "$file" ] && return
|
||||||
|
|
||||||
|
while IFS= read -r line; do
|
||||||
|
if [[ "$line" =~ ^@([^[:space:]].+)$ ]]; then
|
||||||
|
local import_path="${BASH_REMATCH[1]}"
|
||||||
|
local full_path="$base_dir/$import_path"
|
||||||
|
imports_ref+=("$import_path|$full_path")
|
||||||
|
fi
|
||||||
|
done < "$file"
|
||||||
|
}
|
||||||
|
|
||||||
|
# ── Main ──────────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
echo "Context Budget Calculator"
|
||||||
|
echo "========================="
|
||||||
|
echo "Project: $PROJECT_DIR"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
GRAND_TOTAL_TOKENS=0
|
||||||
|
GRAND_TOTAL_RULES=0
|
||||||
|
|
||||||
|
# Global CLAUDE.md
|
||||||
|
echo "Global CLAUDE.md (~/.claude/CLAUDE.md)"
|
||||||
|
echo "----------------------------------------"
|
||||||
|
if [ -f "$GLOBAL_CLAUDE" ]; then
|
||||||
|
G_TOKENS=$(estimate_tokens "$GLOBAL_CLAUDE")
|
||||||
|
G_LINES=$(count_lines "$GLOBAL_CLAUDE")
|
||||||
|
G_RULES=$(count_rules "$GLOBAL_CLAUDE")
|
||||||
|
echo " Lines: $G_LINES"
|
||||||
|
echo " Rules: $G_RULES"
|
||||||
|
echo " Tokens: ~$G_TOKENS"
|
||||||
|
GRAND_TOTAL_TOKENS=$((GRAND_TOTAL_TOKENS + G_TOKENS))
|
||||||
|
GRAND_TOTAL_RULES=$((GRAND_TOTAL_RULES + G_RULES))
|
||||||
|
else
|
||||||
|
echo " (not found — no global config)"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Project CLAUDE.md
|
||||||
|
echo "Project CLAUDE.md ($PROJECT_CLAUDE)"
|
||||||
|
echo "----------------------------------------"
|
||||||
|
if [ -f "$PROJECT_CLAUDE" ]; then
|
||||||
|
P_TOKENS=$(estimate_tokens "$PROJECT_CLAUDE")
|
||||||
|
P_LINES=$(count_lines "$PROJECT_CLAUDE")
|
||||||
|
P_RULES=$(count_rules "$PROJECT_CLAUDE")
|
||||||
|
echo " Lines: $P_LINES"
|
||||||
|
echo " Rules: $P_RULES"
|
||||||
|
echo " Tokens: ~$P_TOKENS"
|
||||||
|
GRAND_TOTAL_TOKENS=$((GRAND_TOTAL_TOKENS + P_TOKENS))
|
||||||
|
GRAND_TOTAL_RULES=$((GRAND_TOTAL_RULES + P_RULES))
|
||||||
|
else
|
||||||
|
echo " (not found)"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# @imports from project CLAUDE.md
|
||||||
|
declare -a IMPORTS=()
|
||||||
|
collect_imports "$PROJECT_CLAUDE" "$PROJECT_DIR" IMPORTS
|
||||||
|
|
||||||
|
IMPORT_TOTAL_TOKENS=0
|
||||||
|
if [ "${#IMPORTS[@]}" -gt 0 ]; then
|
||||||
|
echo "@imports (always-loaded modules)"
|
||||||
|
echo "----------------------------------------"
|
||||||
|
for entry in "${IMPORTS[@]}"; do
|
||||||
|
local_path="${entry%%|*}"
|
||||||
|
full_path="${entry##*|}"
|
||||||
|
if [ -f "$full_path" ]; then
|
||||||
|
I_TOKENS=$(estimate_tokens "$full_path")
|
||||||
|
I_LINES=$(count_lines "$full_path")
|
||||||
|
IMPORT_TOTAL_TOKENS=$((IMPORT_TOTAL_TOKENS + I_TOKENS))
|
||||||
|
printf " %-45s %5d lines ~%d tokens\n" "@$local_path" "$I_LINES" "$I_TOKENS"
|
||||||
|
else
|
||||||
|
printf " %-45s %s\n" "@$local_path" "NOT FOUND"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo ""
|
||||||
|
echo " Import total: ~$IMPORT_TOTAL_TOKENS tokens"
|
||||||
|
GRAND_TOTAL_TOKENS=$((GRAND_TOTAL_TOKENS + IMPORT_TOTAL_TOKENS))
|
||||||
|
echo ""
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Summary
|
||||||
|
echo "Summary"
|
||||||
|
echo "======="
|
||||||
|
echo ""
|
||||||
|
echo " Total always-on tokens: ~$GRAND_TOTAL_TOKENS"
|
||||||
|
echo " Total rules/instructions: $GRAND_TOTAL_RULES"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
ASSESSMENT=$(format_assessment "$GRAND_TOTAL_TOKENS")
|
||||||
|
echo " Budget assessment: $ASSESSMENT"
|
||||||
|
|
||||||
|
if [ "$GRAND_TOTAL_RULES" -gt 150 ]; then
|
||||||
|
echo ""
|
||||||
|
echo " Rule count warning: $GRAND_TOTAL_RULES rules exceeds ~150"
|
||||||
|
echo " Claude's adherence decreases as rule count grows."
|
||||||
|
echo " Consider consolidating redundant rules or moving to task-scoped @imports."
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "Optimization Tips"
|
||||||
|
echo "-----------------"
|
||||||
|
if [ "$GRAND_TOTAL_TOKENS" -gt 10000 ]; then
|
||||||
|
echo " 1. Move reference material to @imports and load only when needed"
|
||||||
|
echo " 2. Trim verbose explanations — rules, not documentation"
|
||||||
|
echo " 3. Remove rules about deprecated tech that's been removed"
|
||||||
|
echo " 4. Consolidate duplicate rules across sections"
|
||||||
|
echo " 5. Global CLAUDE.md: keep to framework-level defaults, not project specifics"
|
||||||
|
else
|
||||||
|
echo " Budget is healthy. Maintain this range as the project grows."
|
||||||
|
echo " Set an alert when you approach $((GRAND_TOTAL_TOKENS + 3000)) tokens."
|
||||||
|
fi
|
||||||
173
examples/context-engineering/eval-questions.yaml
Normal file
173
examples/context-engineering/eval-questions.yaml
Normal file
|
|
@ -0,0 +1,173 @@
|
||||||
|
# Context Engineering Self-Evaluation
|
||||||
|
#
|
||||||
|
# Use these questions to audit your CLAUDE.md periodically.
|
||||||
|
# Score each question: pass (1) | partial (0.5) | fail (0)
|
||||||
|
# Target score: 16+ / 20
|
||||||
|
#
|
||||||
|
# Run this quarterly, or after any significant project change.
|
||||||
|
# Low-scoring areas tell you exactly where to invest time.
|
||||||
|
|
||||||
|
meta:
|
||||||
|
version: "1.0"
|
||||||
|
total_questions: 20
|
||||||
|
passing_threshold: 16
|
||||||
|
scoring:
|
||||||
|
pass: 1.0
|
||||||
|
partial: 0.5
|
||||||
|
fail: 0.0
|
||||||
|
|
||||||
|
questions:
|
||||||
|
# ── Coverage: Does CLAUDE.md contain the right information? ──────────────────
|
||||||
|
coverage:
|
||||||
|
description: "Checks that essential information is present"
|
||||||
|
questions:
|
||||||
|
- id: C1
|
||||||
|
weight: 1.0
|
||||||
|
question: "Does CLAUDE.md explain what this project does in 2-3 sentences?"
|
||||||
|
failing_indicator: "No Project Overview section, or it's vague ('a web app')"
|
||||||
|
passing_indicator: "Clear statement of purpose, audience, and deployment target"
|
||||||
|
|
||||||
|
- id: C2
|
||||||
|
weight: 1.0
|
||||||
|
question: "Are the primary tech stack and versions documented?"
|
||||||
|
failing_indicator: "No version numbers, or stack listed without context"
|
||||||
|
passing_indicator: "Table or list with framework + version for each layer"
|
||||||
|
|
||||||
|
- id: C3
|
||||||
|
weight: 1.0
|
||||||
|
question: "Are coding standards specific enough to be actionable?"
|
||||||
|
failing_indicator: "Rules like 'write clean code' or 'follow best practices'"
|
||||||
|
passing_indicator: "Rules like 'use zod for external input', 'no default exports'"
|
||||||
|
|
||||||
|
- id: C4
|
||||||
|
weight: 1.0
|
||||||
|
question: "Are deployment environments and commands documented?"
|
||||||
|
failing_indicator: "No deployment section, or just 'deploy to production'"
|
||||||
|
passing_indicator: "Environments listed, deploy commands specified"
|
||||||
|
|
||||||
|
- id: C5
|
||||||
|
weight: 1.0
|
||||||
|
question: "Are there explicit anti-patterns (what NOT to do)?"
|
||||||
|
failing_indicator: "No negative rules at all"
|
||||||
|
passing_indicator: "At least 3 explicit prohibitions with reasons"
|
||||||
|
|
||||||
|
# ── Quality: Are the rules well-written? ────────────────────────────────────
|
||||||
|
quality:
|
||||||
|
description: "Checks that rules are clear, non-redundant, and manageable"
|
||||||
|
questions:
|
||||||
|
- id: Q1
|
||||||
|
weight: 1.0
|
||||||
|
question: "Can each rule be followed without reading the rest of the file?"
|
||||||
|
failing_indicator: "Rules like 'follow the patterns established earlier'"
|
||||||
|
passing_indicator: "Each rule is self-contained and unambiguous"
|
||||||
|
|
||||||
|
- id: Q2
|
||||||
|
weight: 1.0
|
||||||
|
question: "Are there fewer than 150 total rules or instructions?"
|
||||||
|
failing_indicator: "More than 150 bullet points / numbered items"
|
||||||
|
passing_indicator: "Compact set that fits in working memory"
|
||||||
|
note: "150 is the adherence ceiling — beyond this, Claude starts dropping rules"
|
||||||
|
|
||||||
|
- id: Q3
|
||||||
|
weight: 1.0
|
||||||
|
question: "Does the file have fewer than 500 lines?"
|
||||||
|
failing_indicator: "File exceeds 500 lines"
|
||||||
|
passing_indicator: "Under 500 lines, or split into @imported modules"
|
||||||
|
note: "Long files signal either verbosity or lack of modularization"
|
||||||
|
|
||||||
|
- id: Q4
|
||||||
|
weight: 1.0
|
||||||
|
question: "Are rules specific and measurable rather than vague?"
|
||||||
|
failing_indicator: "Rules that require judgment ('write readable code')"
|
||||||
|
passing_indicator: "Rules that produce consistent output across different prompts"
|
||||||
|
|
||||||
|
- id: Q5
|
||||||
|
weight: 1.0
|
||||||
|
question: "Does each rule appear only once (no semantic duplicates)?"
|
||||||
|
failing_indicator: "Same constraint expressed in multiple ways across sections"
|
||||||
|
passing_indicator: "No redundancy — each constraint stated exactly once"
|
||||||
|
|
||||||
|
# ── Adherence: Is Claude actually following the rules? ───────────────────────
|
||||||
|
adherence:
|
||||||
|
description: "Behavioral checks — requires reviewing actual Claude outputs"
|
||||||
|
questions:
|
||||||
|
- id: A1
|
||||||
|
weight: 1.0
|
||||||
|
question: "Do Claude's outputs consistently follow the stated coding standards?"
|
||||||
|
how_to_check: "Ask Claude to write a new function and check it against your standards"
|
||||||
|
failing_indicator: "Claude uses patterns explicitly prohibited in CLAUDE.md"
|
||||||
|
passing_indicator: "Outputs match stated standards without prompting"
|
||||||
|
|
||||||
|
- id: A2
|
||||||
|
weight: 1.0
|
||||||
|
question: "Does Claude correctly use the specified libraries and avoid alternatives?"
|
||||||
|
how_to_check: "Ask Claude to add input validation — does it use your specified library?"
|
||||||
|
failing_indicator: "Claude suggests alternatives you've explicitly excluded"
|
||||||
|
passing_indicator: "Claude reaches for the specified tools automatically"
|
||||||
|
|
||||||
|
- id: A3
|
||||||
|
weight: 1.0
|
||||||
|
question: "Does Claude follow the git conventions when generating commits or PRs?"
|
||||||
|
how_to_check: "Ask Claude to write a commit message and check the format"
|
||||||
|
failing_indicator: "Wrong format, missing type prefix, wrong capitalization"
|
||||||
|
passing_indicator: "Commits match your conventional commits format exactly"
|
||||||
|
|
||||||
|
- id: A4
|
||||||
|
weight: 1.0
|
||||||
|
question: "Does Claude avoid the listed anti-patterns?"
|
||||||
|
how_to_check: "Introduce a scenario where the anti-pattern would be tempting"
|
||||||
|
failing_indicator: "Claude suggests a prohibited pattern without flagging it"
|
||||||
|
passing_indicator: "Claude avoids the pattern or explicitly explains why it's excluded"
|
||||||
|
|
||||||
|
- id: A5
|
||||||
|
weight: 1.0
|
||||||
|
question: "When given ambiguous instructions, does Claude make the right default choice?"
|
||||||
|
how_to_check: "Give a vague task ('add a cache') and see what Claude picks"
|
||||||
|
failing_indicator: "Claude invents a default that contradicts your architecture"
|
||||||
|
passing_indicator: "Claude's default aligns with your documented decisions"
|
||||||
|
|
||||||
|
# ── Maintenance: Is the file healthy over time? ──────────────────────────────
|
||||||
|
maintenance:
|
||||||
|
description: "Checks that CLAUDE.md stays accurate as the project evolves"
|
||||||
|
questions:
|
||||||
|
- id: M1
|
||||||
|
weight: 1.0
|
||||||
|
question: "Was CLAUDE.md updated in the last 90 days?"
|
||||||
|
how_to_check: "git log --format='%ar' -- CLAUDE.md | head -1"
|
||||||
|
failing_indicator: "Last update more than 90 days ago"
|
||||||
|
passing_indicator: "Updated within 90 days, or project genuinely unchanged"
|
||||||
|
|
||||||
|
- id: M2
|
||||||
|
weight: 1.0
|
||||||
|
question: "Are there no rules about deprecated technologies still in the file?"
|
||||||
|
how_to_check: "Scan for library names — are any of them removed from package.json?"
|
||||||
|
failing_indicator: "Rules referencing libraries or patterns no longer in use"
|
||||||
|
passing_indicator: "All rules apply to the current actual state of the codebase"
|
||||||
|
|
||||||
|
- id: M3
|
||||||
|
weight: 1.0
|
||||||
|
question: "Do all linked files or @imports actually exist?"
|
||||||
|
how_to_check: "Run canary-check.sh or check each @import manually"
|
||||||
|
failing_indicator: "Broken @import paths or links to non-existent docs"
|
||||||
|
passing_indicator: "All references resolve to real files"
|
||||||
|
|
||||||
|
- id: M4
|
||||||
|
weight: 1.0
|
||||||
|
question: "Have team members other than the original author contributed to or reviewed the file?"
|
||||||
|
failing_indicator: "Single author, no review, rules reflect one person's preferences"
|
||||||
|
passing_indicator: "At least one other team member has reviewed or edited"
|
||||||
|
|
||||||
|
- id: M5
|
||||||
|
weight: 1.0
|
||||||
|
question: "Is the file tracked in git with meaningful commit messages?"
|
||||||
|
how_to_check: "git log --oneline -- CLAUDE.md"
|
||||||
|
failing_indicator: "Not tracked, or all commits are 'update CLAUDE.md'"
|
||||||
|
passing_indicator: "Tracked with descriptive history (e.g., 'context: add zod validation rule')"
|
||||||
|
|
||||||
|
# ── Scoring Guide ─────────────────────────────────────────────────────────────
|
||||||
|
scoring_guide:
|
||||||
|
"18-20": "Excellent — your context is production-grade, maintain it quarterly"
|
||||||
|
"16-17": "Good — minor gaps, address the failing questions this sprint"
|
||||||
|
"13-15": "Needs work — coverage or quality issues affecting Claude's output"
|
||||||
|
"10-12": "Significant issues — likely causing frequent corrections or rework"
|
||||||
|
"0-9": "Critical — CLAUDE.md is not serving its purpose, rebuild from skeleton"
|
||||||
82
examples/context-engineering/profile-template.yaml
Normal file
82
examples/context-engineering/profile-template.yaml
Normal file
|
|
@ -0,0 +1,82 @@
|
||||||
|
# Developer Profile Template
|
||||||
|
# Customize and save as: .claude/profiles/<your-name>.yaml
|
||||||
|
# Run: ts-node assembler.ts --profile .claude/profiles/<your-name>.yaml
|
||||||
|
#
|
||||||
|
# This profile drives context assembly: it selects which shared modules to include,
|
||||||
|
# sets preferences that can be referenced by modules, and allows per-developer overrides
|
||||||
|
# without touching the shared module files.
|
||||||
|
#
|
||||||
|
# Naming convention: use lowercase, no spaces. Example: alice.yaml, bob-ml.yaml
|
||||||
|
|
||||||
|
profile:
|
||||||
|
name: "developer-name" # Used in assembled CLAUDE.md header
|
||||||
|
role: "fullstack" # frontend | backend | fullstack | devops | ml
|
||||||
|
seniority: "mid" # junior | mid | senior | staff
|
||||||
|
tools:
|
||||||
|
primary_lang: "typescript" # typescript | python | rust | go | java | kotlin
|
||||||
|
frontend: "react" # react | vue | angular | svelte | none
|
||||||
|
backend: "node" # node | fastapi | actix | gin | spring | rails
|
||||||
|
database: "postgres" # postgres | mysql | mongodb | redis | sqlite
|
||||||
|
cloud: "aws" # aws | gcp | azure | none
|
||||||
|
test_framework: "vitest" # vitest | jest | pytest | go-test | cargo-test
|
||||||
|
style:
|
||||||
|
verbosity: "concise" # verbose | concise | minimal
|
||||||
|
# verbose: include rationale in explanations, add inline comments liberally
|
||||||
|
# concise: explain when not obvious, comment only complex logic
|
||||||
|
# minimal: no unsolicited explanation, comments only on public APIs
|
||||||
|
comment_style: "inline" # none | inline | jsdoc
|
||||||
|
# none: no comments generated
|
||||||
|
# inline: short // comments on complex lines
|
||||||
|
# jsdoc: full JSDoc/docstring blocks on all public functions
|
||||||
|
test_coverage: "required" # none | optional | required
|
||||||
|
# none: no tests generated unless explicitly asked
|
||||||
|
# optional: generate tests on request or for complex logic
|
||||||
|
# required: always generate tests alongside new functions
|
||||||
|
|
||||||
|
# Modules are markdown files in .claude/modules/ that contain focused rule sets.
|
||||||
|
# The assembler concatenates them in order to build the final CLAUDE.md.
|
||||||
|
# Use subdirectories to organize by domain (e.g., frontend/, backend/, shared/).
|
||||||
|
modules:
|
||||||
|
include:
|
||||||
|
# Core — always include these
|
||||||
|
- shared/core-rules.md # General coding standards
|
||||||
|
- shared/git-conventions.md # Commit format, branch naming, PR requirements
|
||||||
|
- shared/security-rules.md # Input validation, secret handling, dependency policy
|
||||||
|
|
||||||
|
# Role-specific — uncomment what applies
|
||||||
|
# Frontend
|
||||||
|
# - frontend/react-patterns.md # Component structure, hooks, state management
|
||||||
|
# - frontend/accessibility.md # WCAG requirements, ARIA patterns
|
||||||
|
# - frontend/css-conventions.md # CSS modules, utility classes, design tokens
|
||||||
|
|
||||||
|
# Backend
|
||||||
|
# - backend/api-design.md # REST conventions, error formats, versioning
|
||||||
|
# - backend/database-patterns.md # Query patterns, migrations, indexing
|
||||||
|
# - backend/auth-patterns.md # JWT, OAuth, session management
|
||||||
|
|
||||||
|
# DevOps
|
||||||
|
# - devops/ci-cd.md # Pipeline conventions, deployment gates
|
||||||
|
# - devops/docker-patterns.md # Dockerfile standards, compose conventions
|
||||||
|
# - devops/observability.md # Logging format, metric naming, tracing
|
||||||
|
|
||||||
|
# ML
|
||||||
|
# - ml/model-evaluation.md # Evaluation methodology, bias checks
|
||||||
|
# - ml/experiment-tracking.md # MLflow/W&B conventions, artifact naming
|
||||||
|
# - ml/data-pipeline.md # Data validation, transformation patterns
|
||||||
|
|
||||||
|
exclude:
|
||||||
|
[]
|
||||||
|
# Explicitly exclude modules from the base set (e.g., if shared/security-rules.md
|
||||||
|
# has a section that conflicts with your team's approach):
|
||||||
|
# - shared/security-rules.md
|
||||||
|
|
||||||
|
overrides:
|
||||||
|
# Per-developer additions — appended after all modules as a "Personal Rules" section.
|
||||||
|
# Keep these minimal: shared knowledge belongs in shared modules, not personal overrides.
|
||||||
|
# Good use cases: personal debugging preferences, tooling shortcuts, IDE-specific notes.
|
||||||
|
custom_rules:
|
||||||
|
[]
|
||||||
|
# Examples:
|
||||||
|
# - "Always run `pnpm typecheck` before declaring a TypeScript task complete"
|
||||||
|
# - "Use zod for all external input validation, not manual type guards"
|
||||||
|
# - "When unsure about a regex, use a named capture group and add a comment"
|
||||||
93
examples/context-engineering/rules/knowledge-feeding.md
Normal file
93
examples/context-engineering/rules/knowledge-feeding.md
Normal file
|
|
@ -0,0 +1,93 @@
|
||||||
|
# Knowledge Feeding Protocol
|
||||||
|
|
||||||
|
Context engineering is not a one-time setup — it accumulates value over time as Claude learns what works for your project. This file defines when and how to capture that learning back into your `CLAUDE.md`.
|
||||||
|
|
||||||
|
## When to Feed Knowledge
|
||||||
|
|
||||||
|
Run this protocol at the end of any session that:
|
||||||
|
|
||||||
|
- Completed a feature or meaningful code change
|
||||||
|
- Discovered a new pattern that worked well and should become standard
|
||||||
|
- Hit a mistake that required correction (especially if the mistake was repeated)
|
||||||
|
- Made an architectural decision that will affect future work
|
||||||
|
- Established a preference for a library, tool, or approach
|
||||||
|
|
||||||
|
Skip it for trivial sessions (typo fixes, doc edits, minor config changes).
|
||||||
|
|
||||||
|
## The Knowledge Feed Prompt
|
||||||
|
|
||||||
|
Paste this into Claude at the end of qualifying sessions:
|
||||||
|
|
||||||
|
```
|
||||||
|
Before we close this session, run a knowledge feed:
|
||||||
|
|
||||||
|
1. What patterns did we establish that should become permanent rules?
|
||||||
|
2. What did I correct or redirect that should be a rule to prevent recurrence?
|
||||||
|
3. Were any architectural decisions made that CLAUDE.md should record?
|
||||||
|
4. Is there anything in CLAUDE.md that this session proved wrong or outdated?
|
||||||
|
|
||||||
|
Output only high-signal items (3-5 max). Use the knowledge feed format below.
|
||||||
|
Skip anything obvious or already covered.
|
||||||
|
```
|
||||||
|
|
||||||
|
## Knowledge Feed Output Format
|
||||||
|
|
||||||
|
Claude should output discoveries in this structure:
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
## Knowledge Feed — [YYYY-MM-DD]
|
||||||
|
|
||||||
|
### New Pattern (if applicable)
|
||||||
|
**What**: [One sentence describing the pattern]
|
||||||
|
**Why**: [Why this is the right approach for this project]
|
||||||
|
**Rule to add**:
|
||||||
|
> [Exact text to paste into CLAUDE.md, ready to copy]
|
||||||
|
|
||||||
|
### Anti-Pattern Found (if applicable)
|
||||||
|
**What happened**: [What Claude did wrong or what was corrected]
|
||||||
|
**Why it's wrong here**: [Project-specific reason, not generic best practice]
|
||||||
|
**Rule to add**:
|
||||||
|
> Never: [specific behavior to avoid and why]
|
||||||
|
|
||||||
|
### Architecture Decision (if applicable)
|
||||||
|
**Decision**: [What was decided]
|
||||||
|
**Rationale**: [Why — especially if it goes against common practice]
|
||||||
|
**Rule to add**:
|
||||||
|
> [Exact text to paste into CLAUDE.md]
|
||||||
|
|
||||||
|
### Stale Rule to Remove (if applicable)
|
||||||
|
**Rule**: [Current rule in CLAUDE.md]
|
||||||
|
**Why remove**: [What changed that makes this obsolete]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Integration Workflow
|
||||||
|
|
||||||
|
After receiving the knowledge feed:
|
||||||
|
|
||||||
|
1. **Review before adding** — not all patterns generalize. Ask: "Would a new team member need to know this, or is it context-specific to this session?"
|
||||||
|
2. **Copy relevant rules** into the appropriate section of `CLAUDE.md`
|
||||||
|
3. **Remove any rules** Claude flagged as stale
|
||||||
|
4. **Commit the update** with a meaningful message:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add CLAUDE.md
|
||||||
|
git commit -m "context: [short description of what was learned]"
|
||||||
|
|
||||||
|
# Examples:
|
||||||
|
# context: add zod validation rule after form refactor
|
||||||
|
# context: remove Redux rule — migrated to Zustand
|
||||||
|
# context: document payment webhook idempotency pattern
|
||||||
|
```
|
||||||
|
|
||||||
|
## Quality Filter
|
||||||
|
|
||||||
|
Before adding any rule to `CLAUDE.md`, check:
|
||||||
|
|
||||||
|
- **Is it specific to this project?** Generic best practices don't belong here — Claude already knows them.
|
||||||
|
- **Is it actionable?** "Be careful with async code" is useless. "Always check for race conditions in the order state machine" is useful.
|
||||||
|
- **Is it already covered?** Search for similar rules before adding. Duplicates dilute adherence.
|
||||||
|
- **Will it still be true in 6 months?** Avoid rules tied to temporary states ("we're migrating to X so don't use Y yet").
|
||||||
|
|
||||||
|
## Ownership
|
||||||
|
|
||||||
|
Knowledge feeding works best when it's a team habit, not one person's job. Any team member who works with Claude can contribute a knowledge feed. The person who reviews the PR for `CLAUDE.md` changes is responsible for quality filtering.
|
||||||
108
examples/context-engineering/rules/update-loop-retro.md
Normal file
108
examples/context-engineering/rules/update-loop-retro.md
Normal file
|
|
@ -0,0 +1,108 @@
|
||||||
|
# Session Retrospective Template
|
||||||
|
|
||||||
|
A structured prompt to run at the end of Claude Code sessions. The goal is to capture
|
||||||
|
knowledge while it's fresh and turn it into durable rules — keeping your `CLAUDE.md`
|
||||||
|
accurate as the project evolves.
|
||||||
|
|
||||||
|
## The Prompt
|
||||||
|
|
||||||
|
Copy this and paste it into Claude at the end of a session:
|
||||||
|
|
||||||
|
```
|
||||||
|
Session complete. Before we close, run a quick retrospective:
|
||||||
|
|
||||||
|
1. What patterns did we establish that should be permanent rules in CLAUDE.md?
|
||||||
|
2. What did I correct that Claude got wrong? Should a rule prevent that?
|
||||||
|
3. What worked well that we should replicate in future sessions?
|
||||||
|
4. Were any architectural decisions made that CLAUDE.md should record?
|
||||||
|
5. Is there anything currently in CLAUDE.md that this session proved wrong or outdated?
|
||||||
|
|
||||||
|
Output a knowledge feed — 3 to 5 bullets max, high-signal items only.
|
||||||
|
Skip anything obvious, generic, or already in CLAUDE.md.
|
||||||
|
Format each item as an actionable rule ready to copy in.
|
||||||
|
```
|
||||||
|
|
||||||
|
## When to Run It
|
||||||
|
|
||||||
|
| Trigger | Run retro? |
|
||||||
|
|---------|-----------|
|
||||||
|
| Feature or major refactor completed | Yes |
|
||||||
|
| Debugging session that uncovered a systemic gap | Yes |
|
||||||
|
| Architectural decision made | Yes |
|
||||||
|
| Onboarding session where someone flagged missing context | Yes |
|
||||||
|
| Monthly, even if nothing major happened | Yes — catches accumulation |
|
||||||
|
| Trivial session (typo fix, doc edit) | No |
|
||||||
|
|
||||||
|
Monthly is the minimum cadence even for quiet projects. Small drifts accumulate silently.
|
||||||
|
|
||||||
|
## What Good Output Looks Like
|
||||||
|
|
||||||
|
Claude should return something like this (not verbatim — but this level of specificity):
|
||||||
|
|
||||||
|
```
|
||||||
|
Knowledge Feed — 2025-09-15
|
||||||
|
|
||||||
|
1. Pattern established: All database queries go through the repository layer, never called
|
||||||
|
directly from route handlers. Rule to add: "Never call Prisma directly from route
|
||||||
|
handlers — use the repository functions in src/db/."
|
||||||
|
|
||||||
|
2. Correction: I suggested lodash for array manipulation. You redirected to native array
|
||||||
|
methods. Rule to add: "Don't import lodash — use native JS array methods. The bundle
|
||||||
|
cost isn't worth it for our use case."
|
||||||
|
|
||||||
|
3. Architecture decision: We decided to keep auth logic in middleware, not in individual
|
||||||
|
route handlers. Rule to add: "Auth checks belong in src/middleware/auth.ts — not in
|
||||||
|
route handlers. If a route needs special auth logic, extend the middleware."
|
||||||
|
|
||||||
|
4. Stale rule: CLAUDE.md still references the old Express v4 error handler signature.
|
||||||
|
We're on v5. Remove: "Express error handlers take 4 arguments (err, req, res, next)."
|
||||||
|
Update to: "Express v5 error handlers: async errors propagate automatically — no need
|
||||||
|
to call next(err)."
|
||||||
|
```
|
||||||
|
|
||||||
|
## After the Retro
|
||||||
|
|
||||||
|
### Review the output
|
||||||
|
|
||||||
|
Not everything Claude surfaces belongs in `CLAUDE.md`. Ask:
|
||||||
|
|
||||||
|
- Is this specific to our project, or generic advice Claude already knows?
|
||||||
|
- Is it actionable? Would a new Claude session make the same mistake without this rule?
|
||||||
|
- Is it already covered? Search before adding — duplicates reduce adherence.
|
||||||
|
|
||||||
|
### Update CLAUDE.md
|
||||||
|
|
||||||
|
Add new rules to the most relevant section. Remove any stale rules Claude flagged.
|
||||||
|
|
||||||
|
### Commit with a traceable message
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add CLAUDE.md
|
||||||
|
git commit -m "context: [what changed and why]"
|
||||||
|
```
|
||||||
|
|
||||||
|
Meaningful commit messages create a traceable history of how your AI context evolved. Useful
|
||||||
|
for debugging: "Claude started doing X wrong after we made change Y" becomes diagnosable
|
||||||
|
from git log.
|
||||||
|
|
||||||
|
Examples of good commit messages:
|
||||||
|
|
||||||
|
```
|
||||||
|
context: add lodash ban — use native array methods
|
||||||
|
context: clarify auth middleware pattern after refactor
|
||||||
|
context: remove Express v4 error handler rule — now on v5
|
||||||
|
context: document payment webhook idempotency requirement
|
||||||
|
context: add Prisma-direct query ban after code review
|
||||||
|
```
|
||||||
|
|
||||||
|
## Team Usage
|
||||||
|
|
||||||
|
When multiple people work with Claude on the same project, retros become especially valuable.
|
||||||
|
Each developer may get different corrections — different gaps in `CLAUDE.md` surface from
|
||||||
|
different angles. Consider:
|
||||||
|
|
||||||
|
- Running a retro at the end of any PR that involved significant Claude-assisted work
|
||||||
|
- Including `CLAUDE.md` in PR reviews as a standing agenda item
|
||||||
|
- Doing a quarterly joint retro with the whole team to review accumulated changes
|
||||||
|
|
||||||
|
The `CLAUDE.md` file is a shared asset. Its quality reflects how well the team maintains it.
|
||||||
288
examples/context-engineering/skeleton-template.md
Normal file
288
examples/context-engineering/skeleton-template.md
Normal file
|
|
@ -0,0 +1,288 @@
|
||||||
|
# CLAUDE.md — [Project Name]
|
||||||
|
|
||||||
|
<!--
|
||||||
|
HOW TO USE THIS SKELETON
|
||||||
|
|
||||||
|
Fill in each section based on your project. Delete placeholder comments when done.
|
||||||
|
Goal: give Claude enough context to make correct decisions without asking, while staying under 500 lines.
|
||||||
|
|
||||||
|
Key principles:
|
||||||
|
- Specific beats vague: "Use zod for external input validation" beats "validate inputs"
|
||||||
|
- Anti-patterns are as valuable as rules: tell Claude what NOT to do
|
||||||
|
- Update after each significant session (see rules/update-loop-retro.md)
|
||||||
|
- Run `canary-check.sh` weekly to catch drift
|
||||||
|
-->
|
||||||
|
|
||||||
|
## Project Overview
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Write 2-3 sentences answering:
|
||||||
|
- What does this project do?
|
||||||
|
- Who uses it? (internal tool, public API, consumer app, etc.)
|
||||||
|
- What's the primary language and deployment target?
|
||||||
|
|
||||||
|
Example:
|
||||||
|
"A REST API that processes financial transactions for retail merchants, consumed by a Next.js
|
||||||
|
dashboard and a React Native mobile app. Built with Node.js + TypeScript, deployed to AWS ECS.
|
||||||
|
PCI-DSS compliance applies to all payment-adjacent code."
|
||||||
|
-->
|
||||||
|
|
||||||
|
[PROJECT DESCRIPTION]
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Describe the shape of the system. Not a tutorial — just the decisions Claude needs to
|
||||||
|
make correct assumptions. Diagrams are optional; prose is fine.
|
||||||
|
|
||||||
|
Cover:
|
||||||
|
- Monolith or services? If services, how many and how do they communicate?
|
||||||
|
- How is state managed (database, cache, event sourcing)?
|
||||||
|
- Key data flow (request lifecycle, async patterns)
|
||||||
|
- Folder structure if non-obvious
|
||||||
|
-->
|
||||||
|
|
||||||
|
### Stack
|
||||||
|
|
||||||
|
| Layer | Technology | Version |
|
||||||
|
|-------|-----------|---------|
|
||||||
|
| Language | TypeScript | 5.x |
|
||||||
|
| Runtime | Node.js | 20.x |
|
||||||
|
| Framework | [e.g., Express, Fastify, NestJS] | x.x |
|
||||||
|
| Database | [e.g., PostgreSQL] | x.x |
|
||||||
|
| ORM / Query Builder | [e.g., Prisma, Drizzle, Knex] | x.x |
|
||||||
|
| Cache | [e.g., Redis, none] | - |
|
||||||
|
| Message Queue | [e.g., BullMQ, SQS, none] | - |
|
||||||
|
| Frontend | [e.g., Next.js, none] | x.x |
|
||||||
|
| Testing | [e.g., Vitest, Jest] | x.x |
|
||||||
|
| CI/CD | [e.g., GitHub Actions] | - |
|
||||||
|
|
||||||
|
### Folder Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
src/
|
||||||
|
[describe key directories and what belongs in each]
|
||||||
|
[example: api/ — route handlers only, no business logic]
|
||||||
|
[example: services/ — business logic, called by handlers]
|
||||||
|
[example: db/ — Prisma schema, migrations, query functions]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Key Architectural Decisions
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Record the "why" behind non-obvious choices. This prevents Claude from suggesting
|
||||||
|
alternatives that were already considered and rejected.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
- Repository pattern is NOT used — we use Prisma directly in services (decision: team
|
||||||
|
familiarity, added abstraction not worth it at current scale)
|
||||||
|
- Zod schemas are colocated with route handlers, not in a shared schemas/ directory
|
||||||
|
-->
|
||||||
|
|
||||||
|
- [DECISION 1]
|
||||||
|
- [DECISION 2]
|
||||||
|
|
||||||
|
## Code Standards
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Be specific. "Write clean code" is useless. "Use named exports only — no default exports" is actionable.
|
||||||
|
Organize by language/domain if you have multiple.
|
||||||
|
-->
|
||||||
|
|
||||||
|
### TypeScript
|
||||||
|
|
||||||
|
- Strict mode is enabled (`"strict": true` in tsconfig). Never use `any` — use `unknown` and narrow.
|
||||||
|
- All public function signatures must have explicit return types.
|
||||||
|
- Use `type` for unions and intersections, `interface` for object shapes that may be extended.
|
||||||
|
- [ADD YOUR RULES]
|
||||||
|
|
||||||
|
### Naming
|
||||||
|
|
||||||
|
- Files: `kebab-case.ts` (e.g., `user-service.ts`, `create-order.test.ts`)
|
||||||
|
- Classes: `PascalCase`
|
||||||
|
- Functions and variables: `camelCase`
|
||||||
|
- Constants: `SCREAMING_SNAKE_CASE`
|
||||||
|
- [ADD ANY EXCEPTIONS]
|
||||||
|
|
||||||
|
### Error Handling
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Undefined behavior here causes the most inconsistency. Be explicit.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
- All async functions must be wrapped in try/catch at the handler boundary
|
||||||
|
- Errors propagate up as typed error objects, never raw strings
|
||||||
|
- Use the AppError class in src/errors.ts — never throw plain Error objects in service layer
|
||||||
|
-->
|
||||||
|
|
||||||
|
- [ERROR HANDLING RULES]
|
||||||
|
|
||||||
|
### Comments
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Example:
|
||||||
|
- Inline comments only on non-obvious logic (never explain what the code does, only why)
|
||||||
|
- All exported functions must have a JSDoc block with @param and @returns
|
||||||
|
- TODO comments are not allowed in production code — open an issue instead
|
||||||
|
-->
|
||||||
|
|
||||||
|
- [COMMENT RULES]
|
||||||
|
|
||||||
|
## Development Workflow
|
||||||
|
|
||||||
|
### Git Conventions
|
||||||
|
|
||||||
|
- Branch naming: `[type]/[short-description]` — e.g., `feat/add-refund-flow`, `fix/order-status-race`
|
||||||
|
- Commit format: [Conventional Commits](https://www.conventionalcommits.org/)
|
||||||
|
- `feat:` new feature
|
||||||
|
- `fix:` bug fix
|
||||||
|
- `chore:` maintenance, dependency updates
|
||||||
|
- `docs:` documentation only
|
||||||
|
- `test:` tests only
|
||||||
|
- `refactor:` no behavior change
|
||||||
|
- Commits should be atomic — one logical change per commit
|
||||||
|
- [ADD ANY EXCEPTIONS OR ADDITIONAL TYPES]
|
||||||
|
|
||||||
|
### PR Requirements
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Example:
|
||||||
|
- All PRs require at least one reviewer
|
||||||
|
- CI must be green before merge
|
||||||
|
- PR description must include "Why" not just "What"
|
||||||
|
- Link to issue or ticket in PR body
|
||||||
|
-->
|
||||||
|
|
||||||
|
- [PR RULES]
|
||||||
|
|
||||||
|
### Local Setup
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install dependencies
|
||||||
|
[INSTALL COMMAND]
|
||||||
|
|
||||||
|
# Set up environment
|
||||||
|
cp .env.example .env
|
||||||
|
# Edit .env with your local values
|
||||||
|
|
||||||
|
# Run database migrations
|
||||||
|
[MIGRATION COMMAND]
|
||||||
|
|
||||||
|
# Start development server
|
||||||
|
[DEV COMMAND]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Vague testing rules produce no tests. Specific rules produce correct tests.
|
||||||
|
Tell Claude: what framework, what to test, how to structure tests, what coverage means here.
|
||||||
|
-->
|
||||||
|
|
||||||
|
### Framework and Location
|
||||||
|
|
||||||
|
- Framework: [e.g., Vitest]
|
||||||
|
- Test files: colocated with source (`foo.ts` → `foo.test.ts`) OR in `__tests__/` [choose one]
|
||||||
|
- Run tests: `[TEST COMMAND]`
|
||||||
|
- Run with coverage: `[COVERAGE COMMAND]`
|
||||||
|
|
||||||
|
### What Requires Tests
|
||||||
|
|
||||||
|
- All service layer functions (unit tests with mocked dependencies)
|
||||||
|
- All API routes (integration tests using supertest or equivalent)
|
||||||
|
- All utility functions that contain branching logic
|
||||||
|
- **Not required**: pure pass-through functions, simple getters/setters, Prisma model definitions
|
||||||
|
|
||||||
|
### Test Structure
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// Follow this pattern:
|
||||||
|
describe('[unit under test]', () => {
|
||||||
|
describe('[method or scenario]', () => {
|
||||||
|
it('[expected behavior in plain English]', async () => {
|
||||||
|
// Arrange
|
||||||
|
// Act
|
||||||
|
// Assert
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
### Mocking
|
||||||
|
|
||||||
|
- Mock at the boundary: mock external services, never internal modules
|
||||||
|
- [ADD YOUR MOCKING CONVENTIONS — e.g., "Use vi.mock() at file level, not inside tests"]
|
||||||
|
|
||||||
|
## Deployment
|
||||||
|
|
||||||
|
### Environments
|
||||||
|
|
||||||
|
| Environment | Branch | URL | Notes |
|
||||||
|
|------------|--------|-----|-------|
|
||||||
|
| Local | any | localhost:[PORT] | |
|
||||||
|
| Staging | `main` | [STAGING URL] | Auto-deploys |
|
||||||
|
| Production | [TAG/BRANCH] | [PROD URL] | Manual trigger |
|
||||||
|
|
||||||
|
### Deploy
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Staging (auto on merge to main — no manual step needed)
|
||||||
|
|
||||||
|
# Production
|
||||||
|
[DEPLOY COMMAND OR PROCESS]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Post-Deploy Checks
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Tell Claude what to verify after deploying so it can suggest this when relevant.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
- Check /health endpoint returns 200
|
||||||
|
- Verify Sentry has no new errors in first 5 minutes
|
||||||
|
- Confirm database migrations ran (check migration table)
|
||||||
|
-->
|
||||||
|
|
||||||
|
- [POST-DEPLOY CHECKS]
|
||||||
|
|
||||||
|
## What Claude Should NOT Do
|
||||||
|
|
||||||
|
<!--
|
||||||
|
This section is high-value. Anti-patterns prevent regressions and stop Claude from
|
||||||
|
suggesting alternatives that were already rejected.
|
||||||
|
|
||||||
|
Be specific about the pattern AND why it's banned.
|
||||||
|
-->
|
||||||
|
|
||||||
|
### Technologies Not in Use
|
||||||
|
|
||||||
|
- Do NOT suggest GraphQL — REST is the architectural decision for this project
|
||||||
|
- Do NOT use [LIBRARY NAME] — replaced by [ALTERNATIVE] in [VERSION/DATE]
|
||||||
|
- [ADD YOUR BANNED TECHNOLOGIES]
|
||||||
|
|
||||||
|
### Patterns to Avoid
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Example:
|
||||||
|
- Never use class components in React — functional components only
|
||||||
|
- Never mutate request/response objects directly — use immutable patterns
|
||||||
|
- Never use console.log in production code — use the logger at src/lib/logger.ts
|
||||||
|
- Never hardcode environment-specific values — use process.env with validation in src/config.ts
|
||||||
|
-->
|
||||||
|
|
||||||
|
- [ANTI-PATTERN 1]
|
||||||
|
- [ANTI-PATTERN 2]
|
||||||
|
- [ANTI-PATTERN 3]
|
||||||
|
|
||||||
|
### Known Problem Areas
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Patterns that caused production bugs or significant rework. Claude should be extra careful here.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
- The order state machine in src/orders/state.ts is complex — always read it fully before modifying
|
||||||
|
- Payment webhooks are idempotent — every handler must check for duplicate event IDs
|
||||||
|
-->
|
||||||
|
|
||||||
|
- [KNOWN PROBLEM AREA 1]
|
||||||
|
- [KNOWN PROBLEM AREA 2]
|
||||||
|
|
@ -21,6 +21,7 @@ Core documentation for mastering Claude Code, organized by topic.
|
||||||
| [core/visual-reference.md](./core/visual-reference.md) | Visual cheatsheet — ASCII diagrams for key concepts | 5 min |
|
| [core/visual-reference.md](./core/visual-reference.md) | Visual cheatsheet — ASCII diagrams for key concepts | 5 min |
|
||||||
| [core/claude-code-releases.md](./core/claude-code-releases.md) | Official release history (condensed) | 10 min |
|
| [core/claude-code-releases.md](./core/claude-code-releases.md) | Official release history (condensed) | 10 min |
|
||||||
| [core/known-issues.md](./core/known-issues.md) | **Critical bugs tracker**: security issues, token consumption, verified community reports | 15 min |
|
| [core/known-issues.md](./core/known-issues.md) | **Critical bugs tracker**: security issues, token consumption, verified community reports | 15 min |
|
||||||
|
| [core/context-engineering.md](./core/context-engineering.md) | **Context Engineering**: token budget, modular architecture, team assembly, ACE pipeline, quality measurement | 25 min |
|
||||||
| [diagrams/](./diagrams/) | **Visual Diagrams Series**: 41 Mermaid interactive diagrams for model selection, agent lifecycle, security, multi-agent patterns | 15 min |
|
| [diagrams/](./diagrams/) | **Visual Diagrams Series**: 41 Mermaid interactive diagrams for model selection, agent lifecycle, security, multi-agent patterns | 15 min |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ tags: [cheatsheet, reference]
|
||||||
|
|
||||||
**Written with**: Claude (Anthropic)
|
**Written with**: Claude (Anthropic)
|
||||||
|
|
||||||
**Version**: 3.33.1 | **Last Updated**: February 2026
|
**Version**: 3.34.0 | **Last Updated**: February 2026
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -638,4 +638,4 @@ Speed: `rg` (~20ms) → Serena (~100ms) → ast-grep (~200ms) → grepai (~500ms
|
||||||
|
|
||||||
**Author**: Florian BRUNIAUX | [@Méthode Aristote](https://methode-aristote.fr) | Written with Claude
|
**Author**: Florian BRUNIAUX | [@Méthode Aristote](https://methode-aristote.fr) | Written with Claude
|
||||||
|
|
||||||
*Last updated: February 2026 | Version 3.33.1*
|
*Last updated: February 2026 | Version 3.34.0*
|
||||||
|
|
|
||||||
1188
guide/core/context-engineering.md
Normal file
1188
guide/core/context-engineering.md
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -16,7 +16,7 @@ tags: [guide, reference, workflows, agents, hooks, mcp, security]
|
||||||
|
|
||||||
**Last updated**: January 2026
|
**Last updated**: January 2026
|
||||||
|
|
||||||
**Version**: 3.33.1
|
**Version**: 3.34.0
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
@ -5034,7 +5034,7 @@ The `.claude/` folder is your project's Claude Code directory for memory, settin
|
||||||
| Personal preferences | `CLAUDE.md` | ❌ Gitignore |
|
| Personal preferences | `CLAUDE.md` | ❌ Gitignore |
|
||||||
| Personal permissions | `settings.local.json` | ❌ Gitignore |
|
| Personal permissions | `settings.local.json` | ❌ Gitignore |
|
||||||
|
|
||||||
### 3.33.1 Version Control & Backup
|
### 3.34.0 Version Control & Backup
|
||||||
|
|
||||||
**Problem**: Without version control, losing your Claude Code configuration means hours of manual reconfiguration across agents, skills, hooks, and MCP servers.
|
**Problem**: Without version control, losing your Claude Code configuration means hours of manual reconfiguration across agents, skills, hooks, and MCP servers.
|
||||||
|
|
||||||
|
|
@ -22866,4 +22866,4 @@ We'll evaluate and add it to this section if it meets quality criteria.
|
||||||
|
|
||||||
**Contributions**: Issues and PRs welcome.
|
**Contributions**: Issues and PRs welcome.
|
||||||
|
|
||||||
**Last updated**: January 2026 | **Version**: 3.33.1
|
**Last updated**: January 2026 | **Version**: 3.34.0
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
# Source: guide/ultimate-guide.md
|
# Source: guide/ultimate-guide.md
|
||||||
# Purpose: Condensed index for LLMs to quickly answer user questions about Claude Code
|
# Purpose: Condensed index for LLMs to quickly answer user questions about Claude Code
|
||||||
|
|
||||||
version: "3.33.1"
|
version: "3.34.0"
|
||||||
updated: "2026-03-03"
|
updated: "2026-03-03"
|
||||||
|
|
||||||
# ════════════════════════════════════════════════════════════════
|
# ════════════════════════════════════════════════════════════════
|
||||||
|
|
@ -58,6 +58,30 @@ deep_dive:
|
||||||
deployment_automation: "guide/ultimate-guide.md:13172" # Pattern #10: Vercel + Infisical guardrails
|
deployment_automation: "guide/ultimate-guide.md:13172" # Pattern #10: Vercel + Infisical guardrails
|
||||||
iterative_refinement_community: "guide/workflows/iterative-refinement.md:515" # Pattern #7: Ralph Loop + Auto-Continue
|
iterative_refinement_community: "guide/workflows/iterative-refinement.md:515" # Pattern #7: Ralph Loop + Auto-Continue
|
||||||
agent_teams_large_justified: "guide/workflows/agent-teams.md:120" # Pattern #4: when >5 agents are justified
|
agent_teams_large_justified: "guide/workflows/agent-teams.md:120" # Pattern #4: when >5 agents are justified
|
||||||
|
# Context Engineering (consolidated reference)
|
||||||
|
context_engineering_guide: "guide/core/context-engineering.md"
|
||||||
|
context_engineering_what_is: "guide/core/context-engineering.md#1-what-is-context-engineering"
|
||||||
|
context_engineering_budget: "guide/core/context-engineering.md#2-the-context-budget"
|
||||||
|
context_engineering_hierarchy: "guide/core/context-engineering.md#3-configuration-hierarchy"
|
||||||
|
context_engineering_modular: "guide/core/context-engineering.md#4-modular-architecture"
|
||||||
|
context_engineering_team: "guide/core/context-engineering.md#5-team-assembly"
|
||||||
|
context_engineering_lifecycle: "guide/core/context-engineering.md#6-context-lifecycle"
|
||||||
|
context_engineering_quality: "guide/core/context-engineering.md#7-quality-measurement"
|
||||||
|
context_engineering_reduction: "guide/core/context-engineering.md#8-context-reduction-techniques"
|
||||||
|
context_engineering_audit_tool: "tools/context-audit-prompt.md"
|
||||||
|
context_engineering_examples: "examples/context-engineering/"
|
||||||
|
context_engineering_assembler: "examples/context-engineering/assembler.ts"
|
||||||
|
context_engineering_profile_template: "examples/context-engineering/profile-template.yaml"
|
||||||
|
context_engineering_skeleton: "examples/context-engineering/skeleton-template.md"
|
||||||
|
context_engineering_canary: "examples/context-engineering/canary-check.sh"
|
||||||
|
context_engineering_ci_drift: "examples/context-engineering/ci-drift-check.yml"
|
||||||
|
context_engineering_budget_calc: "examples/context-engineering/context-budget-calculator.sh"
|
||||||
|
context_engineering_eval_questions: "examples/context-engineering/eval-questions.yaml"
|
||||||
|
context_engineering_landing: "https://cc.bruniaux.com/context/"
|
||||||
|
context_150_ceiling: "guide/core/context-engineering.md#2-the-context-budget"
|
||||||
|
context_ace_pipeline: "guide/core/context-engineering.md#6-context-lifecycle"
|
||||||
|
context_path_scoping: "guide/core/context-engineering.md#4-modular-architecture"
|
||||||
|
context_maturity_model: "guide/core/context-engineering.md#7-quality-measurement"
|
||||||
# Team Configuration at Scale (Profile-Based Module Assembly)
|
# Team Configuration at Scale (Profile-Based Module Assembly)
|
||||||
team_ai_instructions_section: "guide/ultimate-guide.md#35-team-configuration-at-scale"
|
team_ai_instructions_section: "guide/ultimate-guide.md#35-team-configuration-at-scale"
|
||||||
team_ai_instructions_workflow: "guide/workflows/team-ai-instructions.md"
|
team_ai_instructions_workflow: "guide/workflows/team-ai-instructions.md"
|
||||||
|
|
@ -1510,7 +1534,7 @@ ecosystem:
|
||||||
- "Cross-links modified → Update all 4 repos"
|
- "Cross-links modified → Update all 4 repos"
|
||||||
history:
|
history:
|
||||||
- date: "2026-01-20"
|
- date: "2026-01-20"
|
||||||
event: "Code Landing sync v3.33.1, 66 templates, cross-links"
|
event: "Code Landing sync v3.34.0, 66 templates, cross-links"
|
||||||
commit: "5b5ce62"
|
commit: "5b5ce62"
|
||||||
- date: "2026-01-20"
|
- date: "2026-01-20"
|
||||||
event: "Cowork Landing fix (paths, README, UI badges)"
|
event: "Cowork Landing fix (paths, README, UI badges)"
|
||||||
|
|
@ -1522,7 +1546,7 @@ ecosystem:
|
||||||
onboarding_matrix_meta:
|
onboarding_matrix_meta:
|
||||||
version: "2.1.0"
|
version: "2.1.0"
|
||||||
last_updated: "2026-03-09"
|
last_updated: "2026-03-09"
|
||||||
aligned_with_guide: "3.33.1"
|
aligned_with_guide: "3.34.0"
|
||||||
changelog:
|
changelog:
|
||||||
- version: "2.1.0"
|
- version: "2.1.0"
|
||||||
date: "2026-03-09"
|
date: "2026-03-09"
|
||||||
|
|
@ -1553,7 +1577,7 @@ onboarding_matrix:
|
||||||
core: [rules, sandbox_native_guide, commands]
|
core: [rules, sandbox_native_guide, commands]
|
||||||
time_budget: "5 min"
|
time_budget: "5 min"
|
||||||
topics_max: 3
|
topics_max: 3
|
||||||
note: "SECURITY FIRST - sandbox before commands (v3.33.1 critical fix)"
|
note: "SECURITY FIRST - sandbox before commands (v3.34.0 critical fix)"
|
||||||
|
|
||||||
beginner_15min:
|
beginner_15min:
|
||||||
core: [rules, sandbox_native_guide, workflow, essential_commands]
|
core: [rules, sandbox_native_guide, workflow, essential_commands]
|
||||||
|
|
@ -1642,7 +1666,7 @@ onboarding_matrix:
|
||||||
- default: agent_validation_checklist
|
- default: agent_validation_checklist
|
||||||
time_budget: "60 min"
|
time_budget: "60 min"
|
||||||
topics_max: 6
|
topics_max: 6
|
||||||
note: "Dual-instance pattern for quality workflows (v3.33.1)"
|
note: "Dual-instance pattern for quality workflows (v3.34.0)"
|
||||||
|
|
||||||
learn_security:
|
learn_security:
|
||||||
intermediate_30min:
|
intermediate_30min:
|
||||||
|
|
@ -1653,7 +1677,7 @@ onboarding_matrix:
|
||||||
- default: permission_modes
|
- default: permission_modes
|
||||||
time_budget: "30 min"
|
time_budget: "30 min"
|
||||||
topics_max: 4
|
topics_max: 4
|
||||||
note: "NEW goal (v3.33.1) - Security-focused learning path"
|
note: "NEW goal (v3.34.0) - Security-focused learning path"
|
||||||
|
|
||||||
power_60min:
|
power_60min:
|
||||||
core: [sandbox_native_guide, mcp_secrets_management, security_hardening]
|
core: [sandbox_native_guide, mcp_secrets_management, security_hardening]
|
||||||
|
|
@ -1678,7 +1702,7 @@ onboarding_matrix:
|
||||||
core: [rules, sandbox_native_guide, workflow, essential_commands, context_management, plan_mode]
|
core: [rules, sandbox_native_guide, workflow, essential_commands, context_management, plan_mode]
|
||||||
time_budget: "60 min"
|
time_budget: "60 min"
|
||||||
topics_max: 6
|
topics_max: 6
|
||||||
note: "Security foundation + core workflow (v3.33.1 sandbox added)"
|
note: "Security foundation + core workflow (v3.34.0 sandbox added)"
|
||||||
|
|
||||||
intermediate_120min:
|
intermediate_120min:
|
||||||
core: [plan_mode, agents, skills, config_hierarchy, git_mcp_guide, hooks, mcp_servers]
|
core: [plan_mode, agents, skills, config_hierarchy, git_mcp_guide, hooks, mcp_servers]
|
||||||
|
|
|
||||||
543
tools/context-audit-prompt.md
Normal file
543
tools/context-audit-prompt.md
Normal file
|
|
@ -0,0 +1,543 @@
|
||||||
|
# Audit Your Context Engineering Setup
|
||||||
|
|
||||||
|
> A self-contained prompt to measure and improve your Claude Code context architecture.
|
||||||
|
|
||||||
|
**Author**: [Florian BRUNIAUX](https://github.com/FlorianBruniaux) | Founding Engineer [@Méthode Aristote](https://methode-aristote.fr)
|
||||||
|
|
||||||
|
**Reference**: [The Ultimate Claude Code Guide](https://github.com/FlorianBruniaux/claude-code-ultimate-guide/blob/main/guide/ultimate-guide.md)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. What This Does
|
||||||
|
|
||||||
|
This prompt instructs Claude to audit your context engineering setup by:
|
||||||
|
|
||||||
|
1. **Measuring** total always-on context size, CLAUDE.md length, and path-scoping ratio
|
||||||
|
2. **Detecting** skills-to-rules balance, redundancy, and negative vs positive instructions
|
||||||
|
3. **Flagging** staleness signals (last updated, broken imports, deprecated references)
|
||||||
|
4. **Scoring** across 8 dimensions for a total of /100 with prioritized recommendations
|
||||||
|
|
||||||
|
**Performance**: Uses bash/grep for efficient scanning. Claude reads files only when specific content analysis is needed.
|
||||||
|
|
||||||
|
**Important**: Claude will NOT make any changes without your explicit approval.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Who This Is For
|
||||||
|
|
||||||
|
| Level | What You Get |
|
||||||
|
|-------|-------------|
|
||||||
|
| **Solo developer** | Find quick wins: trim bloat, add missing sections, fix stale imports |
|
||||||
|
| **Small team (2-10)** | Identify consistency gaps and opportunities for profile-based assembly |
|
||||||
|
| **Large team (10+)** | Systematic context architecture assessment with maturity scoring |
|
||||||
|
|
||||||
|
**Prerequisites**:
|
||||||
|
- Claude Code installed and working
|
||||||
|
- A project with at least a CLAUDE.md or `.claude/` directory
|
||||||
|
- Bash shell (native on macOS/Linux, WSL on Windows)
|
||||||
|
|
||||||
|
**Time**: ~3-5 minutes
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. How to Use It
|
||||||
|
|
||||||
|
### Step 1: Copy the Prompt
|
||||||
|
|
||||||
|
Copy everything inside the code block in [Section 4](#4-the-prompt) below.
|
||||||
|
|
||||||
|
### Step 2: Run Claude Code
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd your-project-directory
|
||||||
|
claude
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 3: Paste and Execute
|
||||||
|
|
||||||
|
Paste the prompt and press Enter. Claude will begin the audit.
|
||||||
|
|
||||||
|
### Step 4: Review Results
|
||||||
|
|
||||||
|
Claude will present findings, then ask for validation before making any changes.
|
||||||
|
|
||||||
|
### Platform Note
|
||||||
|
|
||||||
|
| Platform | Global Config Path |
|
||||||
|
|----------|-------------------|
|
||||||
|
| **macOS/Linux** | `~/.claude/` |
|
||||||
|
| **Windows** | `%USERPROFILE%\.claude\` |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. The Prompt
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
# Audit My Context Engineering Setup
|
||||||
|
|
||||||
|
## Context
|
||||||
|
|
||||||
|
Perform a comprehensive context engineering audit of my Claude Code configuration.
|
||||||
|
Focus on context size, structure quality, freshness, and team scalability.
|
||||||
|
|
||||||
|
Reference: https://github.com/FlorianBruniaux/claude-code-ultimate-guide/blob/main/guide/ultimate-guide.md
|
||||||
|
|
||||||
|
## Instructions
|
||||||
|
|
||||||
|
### Phase 1: Discovery (Bash Scan)
|
||||||
|
|
||||||
|
**IMPORTANT**: Use bash commands exclusively in this phase. Do NOT read files yet.
|
||||||
|
|
||||||
|
#### 1.1 Size & Structure Scan
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bash -c '
|
||||||
|
echo "=== GLOBAL CLAUDE.MD ==="
|
||||||
|
if [ -f ~/.claude/CLAUDE.md ]; then
|
||||||
|
lines=$(wc -l < ~/.claude/CLAUDE.md | tr -d " ")
|
||||||
|
chars=$(wc -c < ~/.claude/CLAUDE.md | tr -d " ")
|
||||||
|
tokens=$(echo "scale=0; $chars / 4" | bc 2>/dev/null || echo "~$((chars/4))")
|
||||||
|
echo "Lines: $lines"
|
||||||
|
echo "Chars: $chars (~$tokens tokens)"
|
||||||
|
echo "Imports: $(grep -c "^@" ~/.claude/CLAUDE.md 2>/dev/null || echo 0)"
|
||||||
|
echo "Rules count: $(grep -cE "^[-*] |^\d+\. " ~/.claude/CLAUDE.md 2>/dev/null || echo 0)"
|
||||||
|
echo "Last commit: $(cd ~/.claude && git log --format="%ar" -- CLAUDE.md 2>/dev/null | head -1 || echo "not tracked")"
|
||||||
|
else
|
||||||
|
echo "NOT FOUND"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== PROJECT CLAUDE.MD ==="
|
||||||
|
for f in ./CLAUDE.md ./.claude/CLAUDE.md; do
|
||||||
|
if [ -f "$f" ]; then
|
||||||
|
lines=$(wc -l < "$f" | tr -d " ")
|
||||||
|
chars=$(wc -c < "$f" | tr -d " ")
|
||||||
|
tokens=$(echo "scale=0; $chars / 4" | bc 2>/dev/null || echo "~$((chars/4))")
|
||||||
|
echo "File: $f"
|
||||||
|
echo "Lines: $lines"
|
||||||
|
echo "Chars: $chars (~$tokens tokens)"
|
||||||
|
echo "Imports: $(grep -c "^@" "$f" 2>/dev/null || echo 0)"
|
||||||
|
echo "Rules count: $(grep -cE "^[-*] |^\d+\. " "$f" 2>/dev/null || echo 0)"
|
||||||
|
echo "Last commit: $(git log --format="%ar" -- "$f" 2>/dev/null | head -1 || echo "not tracked")"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== IMPORTED FILES ==="
|
||||||
|
for f in ~/.claude/CLAUDE.md ./CLAUDE.md ./.claude/CLAUDE.md; do
|
||||||
|
[ -f "$f" ] || continue
|
||||||
|
while IFS= read -r line; do
|
||||||
|
[[ "$line" =~ ^@ ]] || continue
|
||||||
|
import_path="${line#@}"
|
||||||
|
import_path="${import_path/ */}"
|
||||||
|
resolved="${import_path/#\~/$HOME}"
|
||||||
|
resolved="${resolved/#./$PWD}"
|
||||||
|
if [ -f "$resolved" ]; then
|
||||||
|
sz=$(wc -c < "$resolved" | tr -d " ")
|
||||||
|
tk=$(echo "scale=0; $sz / 4" | bc 2>/dev/null || echo "$((sz/4))")
|
||||||
|
echo " FOUND $line (~$tk tokens)"
|
||||||
|
else
|
||||||
|
echo " BROKEN $line (file not found)"
|
||||||
|
fi
|
||||||
|
done < "$f"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== RULES & MODULES ==="
|
||||||
|
for d in ~/.claude ./.claude; do
|
||||||
|
[ -d "$d" ] || continue
|
||||||
|
for sub in rules skills commands agents hooks; do
|
||||||
|
if [ -d "$d/$sub" ]; then
|
||||||
|
count=$(find "$d/$sub" -maxdepth 1 -type f | wc -l | tr -d " ")
|
||||||
|
total_chars=$(find "$d/$sub" -maxdepth 1 -type f -exec cat {} \; 2>/dev/null | wc -c | tr -d " ")
|
||||||
|
tokens=$((total_chars / 4))
|
||||||
|
echo " $d/$sub: $count files (~$tokens tokens)"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
done
|
||||||
|
'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Store the output** for evaluation.
|
||||||
|
|
||||||
|
#### 1.2 Quality Pattern Scan
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bash -c '
|
||||||
|
echo "=== NEGATIVE VS POSITIVE INSTRUCTIONS ==="
|
||||||
|
for f in ~/.claude/CLAUDE.md ./CLAUDE.md ./.claude/CLAUDE.md; do
|
||||||
|
[ -f "$f" ] || continue
|
||||||
|
neg=$(grep -ciE "never|do not|dont|avoid|prohibited|forbidden|not allowed|do NOT" "$f" 2>/dev/null || echo 0)
|
||||||
|
pos=$(grep -ciE "always|prefer|use|should|must|recommended|do this" "$f" 2>/dev/null || echo 0)
|
||||||
|
echo "$f: negative=$neg positive=$pos"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== VAGUE INSTRUCTIONS (red flags) ==="
|
||||||
|
for f in ~/.claude/CLAUDE.md ./CLAUDE.md ./.claude/CLAUDE.md; do
|
||||||
|
[ -f "$f" ] || continue
|
||||||
|
echo "$f:"
|
||||||
|
grep -inE "be careful|good practice|appropriately|as needed|when necessary|use your judgment|you should know|be smart" "$f" 2>/dev/null | head -5 || echo " none found"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== DUPLICATE SECTION HEADERS ==="
|
||||||
|
for f in ~/.claude/CLAUDE.md ./CLAUDE.md ./.claude/CLAUDE.md; do
|
||||||
|
[ -f "$f" ] || continue
|
||||||
|
dupes=$(grep -E "^#{1,3} " "$f" | sort | uniq -d)
|
||||||
|
[ -n "$dupes" ] && echo "$f DUPLICATES: $dupes" || echo "$f: no duplicate headers"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== DEPRECATED REFERENCES ==="
|
||||||
|
for f in ~/.claude/CLAUDE.md ./CLAUDE.md ./.claude/CLAUDE.md; do
|
||||||
|
[ -f "$f" ] || continue
|
||||||
|
echo "$f:"
|
||||||
|
grep -niE "claude-1|claude-2\.0|claude-3-haiku-|gpt-3\.5|text-davinci|codex|copilot X|cursor pro 1\." "$f" 2>/dev/null | head -5 || echo " none found"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== PATH SCOPING (modular setup) ==="
|
||||||
|
for f in ~/.claude/CLAUDE.md ./CLAUDE.md ./.claude/CLAUDE.md; do
|
||||||
|
[ -f "$f" ] || continue
|
||||||
|
scoped=$(grep -cE "^@.+\.(ts|tsx|js|jsx|py|rs|go|md)$|globs:|path:" "$f" 2>/dev/null || echo 0)
|
||||||
|
echo "$f path-scoped entries: $scoped"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== SESSION & UPDATE PROTOCOL ==="
|
||||||
|
for f in ~/.claude/CLAUDE.md ./CLAUDE.md ./.claude/CLAUDE.md; do
|
||||||
|
[ -f "$f" ] || continue
|
||||||
|
has_update=$(grep -ciE "update|review|quarterly|maintenance|how to update|keep.*fresh" "$f" 2>/dev/null || echo 0)
|
||||||
|
has_session=$(grep -ciE "session|retro|checkpoint|lesson learned|knowledge loop" "$f" 2>/dev/null || echo 0)
|
||||||
|
echo "$f: update-protocol=$has_update session-retro=$has_session"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== TEAM/PROFILE READINESS ==="
|
||||||
|
for f in ~/.claude/CLAUDE.md ./CLAUDE.md ./.claude/CLAUDE.md; do
|
||||||
|
[ -f "$f" ] || continue
|
||||||
|
has_profile=$(grep -ciE "profile|role:|junior|senior|lead|persona|persona-" "$f" 2>/dev/null || echo 0)
|
||||||
|
has_module=$(grep -cE "^@" "$f" 2>/dev/null || echo 0)
|
||||||
|
echo "$f: profile-mentions=$has_profile module-imports=$has_module"
|
||||||
|
done
|
||||||
|
'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Store the output** for evaluation.
|
||||||
|
|
||||||
|
#### 1.3 Freshness & Conflict Scan
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bash -c '
|
||||||
|
echo "=== GIT FRESHNESS ==="
|
||||||
|
for path in ~/.claude ./; do
|
||||||
|
if git -C "$path" rev-parse --git-dir &>/dev/null 2>&1; then
|
||||||
|
echo "Repo at $path:"
|
||||||
|
git -C "$path" log --format="%ar %s" -- CLAUDE.md .claude/CLAUDE.md 2>/dev/null | head -3 || echo " no commits for CLAUDE.md"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== CONFLICTING RULES PATTERNS ==="
|
||||||
|
for f in ~/.claude/CLAUDE.md ./CLAUDE.md ./.claude/CLAUDE.md; do
|
||||||
|
[ -f "$f" ] || continue
|
||||||
|
echo "$f:"
|
||||||
|
# Look for contradictory patterns like "always X" near "never X"
|
||||||
|
always_terms=$(grep -ioE "always [a-z ]+" "$f" 2>/dev/null | sed "s/always //i" | sort)
|
||||||
|
never_terms=$(grep -ioE "never [a-z ]+" "$f" 2>/dev/null | sed "s/never //i" | sort)
|
||||||
|
conflicts=$(comm -12 <(echo "$always_terms") <(echo "$never_terms") 2>/dev/null)
|
||||||
|
[ -n "$conflicts" ] && echo " POTENTIAL CONFLICTS: $conflicts" || echo " no obvious contradictions"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=== OVERVIEW / ARCHITECTURE SECTION ==="
|
||||||
|
for f in ~/.claude/CLAUDE.md ./CLAUDE.md ./.claude/CLAUDE.md; do
|
||||||
|
[ -f "$f" ] || continue
|
||||||
|
has_overview=$(grep -ciE "^## (overview|purpose|about|architecture|what this|context)" "$f" 2>/dev/null || echo 0)
|
||||||
|
has_antip=$(grep -ciE "anti.pattern|bad example|do not do|wrong way|pitfall" "$f" 2>/dev/null || echo 0)
|
||||||
|
has_hierarchy=$(grep -cE "^#{1,3} " "$f" 2>/dev/null || echo 0)
|
||||||
|
echo "$f: has-overview=$has_overview anti-patterns=$has_antip section-count=$has_hierarchy"
|
||||||
|
done
|
||||||
|
'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Store the output** for evaluation.
|
||||||
|
|
||||||
|
### Phase 2: Evaluate Across 8 Dimensions
|
||||||
|
|
||||||
|
Use the scan outputs from Phase 1. Read specific file sections only if content examples are needed for the report.
|
||||||
|
|
||||||
|
#### Dimension 1: Size & Budget (15 pts)
|
||||||
|
|
||||||
|
Evaluate based on token estimates from Phase 1:
|
||||||
|
|
||||||
|
| Check | Points | Threshold |
|
||||||
|
|-------|--------|-----------|
|
||||||
|
| Total always-on context under 8K tokens | 5 | Sum of all CLAUDE.md + imports |
|
||||||
|
| Rule count under 150 instructions | 5 | global + project combined |
|
||||||
|
| No single file over 400 lines | 5 | flag if exceeded |
|
||||||
|
|
||||||
|
Deduct points proportionally if thresholds are exceeded. A file at 600 lines = 3/5 not 0.
|
||||||
|
|
||||||
|
#### Dimension 2: Structure (15 pts)
|
||||||
|
|
||||||
|
| Check | Points | Signal |
|
||||||
|
|-------|--------|--------|
|
||||||
|
| Has an overview/purpose section | 4 | h2 with "overview", "purpose", "about", "context" |
|
||||||
|
| Has architecture or project-layout section | 3 | h2 with "architecture", "structure", "layout" |
|
||||||
|
| Includes anti-patterns or bad examples | 4 | "anti-pattern", "do not", "pitfall" |
|
||||||
|
| Section count indicates clear hierarchy | 4 | 3+ distinct h2 sections |
|
||||||
|
|
||||||
|
#### Dimension 3: Path-Scoping (12 pts)
|
||||||
|
|
||||||
|
| Check | Points | Signal |
|
||||||
|
|-------|--------|--------|
|
||||||
|
| Uses @imports for modular breakdown | 5 | at least 2 @import lines |
|
||||||
|
| At least one path-specific or glob-scoped rule | 4 | globs: or file-specific section |
|
||||||
|
| Not a monolithic file (all instructions in one block) | 3 | multiple files or sections |
|
||||||
|
|
||||||
|
#### Dimension 4: Rule Quality (15 pts)
|
||||||
|
|
||||||
|
| Check | Points | Signal |
|
||||||
|
|-------|--------|--------|
|
||||||
|
| Ratio positive:negative >= 2:1 | 5 | from negative/positive counts |
|
||||||
|
| No vague instructions detected | 5 | zero "be careful", "as needed", etc. |
|
||||||
|
| Rules are specific and actionable | 5 | judged from sample during report generation |
|
||||||
|
|
||||||
|
#### Dimension 5: Freshness (12 pts)
|
||||||
|
|
||||||
|
| Check | Points | Signal |
|
||||||
|
|-------|--------|--------|
|
||||||
|
| CLAUDE.md committed within past 6 months | 5 | git log output |
|
||||||
|
| No deprecated tool/model references | 4 | deprecated scan output |
|
||||||
|
| No broken @imports | 3 | BROKEN lines in import scan |
|
||||||
|
|
||||||
|
#### Dimension 6: Team Readiness (10 pts)
|
||||||
|
|
||||||
|
| Check | Points | Signal |
|
||||||
|
|-------|--------|--------|
|
||||||
|
| Has profile-based or role-based structure | 4 | profile mentions >= 1 |
|
||||||
|
| Module imports enable selective assembly | 3 | module-imports >= 3 |
|
||||||
|
| Documented update protocol for team | 3 | update-protocol >= 1 |
|
||||||
|
|
||||||
|
#### Dimension 7: Conflict Detection (11 pts)
|
||||||
|
|
||||||
|
| Check | Points | Signal |
|
||||||
|
|-------|--------|--------|
|
||||||
|
| No contradictory rules detected | 5 | no conflicts from scan |
|
||||||
|
| No duplicate section headers | 3 | no duplicates found |
|
||||||
|
| Session retro or knowledge loop pattern | 3 | session-retro >= 1 |
|
||||||
|
|
||||||
|
#### Dimension 8: Knowledge Loop (10 pts)
|
||||||
|
|
||||||
|
| Check | Points | Signal |
|
||||||
|
|-------|--------|--------|
|
||||||
|
| Has update/review protocol documented | 4 | update-protocol >= 1 |
|
||||||
|
| Has session retro or lesson-learned pattern | 3 | session-retro >= 1 |
|
||||||
|
| Context tracked in git (auditable changes) | 3 | git freshness scan shows commits |
|
||||||
|
|
||||||
|
#### Calculate Total Score
|
||||||
|
|
||||||
|
`Score = sum of earned points across all 8 dimensions`
|
||||||
|
|
||||||
|
### Phase 3: Generate Report
|
||||||
|
|
||||||
|
Structure your output exactly as:
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Context Engineering Audit
|
||||||
|
|
||||||
|
### Score: [XX]/100
|
||||||
|
|
||||||
|
| Dimension | Score | Notes |
|
||||||
|
|-----------|-------|-------|
|
||||||
|
| Size & Budget | X/15 | total ~X tokens, X rules |
|
||||||
|
| Structure | X/15 | X sections, has/missing overview |
|
||||||
|
| Path-Scoping | X/12 | X imports, monolithic/modular |
|
||||||
|
| Rule Quality | X/15 | X% positive, X vague found |
|
||||||
|
| Freshness | X/12 | last updated X, X broken imports |
|
||||||
|
| Team Readiness | X/10 | X profiles, update protocol: yes/no |
|
||||||
|
| Conflict Detection | X/11 | X contradictions, X duplicate headers |
|
||||||
|
| Knowledge Loop | X/10 | git tracked: yes/no, retro: yes/no |
|
||||||
|
|
||||||
|
### Context Budget
|
||||||
|
- Global CLAUDE.md: ~X tokens
|
||||||
|
- Project CLAUDE.md: ~X tokens
|
||||||
|
- @imports combined: ~X tokens
|
||||||
|
- Total always-on: ~X tokens
|
||||||
|
- Rule count: X/150 instructions
|
||||||
|
|
||||||
|
### Priority Issues (fix these first)
|
||||||
|
1. [Issue] — [specific fix with example]
|
||||||
|
2. [Issue] — [specific fix with example]
|
||||||
|
3. [Issue] — [specific fix with example]
|
||||||
|
|
||||||
|
### Quick Wins (< 30 min each)
|
||||||
|
- [Fix]: [what to do and where]
|
||||||
|
- [Fix]: [what to do and where]
|
||||||
|
- [Fix]: [what to do and where]
|
||||||
|
|
||||||
|
### Maturity Level
|
||||||
|
[Choose one and explain why]
|
||||||
|
|
||||||
|
**Level 1 — Empty** (0-19): No structured context. Claude operates with zero project knowledge.
|
||||||
|
**Level 2 — Basic** (20-39): CLAUDE.md exists but is monolithic, stale, or mostly vague rules.
|
||||||
|
**Level 3 — Structured** (40-59): Clear sections and imports, but missing freshness or team patterns.
|
||||||
|
**Level 4 — Optimized** (60-79): Modular, scoped, positive-first rules with a known update cadence.
|
||||||
|
**Level 5 — Engineering-Grade** (80-100): Profile-aware, git-tracked, conflict-free, knowledge loop active.
|
||||||
|
|
||||||
|
### Ready-to-use Improvements
|
||||||
|
|
||||||
|
Provide 2-3 concrete text blocks that users can paste directly into their CLAUDE.md.
|
||||||
|
Each block must address a Priority Issue identified above. Format:
|
||||||
|
|
||||||
|
**Improvement 1: [name]**
|
||||||
|
File: `[path]` — add at [top/section X/end]
|
||||||
|
```
|
||||||
|
[exact text to paste]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Improvement 2: [name]**
|
||||||
|
File: `[path]` — add at [top/section X/end]
|
||||||
|
```
|
||||||
|
[exact text to paste]
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Phase 4: Await Validation
|
||||||
|
|
||||||
|
**CRITICAL**: Do NOT create or modify any files without explicit approval.
|
||||||
|
|
||||||
|
After presenting the report, ask:
|
||||||
|
|
||||||
|
"Which improvements would you like me to implement?
|
||||||
|
|
||||||
|
Options:
|
||||||
|
- `all` — Apply all ready-to-use improvements
|
||||||
|
- `1, 2` — Specific improvements by number
|
||||||
|
- `priority` — Only Priority Issues fixes
|
||||||
|
- `none` — Keep the report for reference only
|
||||||
|
|
||||||
|
Please specify your choice:"
|
||||||
|
|
||||||
|
Wait for explicit user response before taking any action.
|
||||||
|
|
||||||
|
## Output Format
|
||||||
|
|
||||||
|
Structure your response exactly as:
|
||||||
|
|
||||||
|
1. **Score table** with dimension breakdown
|
||||||
|
2. **Context Budget** summary
|
||||||
|
3. **Priority Issues** (numbered, fix first)
|
||||||
|
4. **Quick Wins** (bullet list, < 30 min each)
|
||||||
|
5. **Maturity Level** with explanation
|
||||||
|
6. **Ready-to-use Improvements** (paste-ready text blocks)
|
||||||
|
7. **Validation Request** (ask before implementing)
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. What to Expect
|
||||||
|
|
||||||
|
Here's an example of what the audit report looks like:
|
||||||
|
|
||||||
|
### Example Score Table
|
||||||
|
|
||||||
|
```
|
||||||
|
## Context Engineering Audit
|
||||||
|
|
||||||
|
### Score: 52/100
|
||||||
|
|
||||||
|
| Dimension | Score | Notes |
|
||||||
|
|-----------|-------|-------|
|
||||||
|
| Size & Budget | 10/15 | ~6,200 tokens total, 182 rules (over limit) |
|
||||||
|
| Structure | 9/15 | 4 sections, no anti-patterns section |
|
||||||
|
| Path-Scoping | 4/12 | 1 import, monolithic project CLAUDE.md |
|
||||||
|
| Rule Quality | 8/15 | 60% positive, 3 vague instructions found |
|
||||||
|
| Freshness | 9/12 | last commit 4 months ago, 1 broken import |
|
||||||
|
| Team Readiness | 3/10 | no profiles, no update protocol |
|
||||||
|
| Conflict Detection | 6/11 | 1 "always/never" contradiction, no duplicate headers |
|
||||||
|
| Knowledge Loop | 3/10 | not git tracked, no retro pattern |
|
||||||
|
```
|
||||||
|
|
||||||
|
### Example Quick Wins
|
||||||
|
|
||||||
|
```
|
||||||
|
Quick Wins (< 30 min each):
|
||||||
|
- Fix broken import: @~/.claude/TONE.md not found — update path or remove
|
||||||
|
- Add overview section: 2-line project description at top of CLAUDE.md
|
||||||
|
- Trim rule count: merge 3 formatting rules into one compressed block
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Scoring Guide
|
||||||
|
|
||||||
|
| Score | Maturity | Recommended Action |
|
||||||
|
|-------|----------|--------------------|
|
||||||
|
| **80-100** | Level 5: Engineering-Grade | Maintain with quarterly review |
|
||||||
|
| **60-79** | Level 4: Optimized | Address priority issues, reach 80 |
|
||||||
|
| **40-59** | Level 3: Structured | Dedicate a session to improvement |
|
||||||
|
| **20-39** | Level 2: Basic | Restructure recommended, use template |
|
||||||
|
| **0-19** | Level 1: Empty | Start fresh with skeleton template |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Glossary
|
||||||
|
|
||||||
|
| Term | Definition |
|
||||||
|
|------|-----------|
|
||||||
|
| **Always-on context** | Everything Claude loads before your first message: CLAUDE.md files plus all @imports |
|
||||||
|
| **@import** | A line starting with `@` in CLAUDE.md that loads another file into context |
|
||||||
|
| **Path-scoping** | Applying rules only to specific file types or directories, not globally |
|
||||||
|
| **Rule quality** | Specificity and actionability of instructions — vague rules waste tokens and confuse Claude |
|
||||||
|
| **Knowledge loop** | The practice of updating context files after sessions based on what worked and what didn't |
|
||||||
|
| **Profile assembly** | Combining different context modules to create role-specific setups (junior, senior, reviewer) |
|
||||||
|
| **Staleness signal** | Indicators that context is outdated: broken imports, deprecated model names, no git history |
|
||||||
|
| **Conflict** | Two rules that contradict each other — Claude will pick one arbitrarily, usually the wrong one |
|
||||||
|
| **Monolithic CLAUDE.md** | A single large file with all instructions, no imports, no modular breakdown |
|
||||||
|
| **Maturity level** | A 1-5 scale measuring context engineering sophistication from empty to engineering-grade |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. Common Issues
|
||||||
|
|
||||||
|
### "Token estimate seems off"
|
||||||
|
|
||||||
|
**Cause**: The estimate uses chars/4 as a rough proxy for GPT-style tokens. Claude's tokenizer may differ slightly.
|
||||||
|
|
||||||
|
**Fix**: Focus on relative numbers and thresholds rather than absolute token counts. The 8K always-on budget is a heuristic, not a hard limit.
|
||||||
|
|
||||||
|
### "Score is low but Claude seems to work fine"
|
||||||
|
|
||||||
|
**Cause**: Claude works without context engineering — the score reflects optimization, not basic functionality.
|
||||||
|
|
||||||
|
**Fix**: A low score means you're leaving productivity on the table. Each dimension gap adds cognitive overhead per session.
|
||||||
|
|
||||||
|
### "Broken import flagged but file exists"
|
||||||
|
|
||||||
|
**Cause**: Relative path resolution differs from Claude's actual working directory at startup.
|
||||||
|
|
||||||
|
**Fix**: Use absolute paths (`~/.claude/file.md`) for global imports. Use project-relative paths (`./docs/conventions.md`) for project imports.
|
||||||
|
|
||||||
|
### "Profile-readiness flagged but I'm solo"
|
||||||
|
|
||||||
|
**Cause**: The audit checks for team-scalability patterns regardless of team size.
|
||||||
|
|
||||||
|
**Fix**: Profile-based assembly still benefits solo developers when switching contexts (reviewing PRs vs writing features vs debugging). It is optional for solo use.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. Related Resources
|
||||||
|
|
||||||
|
- [The Ultimate Claude Code Guide](../guide/ultimate-guide.md) - Full reference
|
||||||
|
- [Audit Your Claude Code Setup](./audit-prompt.md) - Full configuration audit (agents, hooks, MCP, CI)
|
||||||
|
- [Cheatsheet](../guide/cheatsheet.md) - Quick daily reference
|
||||||
|
- [Claude Code Official Docs](https://docs.anthropic.com/en/docs/claude-code) - Anthropic documentation
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Last updated: March 2026 | Version 1.0*
|
||||||
Loading…
Add table
Add a link
Reference in a new issue