Skip to content

Latest commit

 

History

History
224 lines (158 loc) · 6.56 KB

File metadata and controls

224 lines (158 loc) · 6.56 KB

Context Injection Patterns

Technique Complexity

Context injection is the practice of strategically delivering the right information to Claude at the right time — keeping its context window focused on what matters while avoiding bloat from irrelevant material.


The Context Hierarchy

Not all context is equal. Prioritize by retention value:

ALWAYS IN CONTEXT (loaded every session)
├── CLAUDE.md                    ← Project rules and stack
├── .claude/rules/*.md           ← Detailed rules (auto-loaded)
└── .claude/memory/MEMORY.md     ← User preferences and project state

LOADED ON DEMAND (when relevant)
├── Skill files (.claude/skills/*)    ← Domain patterns
├── Plan files (docs/plans/*.md)      ← Current feature plan
└── Specific code files               ← Only what's needed

NEVER IN CONTEXT (read-only artifacts)
├── blackbox/session-log.md           ← Audit trail
└── docs/diagrams/*.md                ← Reference only

The "never in context" category is important. Large append-only logs consume context without providing proportional value.


Hook-Based Injection

The cleanest injection pattern: use UserPromptSubmit hooks to automatically add context to every prompt.

#!/usr/bin/env bash
# inject-context.sh — adds git state + sprint context to every prompt

BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "no-git")
COMMIT=$(git log --oneline -1 2>/dev/null || echo "no commits")
CHANGED=$(git diff --name-only HEAD 2>/dev/null | head -5 | sed 's/^/  - /')

cat << EOF
## Session Context
- Branch: ${BRANCH}
- Latest commit: ${COMMIT}
$(if [ -n "$CHANGED" ]; then echo "- Uncommitted changes:"; echo "$CHANGED"; fi)
EOF

This runs automatically before every prompt. Claude always knows the current branch and state without you having to say it.


Subagent Context Injection

Subagents start fresh — they need explicit context injection. Template:

## INJECTED PROJECT CONTEXT
Project: [Name] — [one sentence description]

Stack:
- [Language + version]
- [Framework + version]
- [Database]

Critical constraints (these are non-negotiable):
1. [Most important constraint]
2. [Second constraint]
3. [Third constraint]

Relevant files for this task:
- [path]: [one-line purpose]
- [path]: [one-line purpose]

DO NOT:
- [Most important thing to avoid]
- [Second thing to avoid]

## TASK
[The actual task]

## DONE WHEN
- [ ] [Verifiable criterion 1]
- [ ] [Verifiable criterion 2]
- [ ] Tests pass: [exact command]

This template ensures every subagent has the constraints it needs, regardless of what's in CLAUDE.md.


The ASSUMPTIONS Block

Before complex implementations, ask Claude to surface its assumptions. This is context injection in reverse — you're asking Claude to tell you what context it's using:

"Before implementing, surface your assumptions:

ASSUMPTIONS I'M MAKING:
1. [assumption about tech/architecture]
2. [assumption about scope]
3. [assumption about edge cases]
→ Correct me now or I'll proceed with these."

This pattern catches wrong context before it becomes wrong code.


Plan Files as Context

For multi-session features, plan files serve as persistent context injection:

# docs/plans/2026-04-06-rbac.md

## Status: IN PROGRESS (started 2026-04-06)
## Approved by: [human] on 2026-04-06

## Feature
Role-based access control for payments API

## Decisions Made
- Using permissions (not roles) to allow future ABAC upgrade
- JWT includes permissions array in payload
- 15-minute access token, 7-day refresh token

## Current Progress
- [x] Phase 1: permissions.py created
- [x] Phase 2: dependency added to routes
- [ ] Phase 3: tests (NEXT)

## Key Files
- src/auth/permissions.py — permission definitions
- src/payments/routes.py — permission checks added
- tests/auth/test_permissions.py — IN PROGRESS

New session:

"Load docs/plans/2026-04-06-rbac.md and continue from Phase 3."
→ Claude reads the plan
→ Has full context from Phase 1 + 2
→ Continues from exactly where you left off

Structured Summary Injection

Before /compact or at 70% context capacity, save a structured summary:

## Session Intent
Adding RBAC to the payments API

## Files Modified
- src/auth/permissions.py — created, has PERMISSIONS dict and require_permission()
- src/payments/routes.py — all 4 endpoints now have permission checks

## Decisions Made
- Using `permissions: list[str]` not `roles` — future ABAC compatibility
- Tokens include permissions in JWT payload
- 401 for missing/invalid token, 403 for valid token but missing permission

## Current State
Tests: 0 passing (haven't written them yet)
Implementation: complete, linting clean

## Next Steps
1. Write tests in tests/auth/test_permissions.py
2. Write 5 test cases: read-ok, write-ok, write-rejected, no-token, invalid-token
3. Run tests, verify all pass

After /compact, this summary is what Claude retains about the session so far.


Negative Context (What NOT to Inject)

Some information actively hurts context quality:

Don't inject:

  • Long error messages that have been resolved
  • Full file contents when only a function is relevant
  • Git history for files you're not touching
  • Exploratory reads that didn't lead anywhere
  • Session logs (blackbox/session-log.md)

Why: Context distraction is real. Irrelevant material in the context window reduces recall of relevant material by 10–40%. Trim aggressively.


The Rule: Inject Late, Inject Precisely

General principle: inject context as late as possible, as precisely as possible.

# Bad: inject everything upfront
"Here's our entire codebase structure: [500 lines]
Here's our entire architecture: [300 lines]  
Now, fix the login bug."

# Good: inject only what's relevant
"Fix the login bug. The login handler is at src/auth/routes.py:login_user().
The JWT issuer is at src/auth/tokens.py:issue_jwt(). 
The test is at tests/auth/test_login.py:test_login_invalid_password() — it's failing."

The second prompt is more useful despite being much shorter, because all the context is precisely relevant to the task.


Next Steps

  • Context Management — Managing the context window across long sessions
  • Subagents — Context injection for subagent dispatch
  • Hooks — Automating context injection via UserPromptSubmit hooks