Perf Deep Dive: Rule Pipelines
Summary
Replace the cookbook's static rule installation (3 copied files, ~17.7KB loaded per-turn) with two changes:
- Generated rule file — one tight, project-specific rule file (~50-80 lines) that combines ground rules, inline principles, and pipeline triggers. Tailored to the project during onboarding.
- Iterative pipeline — move guideline enforcement from a monolithic "evaluate everything at once" checklist into skills that iterate through each concern one at a time during planning and implementation.
Problem Statement
Research identified 6 issues with the current rule architecture:
Issue 1: Rules are per-turn, not per-session
Files in .claude/rules/ are injected into the system prompt on every single turn — every message, every tool call. The 3 installed rule files total 17,689 bytes. In a 50-turn conversation, that's ~885KB of context consumed by rules alone. This cost is the same whether the user is planning a complex feature or asking "what does this variable do?"
Issue 2: Two rule files say the same things
authoring-ground-rules.md and cookbook.md both cover scope discipline, planning before acting, verification, and incremental progress. Only 3 items in authoring-ground-rules are genuinely unique (confirm context, preserve existing work, no unauthorized changes). The rest is restated in cookbook.md. Claude reads both every turn, processing the same behavioral instructions twice.
Issue 3: Reading 18 principle files is mostly reading YAML
When cookbook.md says "read ALL 18 principle files," each file is 31-37 lines but only 10-16 lines are actual principle content. The rest is frontmatter: UUID, domain URL, version, status, language, dates, author, copyright, license, summary, platforms, tags, depends-on, related, references. That's 381 lines of metadata for 230 lines of substance (62% waste). cookbook.md already contains a 10-row summary table that proves the inline approach works.
Issue 4: auto-lint.md loads when it has nothing to do
auto-lint.md is only relevant when creating or modifying skills, agents, or rules — files that live in .claude/. But it has no globs frontmatter to scope it, so it loads into every turn of every session.
Issue 5: MUST NOT sections restate what the body already says
cookbook.md has 15 MUST NOT items. At least 5 are verbatim restatements of inline instructions: "Do not skip Phase 2" when the body already says "You MUST NOT skip this phase." Each redundant item costs context window space every turn without adding new information.
Issue 6: Every task gets the full ceremony
cookbook.md mandates the same process for every task regardless of size: read 18 principle files, read 3 guideline files, walk through a 38-item checklist with the user, search all recipe directories, trace decisions to principles, and plan three phases. A one-line bug fix triggers the same overhead as a multi-file feature implementation.
Scope
- In scope: Generated rule file, planning pipeline, implementation pipeline, updates to
/install-cookbookand/configure-cookbook, research documentation, linter optimization checks. - Out of scope: Changes to the source rule files in
rules/(they remain as generation input and self-enforced in the cookbook repo). Changes to the 18 principle files, guideline files, or recipe files.
Decisions
Generated rule file
- One file (
cookbook.md) replaces three static copies (authoring-ground-rules.md,cookbook.md,auto-lint.md) - Generated during onboarding by
/install-cookbook, regenerated by/configure-cookbookon preference change - Target size: ~50-80 lines (~4KB), down from 381 lines (17.7KB)
- Content is project-specific: auto-lint section only if
.claude/skills/or.claude/agents/exists; committing workflow only if opted in; recipe/contribution sections only if enabled in preferences - All 18 principles inlined as a summary table — no mandatory external file reads
- The 3 unique items from authoring-ground-rules (confirm context, preserve existing work, no unauthorized changes) merged as a preamble
- MUST NOT section deduplicated: only items that add unique constraints not stated in the body
- A generation manifest (
.cookbook/manifest.json) tracks what was included/excluded - Source rule files in the cookbook repo stay unchanged — they are the raw material, not the output
Iterative pipeline
- Guideline enforcement moves from the always-on rule file into on-demand pipeline skills
- The rule file contains a trigger: "During planning, run the planning pipeline. During implementation, run the implementation pipeline."
- Heavy content (guideline files, checklist details, prompt templates) is loaded only during the relevant pass, then released
Planning pipeline
Iterates through 38 concerns one at a time, building the plan incrementally:
- Passes 1-15 (Core Engineering, always apply): native controls, surface decisions, no blocking main thread, small commits, post-generation verification, linting, simplicity, work/right/fast, DI, immutability, fail fast, design for deletion, YAGNI, explicit over implicit, separation of concerns
- Passes 16-22 (Testing, always apply): comprehensive unit testing, test pyramid, good test properties, unit test patterns, flaky prevention, test data, testing workflow
- Passes 23-38 (Opt-in Concerns, ask the user): show progress, instrumented logging, deep linking, scriptable/automatable, accessibility, localizability, RTL, accessibility display options, privacy/security, feature flags, analytics, A/B testing, debug mode, property-based testing, mutation testing, security testing
For each pass: read the relevant guideline file, evaluate applicability, add to plan or mark N/A, move on. Small tasks get quick N/A passes. Complex tasks get substantive engagement on each applicable concern.
Implementation pipeline
Same 38 concerns as review passes against the code in a branch:
For each applicable concern (from the plan): read the guideline, review the code, make changes if needed, commit. Each pass produces its own commit. At the end, squash merge.
What this replaces
- Static copying of
authoring-ground-rules.md,cookbook.md,auto-lint.mdinto consuming projects - The monolithic "read ALL 18 principles + run full 38-item checklist" mandate
- The one-size-fits-all planning ceremony that treats every task the same
Implementation Order
- Decision record (this file)
- Research document (
research/developer-tools/claude/rule-optimization.md) - Linter optimization checks (O-series in
/lint-rule) - Generated rule file design and template
- Pipeline skills for planning and implementation
- Update
/install-cookbookwith generation logic - Update
/configure-cookbookto trigger regeneration
Each step is one iteration — implement, verify, commit before moving to the next.
Results
Analysis of the generated rule template against the 6 original issues:
| # | Issue | Before | After | Reduction |
|---|---|---|---|---|
| 1 | Per-turn bloat | 381 lines / 17,689 bytes (3 files) | ~90 lines / ~4,500 bytes (1 file) | 75% |
| 2 | Redundancy between rules | 2 files overlapping on scope, plan, verify | 1 file; 3 unique ground rules as a 5-line preamble | Eliminated |
| 3 | Frontmatter waste in principle reads | 18 file reads, 611 lines, 62% metadata | 18-row inline table, 0 mandatory file reads | Eliminated |
| 4 | auto-lint loads when irrelevant | 40 lines loaded every turn | Conditional section, only if project has .claude/skills/ or .claude/agents/ |
Eliminated |
| 5 | MUST NOT duplication | 23 items, 5+ redundant | 6 items, all unique | 74% |
| 6 | Full ceremony for every task | Monolithic 38-item checklist evaluated at once | Iterative per-concern pipeline with fast N/A passes | Resolved |
The only mandatory external file read is ../agentic-cookbook/cookbook/workflow/guideline-checklist.md — read once per planning session, not per turn.
Phase 2: Minimal Rule + Step-by-Step Pipeline
Phase 1 review revealed that the generated rule still carried ~90 lines of workflow content (principles table, planning pipeline, implementation pipeline, verification, conditional sections) that only matters when planning or implementing — not when answering questions or doing small tasks. Three additional insights drove Phase 2:
Insight 1: The always-on rule should be guardrails only
The planning and implementation workflow content only matters during those phases. Loading it every turn wastes context when the user is doing anything else. The always-on rule should contain only behavioral guardrails (~10 lines / ~500 bytes). Everything else moves to on-demand skills.
Insight 2: Load one concern at a time, not the full checklist
The guideline checklist (192 lines, 38 concerns) was loaded in full at planning start. But Claude only needs the current concern during each evaluation pass. Loading one concern at a time (~10 lines) reduces per-step context by 95%.
Insight 3: Pipeline state belongs on disk, not in context
Tracking which concerns have been evaluated and their results should not consume context window space. A .cookbook/pipeline.json file on disk holds the state. This also makes pipelines resumable across sessions.
Phase 2 Design
Always-on rule (~10 lines / ~500 bytes):
1. Confirm you are in the correct project before making changes.
2. Investigate unfamiliar content before overwriting.
3. Fix only what was asked — no unauthorized additions.
4. Do not skip Phase 2 (Make It Right).
5. Do not skip writing tests.
6. Do not optimize without evidence.
When planning or implementing features, use /cookbook-start.
Pipeline skills:
/cookbook-start— initializes.cookbook/pipeline.jsonwith phase (planning/implementation), step counter, and empty results array/cookbook-next— reads the current step fromcookbook/workflow/pipeline-concerns.json, loads only that concern's guideline file, evaluates it, records the result, increments the step counter
Pipeline concerns file (cookbook/workflow/pipeline-concerns.json):
- 38 entries mapping step numbers to concern details
- Each entry: step number, concern name, category, apply rule (always/ask), guideline file path, prompt template
- Uses explicit file paths instead of domain URLs
Phase 2 Additional Changes
- Guideline checklist (
cookbook/workflow/guideline-checklist.md) updated to use file paths instead ofagentic-cookbook://domain URLs code-verification.mdremoved from reference table (inline checks are sufficient)/install-cookbooksimplified (v8.0.0) — generates ~10-line rule, no longer produces principles table or pipeline sections/configure-cookbooksimplified (v4.0.0) — preferences managed via JSON, rule rarely needs regeneration
Phase 2 Results
| Metric | Phase 1 | Phase 2 | Reduction |
|---|---|---|---|
| Per-turn always-on cost | ~4,500 bytes | ~500 bytes | 89% |
| Per-step context (planning) | 192 lines (full checklist) | ~10 lines (one concern) | 95% |
| Pipeline state location | Conversation context | File on disk | Resumable |
| Total reduction from original | 75% | 97% | — |
Phase 2 Implementation
All 8 steps implemented and committed:
| Step | File | Action | Commit |
|---|---|---|---|
| 1 | cookbook/workflow/pipeline-concerns.json |
Created — 38 entries mapping steps to file paths | eaaab18 |
| 2 | cookbook/workflow/guideline-checklist.md |
Modified — domain URLs replaced with file paths (v1.1.0) | 4d2912d |
| 3 | rules/generated-cookbook-template.md |
Modified — slimmed to ~10 lines (guardrails only) | b36a163 |
| 4 | .claude/skills/cookbook-start/SKILL.md |
Created — initializes pipeline state (v1.0.0) | a40d149 |
| 5 | .claude/skills/cookbook-next/SKILL.md |
Created — advances one step per invocation (v1.0.0) | 4ba86f6 |
| 6 | .claude/skills/install-cookbook/SKILL.md |
Modified — minimal rule generation (v8.0.0) | 6540605 |
| 7 | .claude/skills/configure-cookbook/SKILL.md |
Modified — simplified for minimal rule (v4.0.0) | 549a587 |
| 8 | decisions/rule-pipeline-architecture.md |
Modified — Phase 2 implementation record (this update) | — |
Key design decisions during implementation:
- The guideline checklist referenced a non-existent
general.md— the "general" guidelines are distributed across topic subdirectories (ui/,code-quality/,concurrency/,logging/, etc.). Bothpipeline-concerns.jsonand the updated checklist now use actual file paths. - Steps 27 (accessibility) and 30 (accessibility display options) both reference
accessibility/accessibility.md— they are distinct concerns evaluated against the same guideline file. - The committing rule (
committing.md) is a separate file, not a conditional section in the generated rule. It is copied or removed based on user preference. - The minimal rule does not change based on project analysis (no
.claude/skills/check). All conditional behavior moves to preferences and pipeline concerns.
Overall Results
Quantitative Impact
| Metric | Original | Phase 1 | Phase 2 (Final) |
|---|---|---|---|
| Always-on rule files | 3 files | 1 file | 1 file |
| Per-turn cost | 17,689 bytes (381 lines) | ~4,500 bytes (~90 lines) | ~500 bytes (~10 lines) |
| Per-turn cost in 50-turn session | ~885 KB | ~225 KB | ~25 KB |
| Mandatory file reads at planning start | 18 principle files + 3 guideline files | 1 checklist file | 0 files |
| Per-step context during planning | 192 lines (full checklist) | 192 lines (full checklist) | ~10 lines (one concern) |
| Pipeline state storage | N/A (monolithic) | Conversation context | File on disk (resumable) |
| Total per-turn reduction | — | 75% | 97% |
Issue Resolution
| # | Issue | Resolution | Status |
|---|---|---|---|
| 1 | Per-turn bloat (17.7KB × every turn) | Minimal rule: 6 guardrails + 1 skill pointer | Resolved |
| 2 | Redundancy between 2 rule files | Single file; 3 unique ground rules inlined | Eliminated |
| 3 | Frontmatter waste in 18 principle reads | No mandatory reads; principles loaded on-demand per concern | Eliminated |
| 4 | auto-lint loads when irrelevant | Removed from always-on rule; becomes a preference | Eliminated |
| 5 | MUST NOT duplication (15 items, 5+ redundant) | 6 items in guardrails, all unique | Resolved |
| 6 | Full ceremony for every task | Step-by-step pipeline: /cookbook-start + /cookbook-next with fast N/A passes |
Resolved |
File Read Metrics
Rule files injected per turn (loaded into system prompt on every message, tool call, and response):
| Files | Lines | Bytes | |
|---|---|---|---|
| Before | 3 (authoring-ground-rules.md 74 lines, cookbook.md 267 lines, auto-lint.md 40 lines) |
381 | 17,689 |
| After | 1 (cookbook.md — 6 guardrails + 1 skill pointer) |
10 | 358 |
| Reduction | 67% | 97% | 98% |
Mandatory file reads at planning start (tool calls triggered by the rule to read external files):
| File reads | Lines read | Bytes read | |
|---|---|---|---|
| Before | 19 (18 principle files + 1 checklist) | 805 | 31,508 |
| After | 0 (/cookbook-start reads pipeline-concerns.json for entry count only) |
0 | 0 |
| Reduction | 100% | 100% | 100% |
The 18 principle files are 611 total lines but only 72 lines of actual content (12%). The remaining 539 lines (88%) are YAML frontmatter, headings, and change history — metadata that Claude processes but gains no value from.
Per-step context during planning (what's in context while evaluating one concern):
| In context | Bytes | |
|---|---|---|
| Before | Full 38-item checklist (194 lines) + all 18 principle summaries | ~31,500 |
| After | 1 concern entry (~6 lines) + 1 guideline file (~35-142 lines) | ~1,200-7,100 |
| Reduction | 78-96% |
Total context cost for a 50-turn session (rule loading only, excludes file reads):
| Calculation | Total | |
|---|---|---|
| Before | 17,689 bytes × 50 turns | 884,450 bytes (~864 KB) |
| After | 358 bytes × 50 turns | 17,900 bytes (~17 KB) |
| Reduction | 98% |
Architecture Comparison
Before (static installation):
Every turn loads:
authoring-ground-rules.md (5,200 bytes)
cookbook.md (11,200 bytes)
auto-lint.md (1,289 bytes)
─────────────────────────────────────
Total: 17,689 bytes × every turn
Planning starts:
Read 18 principle files (381 lines, 62% YAML metadata)
Read full 38-item checklist (192 lines)
Evaluate all 38 concerns at once
After (minimal rule + pipeline):
Every turn loads:
cookbook.md (~500 bytes, 10 lines)
─────────────────────────────────────
Total: ~500 bytes × every turn
Planning starts:
/cookbook-start creates state file on disk
/cookbook-next loads 1 concern (~10 lines) + 1 guideline file
Repeat 38 times, each invocation independent
Deliverables
| Deliverable | Files |
|---|---|
| Decision record | decisions/rule-pipeline-architecture.md |
| Research document | research/developer-tools/claude/rule-optimization.md |
| Linter optimization checks | lint-rule/references/rule-checklist.md (O-series), lint-rule/references/rule-structure-reference.md |
| Pipeline data | cookbook/workflow/pipeline-concerns.json (38 entries) |
| Guideline checklist (updated) | cookbook/workflow/guideline-checklist.md (v1.1.0, file paths) |
| Generated rule template | rules/generated-cookbook-template.md (minimal) |
| Pipeline skills | .claude/skills/cookbook-start/SKILL.md (v1.0.0), .claude/skills/cookbook-next/SKILL.md (v1.0.0) |
| Updated skills | .claude/skills/install-cookbook/SKILL.md (v8.0.0), .claude/skills/configure-cookbook/SKILL.md (v4.0.0) |
| Linter skill (updated) | .claude/skills/lint-rule/SKILL.md (v1.1.0) |
Total: 22 commits across 2 phases on branch feature/rule-pipeline-architecture (PR #12).
Recipe File Cleanup
Removed redundant ## Changelog sections from all 26 recipe files. Every recipe had both a ## Changelog and a ## Change History section tracking the same version data. Change History is the cookbook convention (includes Author column). Result: 164 lines / 6.2 KB of duplication eliminated.