akm-cli
Version:
akm (Agent Knowledge Manager) — a portable, local-first capability library for AI agents. Discover, load, share, and improve reusable skills, scripts, workflows, and knowledge across any shell-capable coding agent, including Claude Code, OpenCode, and Cur
133 lines (117 loc) • 7.69 kB
Markdown
Migration notes for akm v0.9.17
Run this after upgrading:
```sh
akm migrate apply
akm task sync
```
akm migrate apply reads config.json through the normal load pipeline and
writes its current shape back under a backup, dropping every retired key it
finds -- run it with --dry-run first to see the exact list for your config.
From 0.9.16, that includes index.graph.*, index.metadataEnhance,
search.minScore, search.graphBoost.*, improve.utilityDecay.*, and a dozen
smaller ones. None of them do anything any more -- leaving them in
config.json is harmless until you run migrate apply, which drops them for
good. It also deletes files nothing reads any more: 0.9.16's transaction
journals ($DATA/txn/ and $DATA/txn-quarantine/), its maintenance barrier
lock, and the maintenance-activities/ registry, which leaked an entry per
process and reached 927 MB on one host. It also drops a leftover
improve.strategies["graph-refresh"] override block, but not
defaults.improveStrategy: "graph-refresh" itself -- if you set that, change
it to a different strategy by hand, since graph-refresh now refuses
outright, naming the retirement, rather than quietly running as a no-op. The
shipped akm-graph-refresh-weekly task template is gone; remove or repoint
any task that used it. Separately, akm search --no-project-context and akm
proposal drain --policy/--max-diff-lines now fail as unknown flags; drop
them from any script or task that still passes them.
The first akm index after upgrading migrates index.db to layout 26 in
place -- for a 0.9.16 index this includes a one-time full-text rebuild it
was already due for, so budget a few seconds for a 24k-entry index rather
than a fraction of one. This also drops the LLM entity-graph tables -- the
per-file entity/relation extraction that fed akm show's old related list is
retired -- and ends with a VACUUM that reclaims the space both steps free;
akm index has never VACUUMed index.db before, so this is the first time it
happens at all, not a repeat of something 0.9.16 already did. Nothing is
re-embedded by this migration.
Embeddings are a separate matter if you use a nomic-embed or E5 model:
akm index now sends the model's own document template (nomic:
"search_document: ", E5: "passage: ") instead of the raw text, which changes
what gets embedded, so every entry re-embeds once on the next akm index.
Qwen3, the BGE/mxbai/arctic family, and the default local model have no
document template and keep their stored vectors untouched. Set
embedding.documentTemplate: "" if you'd rather keep the old vectors than pay
for a full re-embed. If you had index.metadataEnhance on before upgrading
(it defaulted off), run akm index --full once afterward to replace the
LLM-written descriptions it left behind with the plain deterministic ones --
an ordinary incremental akm index does not touch them.
The first akm task sync after upgrading rewrites every akm-managed
scheduler row once, in place. Each row now sets its own AKM_BUNDLE_DIR
(plus any AKM_CONFIG_DIR/AKM_DATA_DIR/AKM_CACHE_DIR/AKM_STATE_DIR the
syncing shell had set explicitly) inline, instead of pointing at a
--scheduler-context <file> descriptor, and a crontab's PATH moves the same
way, into a # akm:env block next to the task rows. The rewrite keeps each
row's existing launcher and schedule -- it is reported as an update, never
an add or a remove -- and rows written by 0.9.0 through 0.9.16 keep firing
normally until that sync runs. Once akm task doctor lists no binding still
pointing at a descriptor file, the old $DATA/tasks/context/ files can be
deleted.
akm improve now reworks only what retrieval actually returned -- an asset a
real search, curate, show, or feedback touched in the last 90 days -- plus
material no improve stage has processed yet. The proactive-maintenance and
high-salience lanes, and the memory consolidation judge, no longer reach
into the unread tail of a stash; an asset left out this way shows up under a
new retrieval gate in akm improve --dry-run and under akm health's
not_retrieved skip reason, not silently.
Consolidation gets a second pass. It compares each new-or-changed memory,
flat knowledge/ file, or lesson against its nearest neighbours, and where an
LLM judge calls a pair duplicate, subsumed, or superseding, it mints a
reviewed retire proposal for the losing side -- nothing is retired
automatically. Review these like any other proposal: akm proposal list
--generator consolidate-pair (or just akm proposal list, which flags one
carrying continuity risk inline), show, diff, then accept or reject.
Accepting one archives the losing file instead of deleting it, and akm
proposal revert restores it exactly; archived files are only deleted 30 days
after retirement, and only once git holds them clean and unmodified.
Accepting a promotion (a consolidate promote proposal, by a person or by
triage auto-promotion) now also archives the source memory it was promoted
from, so a promotion no longer leaves a duplicate sitting next to the
knowledge doc it produced.
akm proposal drain, and improve's own triage pre-pass, no longer take a
policy. Both now accept only a proposal the quality judge passed on its
exact content and reject an empty diff; everything else goes to
processes.triage.judgment or waits for review -- including extract and
consolidate proposals, which used to be auto-accepted on size alone under
the personal-stash default.
akm show no longer has a related field. It lists an asset's links instead:
the relations a bundle already declares -- cross-references, supersededBy,
a .derived memory's parent, a wiki's citations, resolved page links, a
workflow's or task's target -- grouped outgoing/incoming/unresolved,
computed with no LLM call. Curate's support refs are drawn from the same
links now, not from the retired entity graph.
akm info always exits 0 and always prints a report, even when something is
wrong: an invalid config.json, a missing or unreadable bundle directory, or
a locked/newer/corrupt index.db is named in the report (configError,
bundleDirError, indexStats.unavailable) instead of failing the command or
showing unexplained zeros. It also reports link counts per kind, including
how many are unresolved.
Decide every pending retire proposal -- akm proposal accept or reject --
before downgrading to 0.9.16. Older releases predate the retire proposal
shape entirely: akm proposal show/diff/drain exits 70 on one it doesn't
recognize, and drain's own nightly pre-pass failing on the first pending
retire proposal it meets stops that run's auto-promotion for the whole
stash, not just for the one proposal.
0.9.16 already refuses to open a newer-layout index.db outright
(INDEX_SCHEMA_INCOMPATIBLE, naming the upgrade) and leaves the file
untouched, so downgrading needs a fresh index: move index.db aside and run
akm index --full under 0.9.16, which re-embeds everything from scratch.
A workflow run started under 0.9.17 freezes its plan as irVersion 6,
which 0.9.16 does not understand and refuses to resume
(WORKFLOW_IR_VERSION_UNSUPPORTED) -- let any in-flight workflow runs finish
before downgrading, or plan to restart them fresh under 0.9.16.
The state.db migration that adds the improve ledger
(028-improve-ledger) drops six tables 0.9.16 and earlier used
(proposal_fingerprints and friends). Because it drops schema, the akm that
runs it first copies the database to state.db.pre-028-improve-ledger.bak
before making the change. That backup is a snapshot from the moment of
upgrade -- restoring it to downgrade discards every proposal, event, and run
state.db has recorded since, not just the ledger's own six tables, so treat
it as a last resort rather than routine.