Skip to content

TOC-native runtime v2 for local adaptive agents #140

Description

@louismorgner

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:

  1. Turn hooks
  2. Just-in-time instruction packs
  3. 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:

  1. Add after_tool_batch and before_model_call hooks only
  2. Add three default packs:
    • repeated_failures
    • evidence_before_done
    • read_heavy_drift
  3. Inject them through BuildContextView
  4. Persist interventions in state.json and events.jsonl
  5. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions