Context Injection
Start-of-session memory injection.
Context injection is the mechanism by which the platform enriches a just-started agent session with relevant past observations. When a worker claims a session, buildSessionMemoryBlock retrieves observations from the store, applies feedback ranking, and formats them into a markdown block that is delivered to the agent over the durable inject rail.
How injection works
Delivery
The rendered block is delivered through the durable session_memory_injects queue, not by literally rewriting the agent's system prompt: injectContextForClaimedSession (called after a worker claims the session) enqueues the block via enqueueMemoryInject, and the owning worker pulls + applies it through the daemon's handle.Inject on its next lock-refresh beat. The queue is the same at-least-once rail described in In-Session Injection → Durable inject queue.
Delivery is gated by the project's runtimeInjectEnabled memory sub-toggle - when it is off, the block is still computed and the context_injection_logs row is still written (so feedback weighting keeps learning), but nothing is pushed to the agent. Enqueue is idempotent per (sessionId, contentHash) and fire-and-forget: a failure never affects the session.
Retrieval query text
In production the queryText is composed from the work item rather than the raw issue UUID: issue identifier + cached issue title + the first line of the description (via the platform's Linear issue cache, populated on session creation), degrading stepwise to identifier-only → issue UUID → session id when fields are missing (retrieval-query.ts).
Token budgets
Each workType has a configurable token budget. The platform uses a 4-chars-per-token heuristic (no tiktoken dependency) to stay under the budget.
Default budgets
workType | Default (tokens) |
|---|---|
bug_fix | 750 |
feature | 400 |
refactor | 600 |
chore | 300 |
| (unknown) | 500 (fallback) |
These are the DEFAULT_CONTEXT_BUDGET values from context-injection.ts. Override them per org:
const budgetConfig: ContextBudgetConfig = {
defaults: {
bug_fix: 750,
feature: 400,
refactor: 600,
chore: 300,
},
orgOverrides: {
'org_abc': {
feature: 600, // this org wants more feature context
},
},
}Org overrides take precedence over the defaults map. The budget controls how many observations are included - observations are added in ranked order until the token estimate would be exceeded; the exceeding observation is skipped and the loop continues (a shorter observation may still fit).
Observation block format
Included observations are rendered as:
## Relevant Past Observations
- [<id>] <content excerpt up to 300 chars> (weight: <weight>)
- [<id>] ...The excerpt is truncated at 300 characters to prevent a single verbose observation from consuming the entire budget.
Graph context merging
When a Knowledge Graph is configured and the project has Knowledge Graph memory enabled (per-project; see Knowledge Graph enablement), the injection also runs a graph search and merges architectural triplets into the block:
## Knowledge Graph Triplets
- AuthService → depends_on → PostgresDB
- UserController → calls → AuthServiceCross-org graph triplets are filtered by the Cedar PEP (enforceGraphAccess) before they reach the prompt. Graph search is per-workType gated in addition to the per-project enablement check:
workType | Graph enabled by default |
|---|---|
bug_fix | Yes |
refactor | Yes |
feature | Yes |
chore | No |
The injection log
Every injection is persisted to context_injection_logs by recordContextInjection. This row powers the Feedback Impact and Context Budget Pareto analytics views:
interface ContextInjectionLog {
id?: string
sessionId: string
workType: string
budgetTokens: number // configured budget
actualTokens: number // tokens actually consumed
observationIds: string[]
sessionSummaryIds: string[]
graphNodeIds?: string[] // graph node UUIDs surfaced to agent
graphEdgeKeys?: Array<{
sourceId: string
targetId: string
relationshipName: string
}>
queryText: string
orgId?: string
projectId?: string
timestamp?: string // ISO-8601, from DB row
}graphNodeIds and graphEdgeKeys are also used at session completion by GraphFeedbackService.applyFeedback to propagate EMA weight updates back to the graph nodes that were helpful or misleading.
Cross-project transfer
When crossProjectTransfer is passed to buildSessionMemoryBlock, the store is transparently wrapped with createCrossProjectTransferStore. This surfaces Cedar-authorized observations from peer projects with overlapping tech stacks. See Cross-Project Transfer for the transfer rules and the 70% Jaccard similarity threshold.
Calling the API
import {
buildSessionMemoryBlock,
recordContextInjection,
} from '@/lib/memory/context-injection'
const block = await buildSessionMemoryBlock({
sessionId: 'ses_abc',
workType: 'bug_fix',
orgId: 'org_123',
projectId: 'proj_xyz',
queryText: 'fix null pointer in auth middleware',
store: myMemoryStore,
crossProjectTransfer: { /* optional */ },
graph: {
engine: graphSearchEngine,
identity: { orgId: 'org_123', agentId: 'agent_dev' },
// gated by isGraphEnabledForProject(orgId, projectId) - per-project, not an org flag
graphEnabled: true,
},
})
// block.block - the markdown string to prepend to the system prompt
// block.observationIds
// block.graphNodeIds
// block.graphEdgeKeys
const logId = await recordContextInjection({
sessionId: 'ses_abc',
workType: 'bug_fix',
budgetTokens: 750,
actualTokens: block.actualTokens,
observationIds: block.observationIds,
sessionSummaryIds: [],
graphNodeIds: block.graphNodeIds,
graphEdgeKeys: block.graphEdgeKeys,
queryText: 'fix null pointer in auth middleware',
orgId: 'org_123',
projectId: 'proj_xyz',
})Related pages
- Observation Store - where observations are persisted
- Feedback Retrieval - the
applyFeedbackRankingstep - Retrieval Ranking - corroboration-boost module (built, not yet wired into this path)
- In-Session Injection - mid-session memory delivery, including the durable inject queue
- Cross-Project Transfer - peer-project observation surface
- Context Budget Pareto - analytics view over injection logs
- Memory Diagnostics - session-outcome diagnostics that feed weight updates affecting future injections