[RFC] Towards Self-Evolving Agents: Interactive Instruction Distillation (/learn) and Rule Metabolism for AGENTS.md
[RFC] Towards Self-Evolving Agents: Interactive Instruction Distillation (/learn) and Rule Metabolism for AGENTS.md
1. Executive Summary & Core Philosophy
As coding agents tackle increasingly complex, multi-week software projects, they face a fundamental evolutionary bottleneck: The Amnesia-vs-Accumulation Dilemma.
- Amnesia (The Groundhog Day Problem): Without durable learning, each new session starts from scratch. Developers find themselves repeatedly steering the agent on the same repository quirks, local sandbox boundaries, tool arguments, and testing gates.
- Accumulation (The Memory Swamp & Unchecked Degradation): Naive instruction systems that only accumulate text without an explicit promotion/retirement lifecycle risk Instruction Drift and Semantic Bloat—obsolete workarounds, conflicting rules, and unverified AI speculation can gradually degrade reasoning quality. Recent empirical research (e.g., Microsoft Research's SkillOpt, arXiv:2605.23904) demonstrates that ungated, unsupervised self-edit loops can rapidly degrade model performance (collapsing from 0.554 to 0.026 in single-seed benchmarks) by overfitting to superficial patterns.
The Guiding Principle: Instruction Metabolism & Rules as Hypotheses
**True agent self-evolution is not about remembering everything; it is about metabolism—treating every rule as a falsifiable hypothesis, enforcing selective extraction, progressive refinement, and the active retirement of superseded rules under human consensus.**
Codex already has a sophisticated two-phase memory architecture (codex-rs/memories) with consolidation, pruning, deduplication, and stale-evidence cleanup. This RFC proposes extending that general philosophy into an explicit, user-visible, auditable lifecycle for authoritative instructions, bridging passive memories with developer workflows and AGENTS.md.
---
2. Analysis of Codex's Current Architecture (codex-rs)
OpenAI Codex already possesses a solid foundational memory harness:
- Phase 1 (Rollout Extraction): Asynchronously extracts
raw_memory,rollout_summary, androllout_sluginto the local SQLite state DB. - Phase 2 (Global Consolidation): An internal background agent uses a Git-backed workspace under
~/.codex/memories/to maintainMEMORY.md,memory_summary.md, and localskills/.
The existing consolidation path already performs meaningful lifecycle work: incremental updates, no-op decisions, stale-input pruning, deduplication, and removal or rewriting of memory no longer supported by evidence. The gap is therefore not “Codex lacks forgetting.” The gap is that this lifecycle is largely passive and memory-scoped, while authoritative operating instructions remain outside an equivalent user-directed promotion/revision flow.
The Critical Structural Gaps
- Isolation from Authoritative Instructions (
AGENTS.md)
codex-memories-writeupdates the memory workspace, but does not intentionally promote validated session learnings into global~/.codex/AGENTS.mdor repository-level./AGENTS.md.- Project constraints, architectural invariants, and team boundaries therefore remain outside the current memory consolidation lifecycle unless a developer edits them separately.
- Absence of In-Session Human-Agent Consensus (
/learn)
- Memory consolidation is primarily asynchronous and startup-triggered.
- Developers cannot intentionally run a distillation pass immediately after a difficult debugging session, repeated correction, or architectural decision and review the proposed durable rule changes before they are applied.
- Lack of an Explicit, User-Visible Lifecycle for Authoritative Instructions
AGENTS.mdrules do not currently have a first-class interactive lifecycle such asADD,NARROW,REPLACE, orRETIREdriven by session evidence and confirmed by the user.- Without such a lifecycle, teams must manually reconcile stale, overlapping, or overly broad instructions over time.
---
3. Proposed Architecture & System Design
┌────────────────────────────────┐
│ Active Codex CLI Session │
│ (User corrections & debug) │
└───────────────┬────────────────┘
│
User calls `/learn` │ (or Agent suggests at turn completion)
▼
┌────────────────────────────────────────────────────────┐
│ Interactive Distillation Sub-Agent │
│ (memory/instruction distillation pass) │
└────────────────────────────┬───────────────────────────┘
│
┌──────────────────┴──────────────────┐
▼ ▼
[ Rule Metabolism Engine ] [ Epistemic Layering ]
- Add: Net-new invariant - Workspace: `./AGENTS.md`
- Narrow: Restrict broad rule - Global: `~/.codex/AGENTS.md`
- Replace: Supersede old pattern - Skill: `skills/<name>/SKILL.md`
- Retire: Remove obsolete rule - Memory: `MEMORY.md`
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Human-in-the-Loop Review & Staged Diff │
│ "Proposed update to ./AGENTS.md (-2 lines, +3 lines): [Y/n]"│
└──────────────────────────────┬──────────────────────────────┘
│ (Approved)
▼
┌─────────────────────────────────────────────────────────────┐
│ Atomic Mutation to Local/Global Instruction File │
└─────────────────────────────────────────────────────────────┘
3.1 Interactive Distillation Protocol (/learn / /distill)
- Trigger: Invocable by the developer via
/learn(or suggested by Codex upon resolving a multi-turn error). - Scope Extraction: Inspects the active turn transcript and execution diff for:
- Explicit user corrections and workflow preferences.
- Validated failure shields (Symptom → Root Cause → Fix → Verification).
- Platform/environment constraints (e.g. TCC permissions, required flags, build timeouts).
- Architectural invariants or contribution rules that have become stable enough to deserve promotion.
The command defaults to a review-first flow: distill candidates, show their proposed destination, lifecycle operation, and review criteria, and only write after explicit user approval.
3.2 The Four Operations of Rule Metabolism & Rules as Hypotheses
Every authoritative-rule candidate is treated as a falsifiable hypothesis rather than an unquestioned permanent decree, and is classified into one of four discrete lifecycle operations:
ADD: Introduce a verified, net-new constraint or workflow invariant. (Optionally tagged with afalsifiable_conditionandreview_aftertimestamp).NARROW: Restrict the scope of an existing rule found to be overly broad.REPLACE: Atomically supersede an older, sub-optimal rule with a validated newer approach.RETIRE: Remove an obsolete rule whose underlying conditions no longer apply (e.g., when an upstream CLI bug is fixed or a library migration completes).
These operations are intended as an auditable interaction model, not necessarily a permanent on-disk schema. The important property is that Codex must distinguish “add another instruction” from “this evidence changes, restricts, or invalidates an existing instruction.”
3.3 Epistemic Layering & Fenced Machine Sections
Not every useful lesson belongs in AGENTS.md, and machine-distilled text should not corrupt human-authored architectural prose.
- Ephemeral Episode → Kept in local session context only; discarded on session close.
- Durable but Non-Authoritative Knowledge →
MEMORY.md/ memory artifacts. - Workspace Invariant / Team Operating Rule →
./AGENTS.md(version-controlled with project code). - Fenced Block Isolation: Distilled instructions can land in a dedicated, clearly delimited block (e.g.,
<!-- CODEX-LEARNED:START -->...<!-- CODEX-LEARNED:END -->) subordinate to hand-authored rules to preserve clean structural boundaries. - Global Developer Preference / Operating Rule →
~/.codex/AGENTS.md. - Reusable Multi-Step Procedure → Synthesized into a dedicated
skills/<name>/SKILL.md.
3.4 Variance-Aware Evaluation vs. Deterministic Constraints
- Deterministic Operational Constraints (e.g., specific CLI flags
--network-timeout 60, required path prefixes, formatters): Verified directly by the immediate tool execution/test pass during the session. - Probabilistic / Behavioral Strategy Rules (e.g., prompt reframing, high-level reasoning heuristics): Treated as empirical hypotheses; when evaluated, should be checked across multiple runs ($k=5$) against a golden regression suite rather than single-run stochastic noise.
3.5 Standing Surface Budget & Adherence-Probed Capacity Gating
Every review of an instruction file inherently suffers from build-bias: rules feel like assets, leading humans and agents to continuously accumulate instructions while rarely retiring older ones. However, as the standing instruction surface expands, model adherence to any individual rule steadily degrades.
To turn retirement into an unavoidable, first-class outcome, the architecture incorporates three complementary mechanics:
- The Forced-Choice Moment (Trade-Off Friction):
- When a newly proposed
ADDwould breach the active standing surface budget, the distillation flow halts silent addition and enforces an explicit trade-off prompt:
> "Standing surface budget exceeded. Promotion requires an explicit RETIRE or MERGE of existing rules to make room for ADD."
- This friction breaks the hoarding instinct and ensures retirement is a required operational step rather than an optional chore.
- Adherence-Probed Capacity Gating (Empirical Evidence over Task Breadth):
- Rather than allowing an agent to arbitrarily self-expand its budget based on workspace task breadth (which conflates what a user wants loaded with what the model actually follows, effectively letting the auditor grade its own homework), the capacity ceiling is bounded by measured adherence evidence.
- The workspace probes multi-rule compliance with all standing rules loaded jointly. If empirical probes demonstrate quiet rule-dropping under load, the budget ceiling is hard-locked, mandating the pruning of mediocre rules before new invariants can land.
- Path-Scoped & Skill Offloading:
- Domain-specific constraints (e.g., prose styling, database migrations, specific framework protocols) are offloaded to directory-scoped rules or on-demand skills, keeping the root
AGENTS.mdstrictly minimal regardless of user versatility.
3.6 Fail-Closed Anchor Guard & Interactive Semantic Re-Anchoring
A subtle failure mode in real-world human-agent co-editing is Anchor Drift leading to Zombie Rules:
- Developers frequently hand-edit
AGENTS.mdbetween sessions (rephrasing rules, moving lines, or tweaking formatting). - When
/learnsubsequently attempts aREPLACEorRETIREoperation, the verbatim target text no longer matches. - A naive implementation might silently fall back to
ADDinto the fenced machine section to avoid a hard error. This reports "Applied", but leaves the mutated old rule intact alongside the new rule, creating contradictory duplicates and stealthily inflating the standing surface.
To prevent this silent degradation, the engine enforces three safeguards:
- Strict Fail-Closed Invariant:
REPLACEandRETIREmust never silently degrade intoADD. If a target rule cannot be anchored with certainty, the mutation must fail-fast rather than creating a duplicate. - Interactive Semantic Re-Anchoring: When an exact verbatim match fails, the engine runs a fuzzy/semantic similarity search across
AGENTS.mdand surfaces drifted candidate lines for explicit user confirmation (Supersede this drifted line? [Y/n/select/abort]). - Machine-Block Stable Identifiers: Rules generated in the machine-managed fenced block carry lightweight stable identifiers (e.g.,
<!-- id: py-formatter -->), ensuring unambiguous targeting even if explanatory text inside the block has been lightly modified.
---
4. Proposed User Experience (CLI Walkthrough)
$ codex
> [User]: Fix the network timeout when calling the internal build cluster on macOS.
> [Codex]: ... (triages sandbox flags, discovers missing `--network-timeout 60` and TCC bypass, fixes issue and verifies) ...
> [User]: /learn
[Codex Distillation Engine]
Analyzing session transcript (Turn 1 to Turn 7)...
Checking standing surface budget (Current: 38/40 rules, 4.8KB / 5.0KB)...
Proposed Rule Updates:
1. [Project Rule -> ./AGENTS.md] (ADD)
Operation: ADD (Fenced Block)
Content: When invoking internal cluster builds, always pass `--network-timeout 60` to accommodate macOS proxy latency.
Condition: Retire if internal cluster proxy latency is resolved upstream.
Review: 2026-10-01
2. [Project Rule -> ./AGENTS.md] (REPLACE)
Operation: REPLACE
- Do not run local cluster integration tests.
+ Integration tests may be run locally if `CLUSTER_DEV_MODE=1` is set.
[Anchor Check]: Exact anchor match verified at ./AGENTS.md:L42.
3. [Global Preference -> ~/.codex/AGENTS.md] (NARROW)
Operation: NARROW
Target: "Always format Python code with flake8."
[Anchor Drift Warning]: Verbatim target not found (user hand-edited file).
Found drifted candidate at ~/.codex/AGENTS.md:L18 (94% match):
- "Always format Python code with flake8 across all projects."
Supersede drifted line L18 with new narrowed rule? [Y/n/edit]: Y
+ Default to `ruff format` across Python projects unless the repository explicitly pins a different formatter.
[Surface Budget Guard]: Proposed updates maintain headroom (39/40 rules, 4.9KB / 5.0KB).
Apply changes to instruction files? [Y/n/edit]:
---
5. Engineering Feasibility & Possible Implementation Strategy
The exact ownership boundary should follow the maintainers' preferred architecture. The proposal does not depend on introducing a specific new crate.
A plausible implementation could:
- Reuse Existing Memory Infrastructure Where Appropriate
- Reuse existing prompt rendering, secret-redaction, evidence hygiene, and workspace-diff helpers from
codex-memories-writewhere those abstractions fit.
- Add an Interactive Distillation Component
- Given the active transcript, current effective instruction files, and relevant execution diff, produce structured candidates such as
{destination, operation, evidence, proposed_diff, review_after, falsifiable_condition}. - This could live in
codex-core, the existing memories write path, or a dedicated component depending on maintainership boundaries.
- Add a First-Class CLI/TUI Binding
- Register
/learnand/or/distillas explicit user-facing commands. - Prefer a review-first flow over silent writes.
- Generate Minimal, Transactional Instruction Diffs
- Avoid rewriting whole
AGENTS.mdfiles when a narrow change is sufficient. - Preserve user-authored structure and unrelated sections.
- Place distilled rules into delimited sections or surgically edit existing lines.
- Reject or surface ambiguous edits instead of silently resolving them.
- Guard Against Instruction Bloat and Authority Escalation
- Treat “no durable change” as a valid result.
- Require stronger evidence for global rules than workspace-local rules.
- Detect semantic overlap with existing instructions before proposing
ADD. - Never silently promote transient task state, speculative conclusions, secrets, or unverified fixes into authoritative instructions.
---
6. Related Work & Literature
- #34668 — Explicit, auditable promotion of operator feedback into Memories: Focuses on memory CRUD with provenance. This RFC extends this to authoritative instruction surfaces (
AGENTS.md). - #32748 — User-facing workflow retrospective / insights: Asynchronous retrospective recommendations. This RFC targets the in-session transactional
/learnpath. - #21932 — Allow
/initto update existingAGENTS.md: Initial repository generation vs. continuous empirical distillation. - SkillOpt (Microsoft Research, arXiv:2605.23904): Empirically frames agent instructions as optimizable weights and proves that un-gated self-evolution leads to catastrophic degradation, validating the necessity of strict human review and held-out validation gates.
- Agent Workspace Architecture Patterns (jimy-r/agent-workspace-architecture): Documents practical patterns for heavily-instructed workspaces—specifically treating scaffolds as hypotheses and enforcing variance-floor regression checks.
The intended composition is:
passive memory consolidation
+
explicit memory promotion / management
+
user-visible retrospectives
+
interactive authoritative-rule distillation (with hypothesis gating)
↓
safer long-term agent adaptation
---
7. Conclusion
Codex already contains much of the hard infrastructure needed for durable learning: persisted rollouts, structured extraction, consolidation agents, a Git-backed memory workspace, pruning, deduplication, skills, and authoritative AGENTS.md instruction chains.
The missing piece is a deliberate promotion boundary between “the agent learned something from experience” and “this should now govern future work as an authoritative rule.”
An interactive /learn / /distill flow could make that boundary explicit, reviewable, and auditable:
experience → evidence → candidate hypothesis → lifecycle operation → human-reviewed diff → durable instruction
That would let Codex evolve across long-running projects without turning either memory or AGENTS.md into an unbounded accumulation of historical text.
8 Comments
The metabolism framing matches what we converged on running a heavily-instructed workspace, with one addition your lifecycle needs to be honest: every promoted rule is a hypothesis, so register it with a falsifiable claim and a review date, and retire it when it can't beat baseline. The subtle failure isn't the memory swamp you name, it's rules that feel like upgrades and were never checked.
Two mechanics that made ours work: (1) measurement uses a small golden-set regression suite replayed under a variance floor (each case run k=5, scored as pass-rate ± stddev, never a single run — LLM outputs are stochastic and one-run comparisons are noise dressed as signal); (2) machine-proposed edits land in a fenced block subordinate to hand-authored rules, and adoption is gated (SkillOpt's own result is instructive: accept an edit only when a held-out split strictly improves; ungated accept loops degraded to near-zero).
Written up here: https://github.com/jimy-r/agent-workspace-architecture/blob/main/PATTERNS.md#11-a-scaffold-is-a-hypothesis--gate-it-behind-a-measurable-signal
Thanks for the incredibly sharp feedback and references, @jimy-r!
The framing that "a scaffold is a hypothesis" and the reference to SkillOpt (arXiv:2605.23904) pinpoint the exact failure mode I want to prevent: the illusion of progress through unchecked accretion.
I have just updated the main RFC description above to directly incorporate these insights:
falsifiable_conditionandreview_aftermetadata to rule candidates (and CLI walkthrough) soRETIREoperations have deterministic triggers.Really appreciate you sharing the pattern library—it adds immense rigor to this proposal!
One refinement for the RETIRE path now that the metadata is in. Make removal a first-class outcome and weight it deliberately, because every review of an instruction file is build-biased. Rules feel like assets, so the review question needs to cover both whether the rule beat baseline and what the always-loaded surface costs as a whole. Adherence to any single rule degrades as the loaded set grows, which means retiring a mediocre rule often improves the rules that remain. The mechanism we use is a hard cap on the standing surface, treated as a budget the whole set must fit inside, so every promotion above the cap forces an explicit trade rather than silent accretion.
Spot-on analysis on points 1 and 2, @jimy-r — build-bias and the adherence degradation curve are real failure modes. Treating rule retirement as a first-class, deliberate outcome (rather than an afterthought) is essential for any sustainable rule metabolism.
Regarding point 3 (the hard surface budget), I strongly agree that an unconstrained surface leads to silent accretion, but I would offer a nuanced perspective on how that budget is structured and enforced:
1. The Scaling Factor: Model Attention Robustness vs. Scope Breadth
While adherence does degrade as the standing surface grows, frontier models have become noticeably more robust at in-context steering across long sequences compared to earlier generations.
However, the bigger challenge with a single, static, one-size-fits-all hard cap is workspace heterogeneity:
Imposing a rigid global ceiling across all personas would either choke multi-domain workspaces or be too loose to constrain narrow ones.
2. Proposed Synthesis: Tiered Budgets, Dynamic Scoping, and Profile-Aware Sizing
Instead of a uniform hard cap, I suggest modeling the standing surface budget through three complementary mechanisms:
budget: strict (2KB) | balanced (5KB) | comprehensive (10KB)or a custom token/character ceiling). When a newly promoted rule would push the surface over the active budget, the CLI enforces the trade-off: "Surface budget exceeded. Please choose a rule to RETIRE/MERGE, or explicitly adjust the workspace budget."AGENTS.md. Broad multi-domain knowledge should be offloaded to directory-scoped rules, specialized skills, or on-demand task projections, keeping the standing root lean regardless of total breadth./learnaudits, the agent can inspect the variance of tasks across the workspace and suggest an appropriate capacity baseline tailored to that specific user profile.Enforcing an explicit trade-off whenever a persona-appropriate budget is breached strikes the right balance: it guarantees discipline against silent accretion without arbitrarily penalizing multi-disciplinary workspaces.
Agreed on offloading and profile heterogeneity — path-scoped loading solves most of it in practice (our writing rules load only in prose lanes, and the root file stays lean because of it).
The one piece I'd defend from operating experience: the budget's value is not its size, it's the forced-choice moment. "Surface exceeded — retire or merge before adding" is where retirement actually happens; without that moment it never does, whatever the ceiling is. So tiered capacities work fine, but the trade-off prompt is the load-bearing part of your synthesis.
Where I'd push back: agent-assisted sizing from task variance risks the auditor grading its own homework. Breadth of work says what a user wants loaded; it says nothing about what the model still follows. The sizing signal that held up for us is adherence evidence — probe rule-following with everything loaded together, at the current size, and let measured degradation set the ceiling. A workspace that follows 40 rules has earned 40; one that quietly drops rule 12 has not, however varied its tasks.
100% aligned, @jimy-r — you've pinpointed the exact load-bearing mechanics:
The Complete Rule Metabolism Loop
Combining your insights with the proposal yields a robust, closed-loop lifecycle:
ADDcandidate breaches the active budget, the CLI halts and demands an explicitRETIREorMERGEtrade-off before writing.I have updated the RFC description above to integrate both the forced-choice trade-off mechanic and adherence-probed capacity gating into the core architecture and CLI walkthrough.
Huge thanks for refining this into a battle-tested engineering blueprint!
the [Y/n] approval is where this quietly under-delivers. REPLACE only supersedes if it finds the old line, but AGENTS.md gets hand-edited between sessions, so once the target text drifts REPLACE can't anchor. the safe-looking fallback is to ADD into the fenced block instead of failing, so the old rule survives, the flow still reports applied, and you've grown exactly the bloat the surface budget exists to kill. the guard you'd want fires on 'REPLACE couldn't locate its anchor', not just on ambiguous edits.
Brilliant and critical edge-case catch, @m13v!
You have exposed a subtle but lethal failure mode in real-world human-agent co-editing: Anchor Drift leading to Zombie Rules.
If a user manually tweaks wording between sessions, an exact-string
REPLACEloses its anchor. Silently falling back toADDis the worst possible compromise—it reports success while leaving the mutated old rule intact alongside the new one, creating contradictory duplicates and stealthily bloating the standing surface.Incorporating the Fail-Closed Anchor Guard
I have integrated this into the RFC with three concrete mechanisms:
REPLACEandRETIREmust never silently degrade intoADD. If the target rule cannot be anchored with certainty, the mutation must fail-fast rather than creating a duplicate.```text
[Anchor Drift Warning]: Target text for REPLACE was not found verbatim.
Found drifted candidate at ./AGENTS.md:L34 (92% similarity):
Supersede this line? [Y/n/edit-line/abort]:
```
<!-- id: py-formatter -->), allowing unambiguous targeting even if the user lightly edits the explanatory prose inside the block.This closes the loop between human manual maintenance and automated distillation.
I’ve updated Section 3 and the CLI walkthrough in the main RFC description to reflect this anchor guard. Really appreciate you calling this out!