v3/@claude-flow/guidance/docs/adrs/ADR-G002-constitution-shard-split.md
Accepted
2026-02-01
A typical CLAUDE.md file for a production project contains 100-500 rules covering security, testing, architecture, deployment, performance, and coding style. Loading all rules into the context window on every turn has two costs:
Token waste. A 400-rule file at ~5 tokens per rule consumes ~2,000 tokens per turn. Over a 50-turn session, that is 100,000 tokens of repeated context that is mostly irrelevant to any single task.
Attention dilution. Transformer attention degrades with document length. A model asked to "fix the login bug" does not benefit from rules about Kubernetes deployment -- but those rules compete for attention with the security rules that are relevant.
The opposite extreme -- loading no rules and relying on the model's training -- causes drift. The model forgets project-specific conventions, introduces forbidden dependencies, or skips mandatory test steps.
We need a middle ground: a small, always-present set of invariants plus a larger set of rules retrieved on demand.
Split the compiled rule set into two tiers:
The GuidanceCompiler in src/compiler.ts identifies constitution rules by scanning for section headers matching CONSTITUTION_MARKERS:
const CONSTITUTION_MARKERS = [
/^#+\s*(safety|security|invariant|constitution|critical|non[- ]?negotiable|always)/i,
/^#+\s*(must|never|always|required|mandatory)/i,
];
Constitution rules are extracted into a Constitution object (defined in src/types.ts) with:
rules array of GuidanceRule objects, each with isConstitution: truetext field containing a compact rendering (capped at maxConstitutionLines, default 60)hash field (SHA-256 truncated to 16 hex chars) for change detectionConstitution rules receive a priority boost of +100 over their base priority, ensuring they always dominate in contradiction resolution.
The constitution is designed to be 30-60 lines (~500 tokens) and covers:
All non-constitution rules become RuleShard objects. Each shard contains:
GuidanceRule with intent tags, domain tags, tool classes, repo scopescompactText field: [RULE-ID] rule text @tag1 @tag2embedding vector (Float32Array) for semantic retrievalThe ShardRetriever in src/retriever.ts indexes shards by generating embeddings (via IEmbeddingProvider, defaulting to HashEmbeddingProvider for zero-dependency operation). At task start, retrieval works as follows:
cosine_similarity + intent_boost(0.15) + risk_boost(0.05-0.10)The ShardRetriever.retrieve() method returns a RetrievalResult containing the combined policyText ready for injection.
selectWithContradictionCheck method in ShardRetriever detects when two retrieved shards have contradictory language (must vs. never) in the same domain and keeps the higher-priority one.HashEmbeddingProvider uses a deterministic hash-based pseudo-embedding that is not semantically meaningful. Production deployments should plug in an ONNX-based provider for real semantic similarity.maxConstitutionLines cap (default 60) enforces discipline.Load the full CLAUDE.md on every turn. Rejected because of the measured ~2,000 token cost and attention degradation on long documents. In testing, models skip rules beyond the first 100 lines with increasing probability.
Match shards by keyword overlap with the task description. Rejected because keyword matching misses synonyms and paraphrases. "Fix the auth issue" would not match a rule about "authentication vulnerability" without semantic similarity.
Use a cheap model to select relevant rules. Rejected because it adds 200-500ms latency and a per-turn API cost. The embedding + cosine approach runs in <5ms with no API calls.
Pre-define shard groups (e.g., "security pack", "testing pack") and load by task type. Rejected because it requires manual curation, does not adapt to new rule combinations, and breaks when rules span multiple domains.
v3/@claude-flow/guidance/src/types.ts -- Constitution, RuleShard, PolicyBundle type definitionsv3/@claude-flow/guidance/src/compiler.ts -- buildConstitution(), buildShards(), CONSTITUTION_MARKERSv3/@claude-flow/guidance/src/retriever.ts -- ShardRetriever.retrieve(), selectWithContradictionCheck()