Issue: TOC-native runtime v2 for local adaptive agents
Summary
Build a local-first v2 of toc-native that can adapt its behavior between turns without turning the runtime into a pile of hidden prompt hacks.
The core idea is simple:
- keep the runtime general, not coding-specific
- add a small number of explicit turn hooks
- let those hooks attach short, just-in-time instructions based on evidence from the session
- preserve all of it in state and events so the behavior stays inspectable
This should make the native runtime better at long tasks, debugging, research, ops, writing, and coding, while staying small enough to ship without cloud infrastructure.
Why this is worth doing
Right now toc-native already has the right shape for this:
So the missing piece is not another runtime. It is a better policy layer inside the runtime we already have.
Problem
The current native loop is competent, but mostly static:
- the system prompt is assembled once at session start
- the runtime tracks working set and compaction state, but it does not actively turn that state into targeted behavior
- tool execution results are appended to history, but there is no explicit "what just happened and how should we react" stage
on_end exists, but there is no equivalent local hook after each model turn or tool batch
That leaves performance on the table. The runtime knows when the agent is looping, over-reading, failing tools, drifting, or reaching context pressure, but it mostly just records those facts instead of using them.
Goal
Make toc-native feel like a runtime with judgment:
- when the task is going well, stay out of the way
- when the task is drifting, inject a short correction
- when the context is getting heavy, preserve the right memory
- when the agent is blocked, steer it toward evidence, not more chatter
This should work for coding, but the design should generalize to any local agent task that uses tools and accumulates state over time.
Non-goals
- no cloud scheduler
- no remote sandboxes
- no multi-agent orchestration overhaul
- no domain-specific planner hardcoded for coding
- no giant hidden prompt layer that nobody can debug
Research evidence behind the direction
This proposal follows the strongest patterns from both papers and current products:
- Execution feedback helps more than free-form reflection. Self-Debugging, LDB, and related work show that model performance improves when the next turn is grounded in concrete runtime evidence instead of generic “think harder” prompting.
- Simpler control loops still win. Agentless showed that localization, repair, and validation can outperform heavier agent scaffolds while being cheaper and easier to reason about.
- Repo or task context should be assembled iteratively, not dumped wholesale. RepoCoder and the broader repo-aware agent work point the same way.
- The best current agent products already converge on runtime-managed context and execution loops. Claude Code, Aider, OpenCode, Codex, and Copilot agents all push in that direction, even when the UX differs.
Sources:
Proposal
Add a small adaptive policy layer to toc-native with three parts:
- Turn hooks
- Just-in-time instruction packs
- Structured working memory updates
1. Turn hooks
Add explicit local hooks inside the native loop. These are runtime phases, not user-defined shell scripts.
Suggested hook points:
before_model_call
after_model_response
after_tool_batch
before_finalize
Each hook gets a typed TurnContext built from:
- current user request
- recent messages
- working set
- pending turn
- latest tool results
- token usage and compaction state
- optional task metadata inferred by the runtime
Each hook can emit a small HookResult:
notes: structured observations for state
instructions: short ephemeral instructions to inject into the next context view
events: human-readable audit entries
continue: whether the runtime should proceed normally
Important constraint: hooks do not call tools directly in v2. They are lightweight policy passes over existing evidence.
2. Just-in-time instruction packs
Instead of inflating the base system prompt, add short instruction packs only when a trigger fires.
Examples:
- repeated tool failure
- "Stop guessing. Use the last failure output to choose the next action."
- excessive reading without action
- "You have enough context to propose a concrete next step. Do not read more files unless it resolves a specific uncertainty."
- context pressure
- "Prefer short updates. Preserve open questions and next actions explicitly."
- plan drift
- "State the current objective, the blocking uncertainty, and the next concrete action before continuing."
- low-evidence completion
- "Do not claim completion until you cite the evidence produced in this session."
These packs should be:
- short
- typed
- traceable in state and events
- configurable per agent
This is the big practical win. The runtime gets to intervene when needed without hard-forking agent behavior by domain.
3. Structured working memory updates
After each tool batch, compute a compact local memory record from what actually happened.
Suggested fields:
goal
active_subgoal
evidence
open_questions
recent_failures
pending_verification
next_best_actions
This is not a long summary. It is a small runtime-owned scratchpad for the next turn.
It should sit next to the existing working set and continuation, not replace them.
Why this generalizes beyond coding
The runtime should not know what a "bug fix" or a "research memo" is. It should know more abstract things:
- whether the agent has evidence
- whether it is repeating itself
- whether it is blocked
- whether it has a pending claim to verify
- whether it is spending context budget well
Coding is a good forcing function because the failures are obvious, but the policy layer itself can stay domain-agnostic.
Examples outside coding:
- research agent
- inject a pack when the agent is summarizing without citing source evidence
- ops agent
- inject a pack when commands fail repeatedly without narrowing the hypothesis
- writing agent
- inject a pack when it keeps revising style before settling the argument
Concrete scope for v2
Phase 1: runtime-owned hook framework
Add new native-runtime types and plumbing:
TurnContext
HookResult
InstructionPack
HookTrigger
Likely files:
Deliverable:
- runtime can attach ephemeral instruction packs before the next model call
- instruction packs are visible in
state.json and events.jsonl
Phase 2: default local policies
Ship a small default set of policies based on state we already have:
- repeated tool failures
- read-heavy drift
- context pressure
- repeated compaction
- low-evidence "done" responses
- excessive sub-agent use
Deliverable:
- a useful default behavior boost without requiring agent authors to configure anything
Phase 3: agent-configurable policy packs
Extend runtime config so an agent can enable, disable, or tune policy packs.
Possible shape:
runtime: toc-native
runtime_config:
adaptive_packs:
- repeated_failures
- evidence_before_done
- context_pressure
pack_overrides:
evidence_before_done:
min_failures: 1
severity: medium
Deliverable:
- agents can stay generic by default but tighten or relax runtime behavior for their own jobs
Proposed implementation details
New state
Add a small runtime-owned section to state:
active_instruction_packs
last_hook_results
working_memory
turn_metrics
turn_metrics can track simple counters:
- consecutive tool failures
- consecutive reads without writes
- turns since last concrete artifact
- turns since last user-visible progress
Context injection strategy
Extend BuildContextView so it can inject:
- working set summary
- active instruction packs
- optional working memory block
All of these should be tagged and easy to inspect in traces.
Event model
Emit explicit events when the runtime intervenes:
hook_observation
instruction_pack_added
instruction_pack_removed
working_memory_updated
That gives us replayable evidence for whether the runtime is helping or just being noisy.
Safety rule
Instruction packs should be bounded:
- max 1-3 active at a time
- strict character budget
- expire automatically after N turns unless renewed
That keeps the runtime from accreting junk into the prompt.
Open explorations worth trying
- Can the runtime add a "prove it before done" pack based on recent tool evidence and materially reduce false completion?
- Is it better to update working memory heuristically, or with a tiny model call under a hard budget?
- Should hooks only observe and inject instructions, or should some be allowed to rewrite the next user-visible task framing?
- Can a generic "stalled loop" detector beat hand-written domain prompts across coding, research, and writing tasks?
- Should compaction and adaptive instruction selection share one budget manager instead of acting independently?
Acceptance criteria
- Native runtime supports internal turn hooks without introducing external shell hooks
- Runtime can inject bounded, typed instruction packs into the next model call
- State and events make every intervention inspectable
- Default policies improve task behavior in at least one native eval harness without noticeably hurting short tasks
- The design remains general enough to apply to non-coding agent templates
Practical first slice
If we want the smallest version that is still worth shipping:
- Add
after_tool_batch and before_model_call hooks only
- Add three default packs:
repeated_failures
evidence_before_done
read_heavy_drift
- Inject them through
BuildContextView
- Persist interventions in
state.json and events.jsonl
- Add focused tests around trigger logic and context rendering
That is narrow, local, and doable. It also sets up the runtime for more ambitious policy layers later without committing us to cloud complexity or domain-specific scaffolding.
Issue: TOC-native runtime v2 for local adaptive agents
Summary
Build a local-first v2 of
toc-nativethat can adapt its behavior between turns without turning the runtime into a pile of hidden prompt hacks.The core idea is simple:
This should make the native runtime better at long tasks, debugging, research, ops, writing, and coding, while staying small enough to ship without cloud infrastructure.
Why this is worth doing
Right now
toc-nativealready has the right shape for this:So the missing piece is not another runtime. It is a better policy layer inside the runtime we already have.
Problem
The current native loop is competent, but mostly static:
on_endexists, but there is no equivalent local hook after each model turn or tool batchThat leaves performance on the table. The runtime knows when the agent is looping, over-reading, failing tools, drifting, or reaching context pressure, but it mostly just records those facts instead of using them.
Goal
Make
toc-nativefeel like a runtime with judgment:This should work for coding, but the design should generalize to any local agent task that uses tools and accumulates state over time.
Non-goals
Research evidence behind the direction
This proposal follows the strongest patterns from both papers and current products:
Sources:
Proposal
Add a small adaptive policy layer to
toc-nativewith three parts:1. Turn hooks
Add explicit local hooks inside the native loop. These are runtime phases, not user-defined shell scripts.
Suggested hook points:
before_model_callafter_model_responseafter_tool_batchbefore_finalizeEach hook gets a typed
TurnContextbuilt from:Each hook can emit a small
HookResult:notes: structured observations for stateinstructions: short ephemeral instructions to inject into the next context viewevents: human-readable audit entriescontinue: whether the runtime should proceed normallyImportant constraint: hooks do not call tools directly in v2. They are lightweight policy passes over existing evidence.
2. Just-in-time instruction packs
Instead of inflating the base system prompt, add short instruction packs only when a trigger fires.
Examples:
These packs should be:
This is the big practical win. The runtime gets to intervene when needed without hard-forking agent behavior by domain.
3. Structured working memory updates
After each tool batch, compute a compact local memory record from what actually happened.
Suggested fields:
goalactive_subgoalevidenceopen_questionsrecent_failurespending_verificationnext_best_actionsThis is not a long summary. It is a small runtime-owned scratchpad for the next turn.
It should sit next to the existing working set and continuation, not replace them.
Why this generalizes beyond coding
The runtime should not know what a "bug fix" or a "research memo" is. It should know more abstract things:
Coding is a good forcing function because the failures are obvious, but the policy layer itself can stay domain-agnostic.
Examples outside coding:
Concrete scope for v2
Phase 1: runtime-owned hook framework
Add new native-runtime types and plumbing:
TurnContextHookResultInstructionPackHookTriggerLikely files:
internal/runtime/native_hooks.gointernal/runtime/native_instruction_packs.goDeliverable:
state.jsonandevents.jsonlPhase 2: default local policies
Ship a small default set of policies based on state we already have:
Deliverable:
Phase 3: agent-configurable policy packs
Extend runtime config so an agent can enable, disable, or tune policy packs.
Possible shape:
Deliverable:
Proposed implementation details
New state
Add a small runtime-owned section to state:
active_instruction_packslast_hook_resultsworking_memoryturn_metricsturn_metricscan track simple counters:Context injection strategy
Extend BuildContextView so it can inject:
All of these should be tagged and easy to inspect in traces.
Event model
Emit explicit events when the runtime intervenes:
hook_observationinstruction_pack_addedinstruction_pack_removedworking_memory_updatedThat gives us replayable evidence for whether the runtime is helping or just being noisy.
Safety rule
Instruction packs should be bounded:
That keeps the runtime from accreting junk into the prompt.
Open explorations worth trying
Acceptance criteria
Practical first slice
If we want the smallest version that is still worth shipping:
after_tool_batchandbefore_model_callhooks onlyrepeated_failuresevidence_before_doneread_heavy_driftBuildContextViewstate.jsonandevents.jsonlThat is narrow, local, and doable. It also sets up the runtime for more ambitious policy layers later without committing us to cloud complexity or domain-specific scaffolding.