Level 3 · Loop Engineering

Build Memory That Helps More Than It Costs

The memory that scales long autonomous agent work is not a bigger context dump, but a repo-local retrieval and retirement system that proves what is still useful.

Start With Memory Budgets, Not Memory Files

Long loops fail when memory becomes a second prompt window: every preference, incident, half-true rule, and stale workaround gets dragged into every run. The central design constraint is cost per decision. Memory should reduce search, prevent repeated failures, or preserve project intent across fresh contexts. Anything else is context debt.

Treat `AGENTS.md`, `CLAUDE.md`, or the repo equivalent as a router, not a handbook. Keep it under a hard size cap and make it point to deeper files by task type: architecture invariants, verification contracts, run logs, gotchas, domain decisions, client rules. The agent should read the router first, then progressively disclose only the bundle needed for the current phase. If the file tells every agent everything, it will eventually make every agent worse.

A practical repo layout is `memory/index.md`, `memory/bundles/`, `memory/runs/`, `memory/retros/`, and `memory/rot.md`. The index answers: what exists, when to load it, and what not to load. The rot file is not ceremony. It records review cadence by layer: identity rarely, skills monthly or after failures, model-specific instructions aggressively, tool/API notes whenever dependencies change. Memory that has no review policy is just delayed entropy.

Use Knowledge Bundles As Retrieval Units

Once the router is lean, the next problem is granularity. A folder full of markdown is easy for humans but expensive for agents unless it has predictable traversal. Use OKF-style bundles: small directories with a top-level index, section indexes, and YAML metadata on each document. At minimum, every document needs a `type`; add `title`, `tags`, `status`, `updated`, `applies_to`, and relationship fields when they materially improve lookup.

The goal is not standards compliance for its own sake. The goal is giving any agent a cheap graph walk: list bundles, inspect indexes, select concept IDs, then read only the relevant files. For example, `memory/bundles/payments/index.md` might route to `concepts/idempotency.md`, `decisions/refund-state-machine.md`, and `gotchas/stripe-webhook-retries.md`. The agent should not open the whole payments history to fix one webhook test.

Build a tiny CLI before building a bigger memory system. `mem list`, `mem index payments`, `mem read payments stripe-webhook-retries`, and `mem stale --days 90` are enough. The CLI gives agents deterministic access patterns and lets verification code assert what was loaded. It also makes memory portable across Claude Code, Codex, Goose, and local wrappers instead of binding your process to one vendor's session format.

Separate Run Logs From Standing Instructions

After retrieval works, resist the urge to promote every lesson into rules. Most autonomous loop data belongs in run logs, not permanent memory. A run log should capture objective state: goal, commit SHA, model, tools enabled, files touched, commands run, test output hashes, failures, retries, elapsed time, token or quota use, and final verdict. This is evidence, not advice.

Standing instructions should be curated from retrospectives over logs. Add a retrospective pass at the end of long loops that asks: what failure repeated, what missing context caused it, what deterministic gate would have caught it, and what memory entry should change? The output should be a patch proposal against `memory/`, not an automatic rewrite of the whole knowledge base. The best durable memories are short gotchas tied to proof: "Do not use mocked auth in checkout E2E; Playwright run 2026-07-18 passed only after real session setup." That is much better than a generic rule to write realistic tests.

This distinction controls bloat. Logs can be verbose because they are cold storage and compressible. Instructions must be sparse because they sit near the model's decision loop. Use tools that compress logs and tool output before re-ingestion, but do not compress standing rules into vague summaries. If a memory cannot name the condition where it applies, demote it back to a log reference.

Make Memory Part Of The Harness

Memory only pays off when the harness decides when to load it, when to ignore it, and when to challenge it. For serious loops, model the workflow as states: research, plan, implement, verify, review, retrospect. Each state gets a different memory policy. Research can read broad indexes and spawn bounded sub-agents for analysis. Planning reads decisions and architecture invariants. Implementation reads only local gotchas and task-specific bundles. Verification reads contracts and prior failure logs. Retrospective writes proposed updates.

This is where parallelism becomes safe. Run independent sub-agents against the same indexed memory for security, performance, code quality, or test-failure diagnosis, but have them return findings rather than broad patches. Keep the implementation context fresh and supervised by the main loop. A long single context that researches, debates, codes, debugs, and self-reviews will accumulate accidental commitments. Fresh contexts plus repo-local memory give you continuity without conversational drift.

Verification should include proof-of-work gates that memory cannot talk its way around. Require command transcripts, test-output hashes, Playwright recordings, artifact paths, or CI links depending on the work. If a retrospective claims a rule helped, the run log should show the gate it changed. Treat agent failures as harness bugs: either the right memory was not discoverable, the wrong memory was loaded, the verifier accepted a weak claim, or the task should have been split.

Route Models And Retire Context Aggressively

Once memory is harness-controlled, cost control becomes an architecture choice instead of a budget panic. Use stronger models for ambiguous research, adversarial requirement interviews, and plan critique. Use cheaper or faster models for bounded implementation, log summarization, stale-memory scans, and independent review passes where the rubric is explicit. Track model, tokens, wall time, cache reads, and verdict per run so routing decisions are based on observed throughput, not preference.

Keep project memory vendor-neutral. Repo files, OKF-like metadata, and simple CLIs survive tool changes; hidden session state does not. This matters when splitting work across agents: one model may be better at planning pushback, another at disciplined execution, another at lean review. If memory is local and structured, the handoff is a file read, not a migration.

The final habit is deletion. Schedule memory pruning the same way you schedule dependency updates. Delete rules replaced by deterministic hooks. Collapse three similar gotchas into one sharper condition. Archive decisions that no longer match the code. Prefer a small set of high-signal memories over a comprehensive autobiography of the project. The frontier pattern is not agents that remember everything. It is agents that can resume overnight work because the repo tells them exactly what still matters, proves what happened last time, and discards the rest.

Key takeaways

  • Keep top-level agent files as routers with hard size caps, not encyclopedias.
  • Store durable knowledge in indexed OKF-style bundles so agents can traverse context progressively.
  • Keep verbose run logs separate from sparse standing instructions, then update memory through retrospectives.
  • Use state-machine harnesses to vary memory policy across research, plan, implement, verify, review, and retrospect phases.
  • Require proof-of-work gates so memory updates are grounded in evidence, not model claims.
  • Track model cost and performance per run, then route strong models to ambiguity and cheaper models to bounded checks.