Make a Coding Agent Show What It Recalled, Restored, and Routed
Agent memory, context paging, and specialist routing work best when memory records, active context, and adapter choice are modeled as separate runtime boundaries.
Flow
Inspectable Planning Pipeline
The pipeline exposes every state transition while keeping private payloads out of telemetry.
1Query memory
Return references plus freshness and provenance metadata.
2Score candidates
Evaluate relevance, sensitivity, and staleness.
3Budget active context
Reserve space and accept only bounded selections.
4Select specialist
Route behavior from request intent, not from recalled memory.
5Authorize tools
Intersect requested capabilities with runtime policy.
6Execute and report
Record selected keys and outcomes without raw private content.
A coding agent does not have just one kind of state.
It may have durable notes, current task context, saved context snapshots, tool policy, active editor state, and specialist behaviors. When these are all collapsed into one hidden prompt, the system becomes difficult to inspect.
The agent may appear to "remember" something, but the user cannot tell what happened.
Did the runtime retrieve durable memory?
Did it restore an old context snapshot?
Did it route the request to a specialist adapter?
Did a tool policy change because of that route?
Those should be separate questions.
The public-safe thesis is:
A local coding agent becomes more inspectable when durable memory, active context, and specialist behavior routing are modeled as separate runtime surfaces instead of one hidden prompt blob.
This is not a claim that memory or specialist routing improves accuracy by itself. That would need benchmark evidence. The useful claim is architectural: each surface should have its own contract.
Three runtime surfaces
A practical local agent can split state into three layers.
| Layer | Question | Safe framing | |---|---|---| | Memory | What should persist across work? | Durable records need selection policy | | Context paging | What should enter the active window now? | Context is a bounded runtime budget | | Adapter routing | What behavior should handle this request? | Routing should be explicit and auditable |
These layers interact, but they should not collapse into one mechanism.
Memory is not active context
Memory is application state. It may include notes, summaries, decisions, scratchpad entries, or semantic recall records.
But saved memory should not automatically become prompt text.
A safer memory interface returns candidates:
Illustrative anonymized example
{
"query": "database migration index",
"candidateRecords": [
{
"key": "schema-index-note",
"tags": ["database", "migration"]
},
{
"key": "query-plan-summary",
"tags": ["sql", "performance"]
}
]
}
The runtime can then decide whether those records belong in the current active context.
That boundary matters because old memory can be stale, irrelevant, or too sensitive to replay.
Context paging is a bounded selection process
Context paging answers a different question:
Illustrative anonymized example
What should enter the active context window right now?
A local agent may save a named snapshot:
Illustrative anonymized example
{
"name": "schema_design",
"promptSummary": "Database schema design discussion",
"tokenEstimate": 1800,
"payloadRef": "example-ref"
}
Later, the runtime may restore that snapshot if it is relevant and fits within the active budget.
Safe defaults:
- Do not restore context silently.
- Do not restore snapshots that exceed the budget.
- Do not treat saved context as always relevant.
- Do not print raw prompt payloads in public logs.
The point is to make context movement visible.
Adapter routing is a separate decision
Adapter routing chooses which specialist behavior should handle a request.
Example:
Illustrative anonymized example
User: This SQL query is slow after the migration.
Router: sql
Another example:
Illustrative anonymized example
User: The browser page is not loading the expected component.
Router: web
This should not happen merely because memory exists or because a context snapshot was restored. It should happen because the router made a request-specific decision.
A useful planning event can report:
Illustrative anonymized example
{
"event": "agent.runtime.plan",
"requestId": "example-request-id",
"selectedAdapter": "sql",
"activeContextName": "schema_design",
"recalledMemoryCount": 2,
"recalledMemoryKeys": ["schema-index-note", "query-plan-summary"],
"contextTokenEstimate": 1800,
"toolPolicy": {
"allowedTools": ["read_file", "grep_files"],
"deniedTools": ["send_message"]
},
"rawMemoryTextPrinted": false,
"rawPromptPrinted": false
}
The event explains the runtime decision without exposing private contents.
Training records should teach the boundary
If the system uses training data for context paging, the examples should preserve the distinction between memory, context, and routing.
Sanitized examples:
Illustrative anonymized example
{
"instruction": "We are done with schema design. Switch to frontend work.",
"output": "ToolCall: {\"name\":\"context_save\",\"arguments\":{\"name\":\"schema_design\"}}\nToolCall: {\"name\":\"context_clear\",\"arguments\":{}}"
}
Illustrative anonymized example
{
"instruction": "What was the table key we used earlier?",
"output": "ToolCall: {\"name\":\"context_restore\",\"arguments\":{\"name\":\"schema_design\"}}"
}
Illustrative anonymized example
{
"instruction": "This looks like a database performance problem.",
"output": "ToolCall: {\"name\":\"delegate_to_expert\",\"arguments\":{\"domain\":\"sql\"}}"
}
These records teach transitions. They do not need real project names, private prompts, file paths, or raw task content.
Key failure modes
| Failure | What happened | Guard | |---|---|---| | Stale memory drives a new task | Recall is injected automatically | Memory returns candidates, not prompt text | | Context restore overflows window | Snapshot restored without budget check | Token estimate gate | | Specialist route is hidden | Behavior changes silently | Planning event reports adapter | | Adapter owns tool authority | Route changes allowed tools without runtime policy | Runtime owns tool policy | | Training row leaks private work | Real prompt becomes dataset row | Use synthetic examples |
The goal is not to make agent state magical. The goal is to make it visible.
A local coding agent should be able to explain:
- what it recalled
- what context it activated
- which adapter it selected
- which tools were allowed
- what private text was not printed
That is the difference between hidden prompt state and inspectable runtime state.