PHPackages                             voku/agent-loop - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. voku/agent-loop

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

voku/agent-loop
===============

Umbrella package and unified CLI for the governed agentic-coding loop: board (kanban), learning, and recall-compiler.

0.0.3(today)14↑2900%MITPHPPHP ^8.3CI passing

Since Jun 20Pushed todayCompare

[ Source](https://github.com/voku/agent-loop)[ Packagist](https://packagist.org/packages/voku/agent-loop)[ Docs](https://github.com/voku/agent-loop)[ RSS](/packages/voku-agent-loop/feed)WikiDiscussions main Synced today

READMEChangelogDependencies (6)Versions (6)Used By (0)

Agent Loop (`voku/agent-loop`)
==============================

[](#agent-loop-vokuagent-loop)

`agent-loop` is one boring CLI for coding-agent DX. It does not think, decide, or remember anything itself — it routes a stable set of commands to the packages that do.

The problem it solves
---------------------

[](#the-problem-it-solves)

A realistic coding-agent workflow needs a board to pick work from, a session to hold working memory while a task is in progress, a compiler that selects relevant context instead of dumping everything into the prompt, and a learning loop that turns findings into durable rules without overreacting to noise. Each of those is its own focused package. Wiring them by hand means a different `vendor/bin/...` invocation per concern, which nobody — human or agent — keeps straight across a long session.

`agent-loop` exists only to remove that friction: one binary, one stable command vocabulary, zero shared state of its own.

Package map
-----------

[](#package-map)

```
                ┌──────────────────────────── voku/agent-loop ───────────────────────────┐
  agent-loop →  │  board    →  voku/agent-kanban           (TODO Kanban board + Jira sync) │
                │  verify   →  voku/agent-loop              (cross-package consistency)    │
                │  board:verify → voku/agent-kanban         (TodoBoardVerifier, board only) │
                │  session  →  voku/agent-session           (working memory per task)      │
                │  recall   →  voku/agent-recall-compiler   (L2 meta-prompt compilation)    │
                │  learn    →  voku/agent-learning          (findings → proposals → history)│
                │  memory   →  voku/agent-loop               (MEMORY.md promotion review)    │
                └─────────────────────────────────────────────────────────────────────────┘

```

NamespacePurposeOwning package`board`Pick work from a Markdown/Jira Kanban board`voku/agent-kanban``session`Working memory for an in-progress task`voku/agent-session``recall`Compile task-scoped context (L2 meta-prompt)`voku/agent-recall-compiler``learn`Findings → proposals → reviewed decision history`voku/agent-learning``verify`Cross-package consistency check (the only thing that looks at all of the above at once)`voku/agent-loop``board:verify`Narrow check of the kanban board source only`voku/agent-kanban``memory``MEMORY.md` promotion review`voku/agent-loop`Requirements
------------

[](#requirements)

RequirementVersionPHP8.3 or newerComposerrequiredInstallation
------------

[](#installation)

```
composer require voku/agent-loop
```

This installs `voku/agent-kanban`, `voku/agent-session`, `voku/agent-recall-compiler`, and `voku/agent-learning` as dependencies and exposes `vendor/bin/agent-loop`.

Basic workflow
--------------

[](#basic-workflow)

Start with the smallest useful loop — one task, one session, one compiled briefing:

```
agent-loop session start --task ABC-123 --by lars --base-commit "$(git rev-parse HEAD)"
# -> Started session: 2025-01-15-abc-123

agent-loop recall compile --root infra/doc/agent-learning --task ABC-123 --file src/Foo.php

# ...do the work...

agent-loop session record ABC-123 --kind decision --title "Keep change scoped" --body "..."
agent-loop session checkpoint ABC-123 --title "Validation" --body "PHPStan passed."
agent-loop verify
agent-loop session close ABC-123 --status done
```

`session start` prints its own generated **session id**(date-prefixed, e.g. `2025-01-15-abc-123`) on its first line. You don't need to capture it: `session record`/`checkpoint`/`close`/`claim`/`show`also accept the task id you started the session with — `agent-loop`resolves it to the matching session id before delegating. The session id still works directly if you have it (e.g. from a list of multiple sessions for the same task). Likewise, `recall compile --task ABC-123`without `--output-dir` writes to `recall/ABC-123/` automatically, where `agent-loop verify`'s recall-coverage check expects to find it; pass `--output-dir` explicitly only to override that default. See [`examples/basic-loop`](examples/basic-loop) for this full sequence run against a tiny fake task with real captured output.

Add the board once you have more than one task in flight, and the learning loop once you want findings to survive past a single session:

```
agent-loop board next-pull
agent-loop learn validate --root infra/doc/agent-learning
agent-loop learn guidance-evaluate --root infra/doc/agent-learning
```

Exact available commands
------------------------

[](#exact-available-commands)

Every command below is real and was verified against this repository's installed dependencies (`composer require`'d versions); none of it is aspirational. Run `agent-loop  help` (or `--help`) for a namespace's own usage.

```
agent-loop --help                 # top-level namespaces
agent-loop learn --help           # commands for a namespace
agent-loop recall --help
agent-loop session --help
agent-loop board --help

# board: reads cards from todo/jira/-N.md (one file per ticket;
# optional todo/board.md sets the project prefix and done count). Falls
# back to a single legacy TODO.md only if todo/jira/ doesn't exist.
agent-loop board summary
agent-loop board render --lanes=READY,BACKLOG --limit=10
agent-loop board next-pull
agent-loop board ticket ABC-123

# session: working memory for one task
agent-loop session start --task ABC-123 [--by ACTOR] [--base-commit SHA] [--slug S]
agent-loop session claim  --by ACTOR [--base-commit SHA] [--force]
agent-loop session checkpoint  --title T [--body TEXT]
agent-loop session record  --kind decision|assumption --title T [--body TEXT]
agent-loop session close  --status done|dropped
agent-loop session list [--status STATUS]
agent-loop session show
agent-loop session prune [--keep-days N] [--status done,dropped] [--dry-run]

# recall: compile a task-scoped briefing
agent-loop recall compile --root infra/doc/agent-learning --task ABC-123 --file lib/foo.php
agent-loop recall log-outcome --root infra/doc/agent-learning --by lars --commit abc1234

# learn: findings, proposals, decision history
agent-loop learn validate --root infra/doc/agent-learning
agent-loop learn guidance-evaluate --root infra/doc/agent-learning
agent-loop learn proposal-validate --proposal proposals/candidate/proposal.001.json
agent-loop learn proposal-approve --by lars proposals/candidate/proposal.001.json
# (also: prepare, proposal-import, proposal-reject, proposal-mark-applied,
#  constraint-export, constraint-activate, constraint-loop, finding-transition)

# verify: the safety net — see below
agent-loop verify

# memory promotion review
agent-loop memory review --file MEMORY.md
```

`agent-loop board jira-sync` needs a `JiraIssueProvider`. The bare binary does not wire one (Jira clients are host-specific) — see "Programmatic use" below.

`agent-loop verify`: the safety net
-----------------------------------

[](#agent-loop-verify-the-safety-net)

Every other namespace delegates outward and stops there. `verify` is the one command that looks *across* board, session, recall, and learning state at once and answers: **is this repo's agent workflow state internally consistent?**

```
agent-loop verify
```

Checks, each of which prints `[OK]`, `[SKIP]`, or `[FAIL]` and skips itself when its inputs are absent (so the command stays meaningful for a repo that only wires up part of the stack):

- **package delegates** — board/learn/recall/session classes are installed and resolve
- **tasks** — every `*.md` file under `tasks/` parses (non-empty, has a heading)
- **board** — `TODO.md` kanban board projection (delegated to `voku/agent-kanban`)
- **sessions** — every non-closed session under `session_plan/` points to a known task id
- **recall** — every active session has a compiled briefing, and every `recall//meta.json` output hash still matches the file on disk (catches a briefing edited or regenerated out of band)
- **learning root** — findings, proposals, and decision/outcome history validate

Run `agent-loop verify --help` for the override flags (`--tasks-root`, `--sessions-root`, `--recall-root`, `--learning-root`). `agent-loop board:verify` remains available as the narrower, board-only check this command used to be.

What `agent-loop` deliberately does not do
------------------------------------------

[](#what-agent-loop-deliberately-does-not-do)

> agent-loop is not the learning engine. agent-loop is not the session store. agent-loop is not the recall compiler. agent-loop is the command surface.

Concretely, `agent-loop`:

- holds no working memory of its own — sessions live in `voku/agent-session`'s files, not in this package
- makes no decisions about what counts as a durable lesson — that judgment lives in `voku/agent-learning`
- selects no context for a prompt — selection logic lives in `voku/agent-recall-compiler`
- owns no board data — board state lives in whatever Markdown/Jira source `voku/agent-kanban` reads
- adds no scheduler, hidden state machine, or plugin lifecycle — `voku/housekeeping` is the runner; this is just the loop

If a feature needs new durable state, it belongs in one of the focused packages, not in `agent-loop`. The moment this wrapper starts hiding state of its own, it has become the second source of truth this whole stack was built to avoid.

Programmatic use (host wiring)
------------------------------

[](#programmatic-use-host-wiring)

Hosts that already have a Jira client wire it once and reuse the whole CLI:

```
use voku\AgentKanban\JiraIssueProvider;
use voku\AgentLoop\Dispatcher;

$provider = new class implements JiraIssueProvider {
    public function projectKey(): string { /* ... */ }
    public function searchIssues(string $jql): array { /* ... */ }
};

exit((new Dispatcher($rootPath, $provider))->run($argv));
```

That single wrapper replaces per-library glue scripts: every `board`/`verify`/`session`/`recall`/`learn`/`memory` command flows through it.

Auto-running it on a schedule
-----------------------------

[](#auto-running-it-on-a-schedule)

`voku/agent-loop` is the *loop*; [`voku/housekeeping`](https://github.com/voku/housekeeping)is the *runner*. Install Housekeeping in its own checkout, point it at your target repository, and let it invoke `agent-loop` commands (board refinement, verification, recall, …) from cron in safe patch mode.

Development
-----------

[](#development)

```
composer install
composer ci    # composer validate --strict + phpunit + phpstan (level 8)
```

`tests/fixtures/basic-loop` is a minimal end-to-end fixture (`SmokeLoopTest`) proving the orchestration shape: a task file exists, a session starts against it, recall compiles a briefing, learn validates the root, and `agent-loop verify` reports no drift — then fails on purpose once a briefing goes missing or gets edited out of band. [`examples/basic-loop`](examples/basic-loop)walks through the same shape by hand, with real command output, for reading or running yourself.

License
-------

[](#license)

MIT — see [LICENSE](LICENSE).

###  Health Score

41

—

FairBetter than 87% of packages

Maintenance100

Actively maintained with recent releases

Popularity7

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity42

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 66.7% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

3

Last Release

0d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/6456fe693db197c458272cb758bf78958bc7d3e787ccd59db4bf3cf41654316a?d=identicon)[voku](/maintainers/voku)

---

Top Contributors

[![claude](https://avatars.githubusercontent.com/u/81847?v=4)](https://github.com/claude "claude (4 commits)")[![voku](https://avatars.githubusercontent.com/u/264695?v=4)](https://github.com/voku "voku (2 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Type Coverage Yes

### Embed Badge

![Health badge](/badges/voku-agent-loop/health.svg)

```
[![Health](https://phpackages.com/badges/voku-agent-loop/health.svg)](https://phpackages.com/packages/voku-agent-loop)
```

###  Alternatives

[elhebert/laravel-sri

Subresource Integrity hash generator for laravel

39241.9k](/packages/elhebert-laravel-sri)[mtdowling/burgomaster

Packages up PHP packages into zips and phars

2780.9k12](/packages/mtdowling-burgomaster)[francescomalatesta/laravel-circuit-breaker

A circuit breaker pattern implementation for the Laravel framework

2919.2k2](/packages/francescomalatesta-laravel-circuit-breaker)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
