004 2026-04-04 concluded just-another-coding-agent

Why agents need memory and runtime framing

agentsarchitecturesessionsmemoryruntime-context
Setup
resumed agent sessions, compacted history, and one design question: is remembering the conversation enough
Found
it is not; an agent needs both conversation memory and a separate runtime-framing baseline for the next run
Result
JACA now persists both channels separately, and Codex made that split especially clear: replacement history carries the past, turn context carries the execution contract

The missing distinction

I think this is one of the easiest mistakes to make in agent design.

You notice that sessions are getting long, so you focus on memory. How should the old conversation be compressed? What should survive? What should the next run replay?

That is a real problem. It is not the whole problem.

An agent also needs to know under what conditions the next run should happen. Which workspace is active. Which shell family it should assume. Which date and timezone it believes. Which model and execution settings are in force.

That is not memory. It is runtime framing.

The split

The clean way to think about it is this:

  • memory answers: what happened?
  • runtime framing answers: under what conditions should the next run happen?

Once those two questions are visible, a lot of design confusion disappears.

sequenceDiagram
  autonumber
  actor User
  participant Session as Stored session
  participant Memory as Conversation memory
  participant Framing as Runtime framing
  participant NextRun as Next run

  User->>Session: Resume the session
  Session->>Memory: Rebuild the surviving conversation history
  Session->>Framing: Recover the latest run conditions
  Memory-->>NextRun: What happened so far
  Framing-->>NextRun: Where and how to continue

What the code forced me to see

JACA now persists those two channels separately.

The memory side is the compaction artifact: a compacted replacement history that resumed runs replay. The runtime side is a separate turn-context snapshot written per run. That snapshot carries the workspace root, shell family, date, timezone, model, thinking setting, and the runtime context text used to frame the next run.

The resume path then does two things before the next turn starts. It evaluates the latest persisted turn-context baseline, and it rebuilds the runtime-framed resume history from both the loaded session and that baseline. That is a stronger design than asking one artifact to do both jobs.

Codex makes the same split even more explicitly. Its compaction artifact is replacement_history, while TurnContextItem persists the turn conditions separately. The protocol makes the runtime side impossible to ignore: a real user turn carries cwd, approval policy, sandbox policy, model, and other turn settings as first-class context, not as hidden memory.

Why this matters

If you overload memory with runtime framing, two bad things happen.

First, the system becomes less trustworthy. After resume, fork, rollback, or compaction, the agent can remember the right task and still run under the wrong conditions.

Second, the system becomes harder to evolve. Conversation continuity and execution policy change at different speeds. They should not have to share one artifact.

That is why this distinction impressed me once it became concrete in code. The right design is not just “better memory.” It is admitting that an agent has two separate kinds of continuity to preserve.

Takeaway

An agent does not resume from memory alone.

It resumes from memory plus framing. One tells it what happened. The other tells it where it is and how to continue.