NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
Packagist
Working-memory layer for coding agents: per-task session plans, decisions, assumptions, checkpoints, claim metadata, and retention.
Last release 25 days ago
13 Sep 2026
Ships fairly regularly
a new release about every 9 days
Nearly every release is documented
notes for 15 of 16 stable releases
Nothing withdrawn
no release was ever pulled
3 months old
16 releases · first in 2026
One column per month.
Merge branch 'feature/scoped-package-resources'
Merge branch 'feature/scoped-package-resources'
PackageResources: consumerSkills() returns an empty array, and maintainerSkills() explicitly classifies agent-session-maintainer as an owner repository skill.PackageResources is the single owner of package-shipped resource locations,
matching agent-loop, agent-map, agent-learning, and
agent-recall-compiler. Hosts that projected assets by spelling
vendor/voku/agent-session/... themselves can ask for SKILLS /
skillsRoot() instead, so a future layout change stays a fact of this package.resources/skills/agent-session-maintainer/SKILL.md ships the maintainer
guidance for agents changing this package: dependency direction, the
invariants a change has to preserve, and the declared validation gate.docs/ now holds the CLI reference (docs/cli.md) and the typed host
integration contract (docs/php-api.md), indexed by docs/README.md. The
README keeps the overview, requirements, install, and a quick start.UPGRADING.md records breaking changes, starting with the
session_plan/ -> .agent-loop/sessions/ sessions-root move that was
previously documented only inside the README.Makefile exposes the same install / test / phpstan / ci entry
points the sibling packages use.installed-consumer job that installs the package into a clean
Composer consumer and a dist-hygiene job that checks the released
git archive ships resources/skills while excluding tests, phpunit.xml,
phpstan.neon.dist, and the Makefile. A Composer path repository copies the
directory verbatim, so export-ignore can only be verified against a real
archive..gitattributes marks development-only surfaces export-ignore, so released
archives no longer ship .github/, tests/, phpunit.xml,
phpstan.neon.dist, or the Makefile.UPGRADING.md records breaking changes, starting with the session_plan/ -> .agent-loop/sessions/ sessions-root move that was previously documented only…
PackageResources is the single owner of package-shipped resource locations,
matching agent-loop, agent-map, agent-learning, and
agent-recall-compiler. Hosts that projected assets by spelling
vendor/voku/agent-session/... themselves can ask for SKILLS /
skillsRoot() instead, so a future layout change stays a fact of this package.resources/skills/agent-session-maintainer/SKILL.md ships the maintainer
guidance for agents changing this package: dependency direction, the
invariants a change has to preserve, and the declared validation gate.docs/ now holds the CLI reference (docs/cli.md) and the typed host
integration contract (docs/php-api.md), indexed by docs/README.md. The
README keeps the overview, requirements, install, and a quick start.UPGRADING.md records breaking changes, starting with the
session_plan/ -> .agent-loop/sessions/ sessions-root move that was
previously documented only inside the README.Makefile exposes the same install / test / phpstan / ci entry
points the sibling packages use.installed-consumer job that installs the package into a clean
Composer consumer and a dist-hygiene job that checks the released
git archive ships resources/skills while excluding tests, phpunit.xml,
phpstan.neon.dist, and the Makefile. A Composer path repository copies the
directory verbatim, so export-ignore can only be verified against a real
archive..gitattributes marks development-only surfaces export-ignore, so released
archives no longer ship .github/, tests/, phpunit.xml,
phpstan.neon.dist, or the Makefile.SessionStore::load() now enforces the session.json schema boundary that Session metadata already publishes. Schema 1.0 and 1.1 are read explicitly; mi
SessionStore::load() now enforces the session.json schema boundary that
Session metadata already publishes. Schema 1.0 and 1.1 are read
explicitly; missing, malformed, future, or otherwise unsupported versions
fail closed with UnsupportedSessionMetadataVersion instead of being
reinterpreted through current field defaults. A normal owner mutation of a
supported 1.0 Session rewrites it through the current 1.1 shape without
changing Session or task identity, while pruned working memory still uses
exact-ID rehydrate() rather than migration machinery.[*]: update the changelog
[*]: update the changelog
SessionStore::reopen() and agent-session reopen <id> --reason TEXT bring a
Session closed as done back to active. A governed Run binds to exactly one
Session id, so without this transition the Run was sealed by its own close: work
that legitimately continues afterwards - for example a follow-up change demanded
by the closing Run's review gate - could neither reuse the bound Session (closed)
nor a freshly started one (different id). The transition is deliberately narrow:
only done reopens (dropped states an abandoned Session and stays final), the
task must have no other open Session, and the required reason is recorded as a
Session reopened checkpoint so it survives the cleared closed_reason field.SessionStore::activeForTask(), openForTask() and allForTask() own the "one open governed Session per task" rule. create() and rehydrate() refuse to al
SessionStore::activeForTask(), openForTask() and allForTask() own the
"one open governed Session per task" rule. create() and rehydrate() refuse to
allocate parallel open working memory for the same task, while the selection
APIs let reporting callers expose legacy or externally-corrupted ambiguity
instead of silently picking a winner.Session::$closedAt / $closedReason and SessionStore::close() record
why working memory stopped being open while that pruneable Session still
exists. Durable lifecycle provenance that must survive Session pruning remains
owned by the durable lifecycle package rather than leaking back into working
memory.agent-session close <id> --reason TEXT and agent-session list --task ID.activeForTask() both ignore ephemeral Sessions. An
experiment is never approved and never meant to be finished, so nobody closes
it; counting it would let a forgotten throwaway block its task's governed
working memory permanently, which is the failure the flag exists to prevent.
The resume lookup counts exactly what the allocation rule counts, so a state
create() permits is never reported as corruption. openForTask() remains
the raw view and still reports an experiment, because it is genuinely open.SessionHandoffProjector / SessionHandoff and agent-session handoff <id> [--format md|json] project a compact resume packet out of a Session's own
working memory: goal, next action, latest checkpoint, recorded decisions and
assumptions, plus validation history. The projection deliberately does not
infer which assumptions are still unvalidated or which historical validation
describes the current implementation. The packet is derived on read, never
stored, so working memory stays pruneable and no second source of durable
truth or lifecycle authority appears.ValidationEvidenceStore::select() and ValidationEvidenceSelection answer
"is this obligation validated for this exact state?". Exact-state selection
requires both the Contract revision and implementation snapshot. Snapshotless
legacy observations remain readable but cannot satisfy a snapshot-bound
currentness question. The selection reports never-recorded, superseded
implementation, and superseded Contract revision separately instead of
allowing historical PASS evidence to read as current.SessionStore::setStatus() refuses to
reopen it or relabel it as the other closed status, and repeating the identical
close is idempotent. create() allocates fresh working memory and
rehydrate() restores caller-authorized historical identity, but both reject a
task that already has open working memory.SessionHandoff::recordedFailures() exposes historical failed observations by
name instead of implying they are the current validation verdict. Markdown
output labels validation as history and carries Contract revision plus
implementation snapshot identity for every observation.Cli writes to php://output / php://stderr instead of the STDOUT /
STDERR constants, and accepts explicit streams. A PHP host embedding the CLI
in-process can now capture or discard its output with ordinary output
buffering, instead of installing a stream filter to silence a library it
called itself.session.json is schema 1.1. The added fields are optional and 1.0
metadata still loads unchanged.SessionStore::rehydrate() can recreate pruneable working memory at an exact, already-authoritative Session ID after pruning or a clean checkout. It re
SessionStore::rehydrate() can recreate pruneable working memory at an exact,
already-authoritative Session ID after pruning or a clean checkout. It rejects
unsafe IDs and existing paths instead of deriving a new date-based identity or
overwriting surviving Session state.dev-main again matches the current 0.6 release line instead of advertising
the stale 0.5.x-dev alias.Breaking: validation evidence may carry the deterministic implementation snapshot observed by the validation command. Governed consumers can now rejec
validation record accepts --implementation-snapshot sha256:<digest> and
persists that opaque identity without trying to compute repository state in
agent-session itself.Session becomes what its name claims: disposable working memory for one governed Run. Everything a Run must still be able to explain after its Session
Session becomes what its name claims: disposable working memory for one governed Run. Everything a Run must still be able to explain after its Session is pruned now belongs to the package that owns it.
Breaking: Session no longer owns durable approved work. WorkBrief,
WorkBriefStatus, WorkBriefStore, Approval and OperatingPromptSelection
are removed. A durable Contract and its approval are owned by agent-loop,
which persists them before any Session exists.
Breaking: Session no longer owns Learning close-out. LearningDecision,
LearningDecisionRecord and LearningDecisionStore are removed.
agent-learning owns the durable run Learning decision.
Both removals delete a real contradiction rather than move code: while Session held them, pruning working memory destroyed the evidence that explained why a Run was allowed to close.
<cwd>/.agent-loop/sessions instead of <cwd>/session_plan. Explicit
--root remains authoritative. Existing state is not copied, symlinked, or
dual-written; migrate session_plan/ explicitly or keep selecting it with
--root session_plan.Consumers that read Session-owned work briefs, approvals or learning decisions must read them from their new owners. There is no compatibility shim: a pre-1.0 breaking migration that silently kept answering from the old location would reintroduce exactly the ambiguity this release removes.
Work briefs can now seal an explicit operating-prompt policy together with the task goal, scope, non-goals, validation commands, tags, and behavior an
bool|int|string arguments. This lets an orchestrator such
as voku/agent-loop approve the L2 recipe and its thresholds as part of the
same revision that authorizes the implementation.OperatingPromptSelection value object and JSON projection for
operating-prompt selections. Prompt identifiers and arguments are normalized
and validated before they enter the WorkBrief rather than being carried as
unstructured orchestration metadata.dev-main now follows the 0.4.x-dev release line.status=passed with a non-zero exit code.
Contradictory execution evidence is rejected instead of being persisted as a
successful validation result.0.3.0 - distinguish experiments from governed sessions
0.3.0 - distinguish experiments from governed sessions
session start --ephemeral marks a session as an experiment: created to try a
command out, never approved, never meant to be finished. The flag is persisted
as ephemeral in session.json and survives reload and status changes.
Session::$ephemeral defaults to false, so a session written before the flag
existed still counts as governed work - defaulting the other way would let old
sessions quietly escape every repository gate.vendor/
directory. When one is present next to an installed copy - a path repository, a
mirrored checkout, a stale local install - that autoloader wins and silently
loads its dependencies instead of the project's. Found by a release-set smoke
test that reported Undefined property Session::$ephemeral against an
installed version that plainly had it. The outer autoloader is now tried first.agent-loop verify for every other session until it was explicitly dropped.
The gate was correct; the model was missing a way to say "this was never
governed work".docs: prepare 0.2.2 release
docs: prepare 0.2.2 release
--behavior-anchor on brief create/brief revise). Anchors preserve the
concrete behavior that must remain true while agents plan, implement, and
review a change. Briefs without anchors remain fully compatible.Recall consumers can match a fact against a task by shared tag even when neither side's path is a prefix of the other, so cross-cutting knowledge (e.g
Recall consumers can match a fact against a task by shared tag even
when neither side's path is a prefix of the other, so cross-cutting
knowledge (e.g. an LDAP learning) isn't tied to directory layout.
Co-Authored-By: Claude Sonnet 5 noreply@anthropic.com
tags (via --tag on
brief create/brief revise), independent of --scope paths. Recall
consumers such as voku/agent-recall-compiler can match facts against
these tags even when a task's files share no path prefix with the fact's
scope. Purely additive: briefs without tags decode and behave exactly as
before.[*]: update the changelog
[*]: update the changelog
findings_recorded,
no_durable_learning, or follow_up_required.[*]: update the changelog
[*]: update the changelog
Revisioned, session-local work briefs with explicit candidate, approved, and superseded states.
agent-session brief create, revise, approve, and show commands.Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →