Distill Coding Agent Learnings A developer built voku/agent-loop, a governed workflow for coding agents that distinguishes between temporary context, evidence, proposed learning, and approved project guidance. The system requires explicit work briefs and human approval for plans, and separates recall (rules and decisions) from code maps (structural information) to avoid context pollution. It also introduces verification steps and a three-level memory hierarchy (session state, findings, guidance) to prevent agents from repeating mistakes or acting on outdated information. Repo: https://github.com/voku/agent-loop https://github.com/voku/agent-loop Demo: https://voku.github.io/agent loop demo/ https://voku.github.io/agent loop demo/ Coding agents repeat mistakes. The obvious response is to give them more memory: MEMORY.md project-rules.md agent-notes.md lessons-learned.md MEMORY FINAL.md Soon the agent receives old decisions, temporary workarounds, copied transcripts, abandoned ideas, and rules nobody remembers approving. It has more context. It does not necessarily have better context. At some point, memory becomes landfill. The problem is not that coding agents forget too much. The problem is that most workflows fail to distinguish between temporary context, evidence, proposed learning, and approved project guidance. A transcript is not memory. A note is not a rule. A finding is not guidance. And a successful patch is not automatically a project convention. Instead of giving the agent one growing pile of context, I built voku/agent-loop around a governed workflow: php task - approved plan - selective recall - implementation - verification - recorded evidence - reviewed learning A coding agent should not begin by reading a ticket and creatively filling in everything the ticket forgot to mention. It should begin with an explicit work brief: For example: vendor/bin/agent-loop workflow plan PROJECT-123 \ --by lars \ --learning-root infra/doc/agent-learning \ --file src/Order/OrderService.php \ --file tests/Order/OrderServiceTest.php \ --goal "Reject invalid order state transitions" \ --scope "Order state validation and its tests" \ --non-goal "Do not redesign the order aggregate" \ --validate "composer phpstan" \ --validate "composer test" A human then approves that specific revision: vendor/bin/agent-loop workflow approve PROJECT-123 --by lars When the plan changes, the old revision becomes superseded , and the new one requires approval again. That sounds slightly bureaucratic until an agent performs a technically impressive refactoring nobody requested. Approval should apply to a concrete plan, not permanently to a task ID whose meaning can silently change. The agent usually needs two different kinds of context: agent-recall-compiler selects task-specific guidance. agent-map provides compact information about the relevant code. These are separate because they answer separate questions: Recall: - Which rules apply? - Which previous decisions matter? - What must be validated? Map: - Where is this class defined? - Which methods and dependencies are relevant? - What is the smallest useful code neighbourhood? The goal is not to compress the entire repository into the prompt. The goal is to avoid loading most of it. Dumping a complete AST or months of transcripts into the context window is not understanding. It is bulk data transport with unusually confident autocomplete. During implementation, the agent may need to track: That belongs in a task session. It should be inspectable, closable, and removable. Temporary observations should not silently become permanent project knowledge. A workaround that was useful for one task can become actively misleading after the code changes. A useful system therefore has at least three levels: session state temporary finding evidence to review guidance approved durable knowledge Collapsing those levels into one memory file removes the provenance that makes information trustworthy. An agent saying “done” is not evidence. The work brief already contains the expected validation commands. The loop can verify that the task state, recall output, sessions, files, and repository checks agree. For example: vendor/bin/agent-loop verify PROJECT-123 The result should be based on repository-specific checks such as: composer phpstan composer test composer cs The exact commands matter less than the rule: Validation must be declared before implementation, not invented afterwards to match whatever changed. A passing test suite also does not prove that the agent stayed inside scope. That is why workflow verification and code validation are related but separate concerns. Recall can select a rule for a task, but selection alone proves nothing. The guidance may have been: HELPFUL IRRELEVANT HARMFUL NOT USED UNKNOWN NOT USED is particularly important. A guidance item may be selected for an audit or investigation but never actually consulted. Without that outcome, selection statistics quietly become usage statistics, and the metrics begin describing a workflow that never happened. The distinction is simple: selection = the system supplied it usage = the agent consulted it outcome = whether it helped Recording those separately gives us evidence for improving recall instead of merely counting how often a file appeared in a generated prompt. After the task, the agent may record findings. A finding is evidence, not a new rule. It can become a proposal with actions such as: ADD REPLACE DELETE REJECT NO DURABLE LEARNING A human reviews the proposal before durable guidance changes. Most tasks should probably end with: NO DURABLE LEARNING Fixing one bug does not necessarily reveal a reusable project rule. Sometimes the correct lesson is simply that the bug was fixed. That conclusion has its own terminal state: ACKNOWLEDGED It is neither approved as a guidance change nor rejected as incorrect. It records that the task was reviewed and no durable change was needed. This may seem like excessive precision for one status name. It is not. When lifecycle states use the wrong verbs, audit trails gradually stop saying what actually happened. The approach became more credible when we used it to audit agent-learning itself. The audit found three real defects: NO DURABLE LEARNING had no semantically correct terminal transition.The fixes shipped in versions 0.8.2 , 0.8.3 , and 0.8.4 . None required a new agent architecture. They required: That is what real dogfooding usually finds. Not a revolutionary new autonomous platform. A missing state, an inconsistent helper call, and a silent continue . Software remains software, even after somebody adds the word “agentic” to the README. agent-loop actually does voku/agent-loop is a PHP 8.3 CLI that coordinates several focused packages: agent-kanban work and task state agent-session temporary working memory agent-recall-compiler selective project guidance agent-map compact code intelligence agent-learning governed durable learning agent-loop orchestration It does not replace maintainers, code review, static analysis, tests, or domain knowledge. It gives those existing engineering practices an explicit workflow around coding agents. A typical task looks roughly like this: vendor/bin/agent-loop board card show PROJECT-123 vendor/bin/agent-loop workflow plan PROJECT-123 ... vendor/bin/agent-loop workflow approve PROJECT-123 --by lars recall, map, implementation and review vendor/bin/agent-loop verify PROJECT-123 close the task and evaluate findings The important part is not the CLI syntax. The important part is that every transition is visible: What was requested? What was approved? Which context was selected? What changed? How was it verified? What evidence remains? Did anything deserve to become durable guidance? Coding agents do not need to remember everything. They need: More memory hides bad context management. A governed loop exposes it. And once the workflow can reject stale approvals, irrelevant guidance, unsupported claims, and accidental “lessons,” the agent does not need to behave like it remembers the entire repository. It only needs enough verified context to complete one controlled task.