Migration notes for akm v0.9.0
These notes apply to the 0.9.0 release candidates and final release. If you were already running a 0.9.0 beta, align scripts, prompts, and stash layout with the current command surface and verify every durable artifact before normal use.
Heads-up: 0.9.x is a refactoring and clean-up release series. Patch releases may include breaking changes (each called out in the CHANGELOG with a migration note) until the remaining technical debt is paid off; the 0.10.x series returns to bug fixes and tuning with breaking changes only in major and minor releases. See STABILITY.md for the full policy.
Key operator-facing changes:
- This release is the format-neutral bundle-adapter refactor — for
recognition, indexing, presentation, and validation. The flat asset-type
registry is replaced by per-format adapters that decide what a file is
(11 adapters behind a static registry), how it is indexed and shown, and
how it validates. Refs move from the old
type:namegrammar to[bundle//]conceptId— a subdir-qualified concept id such asskills/code-review,memories/vpn-note, orenv/prod, with an optionalbundle//installation prefix and an optional#fragment. Durable state is stored fully-qualified; the short bundle-omitted form is input sugar (resolved againstdefaultBundle, then installation-priority order).akm migrate applyre-keys all durable state, folds the formerworkflow.dbintostate.db(three tracked databases:state.db/index.db/ a separatelogs.db, down from four —logs.dbitself sits outside migration control entirely, see the migration guide), and migrates config from the flatstashDir/sources/installed/wikiNamekeys tobundles/defaultBundle. In AKM stashes,index.md/log.mdare reserved structural files — never indexed as items and never valid item-write targets. Other bundle formats use their adapter's own structural-file rules. What this refactor does not (yet) touch: placement.adapter.placeNew()is defined on the interface (src/core/adapter/bundle-adapter.ts) as an optional capability method and already implemented by 9 of the 11 built-in adapters (all butokfandwebsite-snapshot), but nothing in the write path calls it in 0.9.0 — writes still route through AKM's native flat type→directory placement table (stashDirForinsrc/core/asset/asset-placement.ts). That wiring is deferred to 0.10 as its own change (see STABILITY.md and D12); placement is already correct for every existing bundle today, this only changes which code computes it.adapter.validate(), by contrast, is a REQUIRED interface member and each adapter owns its own checks in 0.9.0:akm lintdispatches to the bundle's own adapter rather than re-implementing its rules. One caveat worth knowing: the proposal pre-commit path also runsvalidate(), but advisory only — it reports findings via a warning and does not reject the write. Making it blocking needs the adapter and legacy ref resolvers reconciled first, so a proposal that trips an adapter diagnostic still applies in 0.9.0. The adapter layer'sindex()/affectedItems()capability hooks also have no implementors yet — every 0.9.0 adapter is scanned through the shared core walk. None of this blocks normal use; it means "adapter-driven" in this release now covers reading and validating a bundle, but not yet writing to one. - Installed non-akm bundles reclassify on your next
akm index. The indexer now dispatches each installed bundle's detected adapter instead of recognizing everything with the akm-stash adapter. No action needed — the index is a regenerable cache — but searches/saved refs into those bundles may resolve to new ref spellings afterwards. - OKF and llm-wiki are both consumer/read-only in 0.9.0. Arbitrary OKF
typevalues remain searchable and showable with heading fragments, while the selected adapter decides which types receive specialized behavior. AKM-authored Markdown now emits its nativetypefield and remains OKF-compatible; commands, scripts, workflows, tasks, environments, and secrets retain AKM's progressively enhanced native handling. Both theokfadapter and thellm-wikiadapter are consumer-only in 0.9.0 — AKM-native write commands (akm remember,akm import, proposal-accept, …) reject OKF and llm-wiki targets before modifying them. Author llm-wikipages/content the way the Karpathy pattern always intended: your agent writes the files directly, and akm indexes and serves the result. - The published npm package requires Node.js >= 22 as its cross-platform
bootstrap. The
akmlauncher prefers a working Bun >= 1.0 and otherwise falls back to Node.js;akm-migratefollows the same model, with Bun optional and preferred. The standalone binaries are runtime-free. - The legacy
vaultasset type andakm vault ...command family are gone. Useenv/<name>for whole.envgroups andsecrets/<name>for a single sensitive value. akm saveis replaced byakm syncfor writable-stash persistence and pushes, andakm eventsis replaced byakm log.- The entire
akm wiki ...command family and thewikiasset type are gone. The Karpathy-style LLM wiki structure (schema.md+pages/) is now a first-class bundle format recognized and indexed directly byakm index/akm search/akm show— no dedicated verb surface needed.akm lintstill runs, now dispatching to the adapter's own wiki-shaped checks throughvalidate()(see above); it is a read surface in 0.9.0, not a write target — placement isn't wired to the adapter until 0.10. akm-migrate storageperforms the non-destructivevaults/->env/copy for older stashes. Run it before indexing if you are upgrading from a stash that still stores.envfiles only undervaults/.- Proposal workflow is fully consolidated around
akm improve,akm proposal new, andakm proposal .... Update any oldakm reflect,akm distill,akm accept,akm reject, orakm proposalsusage. - LLM-backed sustaining work is opt-in in the shipped presets: improve-stage
extract is off in
defaultandfrequent, andproactiveMaintenanceis off indefaultandreflect-distill. The dedicatedproactive-maintenancestrategy remains enabled as an explicit opt-in. Presets that omit these fields inherit thedefaultoff values, while an explicit userenabled: trueoverride still wins. - Config,
state.db, andworkflow.dbare now classified independently by the explicitakm migratecoordinator. Normal commands refuse old, future, or divergent durable schemas instead of attempting migration as a side effect. akm-migratederives the 0.9 config from your 0.8 keys instead of demanding a hand-authored one: the firstapplywith no--configwrites a validated starter config under the backup root and stops; a secondapplyperforms the cutover. Engine settings are never guessed — they are reported indroppedKeysfor you to re-add. Fresh 0.8 installs (whose configs carry noconfigVersionkey) now classify asoldinstead of being blocked, andmigratereportsnot-applicable(exit 0) when there is nothing to migrate.- The experimental
akm workflow brief/akm workflow reportexternal-driver protocol is removed.akm workflow runis the single execution surface. A legacyexperimental.workflowEngineconfig key is accepted and ignored; scripts callingbrief/reportmust move torun. - Engine-less installs fall back to
opencode-sdkforworkflow run, prompt tasks,akm agent,propose, andimprovereflect — when theopencodebinary is on PATH, akm synthesizes a config-free engine that resolves provider, model, and auth from opencode's own configuration instead of failing closed with exit 78. The fallback is always announced (resultwarnings, task run log, or stderr). An operator-configured engine always wins. - RSS, Bluesky, and X URLs are recognized by
akm bundle addand snapshotted as knowledge assets instead of being crawled as ordinary web pages. X needsX_BEARER_TOKEN(orX_RSS_TEMPLATE); store it as an akm secret and inject it per-invocation withakm secret run. Website crawls now respectrobots.txtby default ("respectRobots": falseopts out), have a hardcrawlTimeoutMscap, and extract the page's main content — existing website snapshots will get shorter and cleaner on their next refresh.
Primary public command family for 0.9.0:
akm improve <ref> [--task "..."]akm proposal new <type> <name> (--task "..." | --file <path>)akm proposal listakm proposal show <id>akm proposal diff <id>akm proposal accept <id>akm proposal reject <id> --reason "..."
Release validation
Unit/integration test counts below are point-in-time snapshots from the validation passes named next to each figure, not a promise about the count on any later commit — the suite keeps growing after each pass. Run
bun run checkyourself for the current count; do not treat a number below as still accurate.
Release validation was repeated on 2026-07-31. An isolated manual pass covered
114 first-run, CLI, indexing, search/show, output-format, strict-flag,
tools-only agent classification, multi-bundle write/lint, workflow, task,
llm-wiki, env/secret, feedback/log, config/migration, health, upgrade, and
registry checks with no failures. bun run release:check, as run on
2026-07-31, verified the packed npm installation, Node fallback and Bun
launcher paths, migration and task execution from published 0.8.14, the Linux
standalone scheduler artifact, its then-current unit/integration test counts,
and all seven Docker install targets. The gated semantic-search suite passed
9 tests; Node 24 passed all 9 fallback smoke steps and 25 compatibility tests.
The post-release checklist audit added a separate 125-check deterministic pass
for cross-bundle identity, write fidelity, output destinations, lint/task
behavior, env secrecy, durable log cursors, workflow transitions, proposal
dry-runs, setup recovery, fresh health initialization, and source-install
safety. It passed 125/125 on Linux. The branch as of that same pass also
passed bun run check and bun run build.
A container-isolated follow-up passed 188 destructive crash/recovery checks,
including real SIGKILL windows across proposal, workflow, and lock journals,
plus deterministic interruption replay across phase-free migration sentinels.
The container also passed release:check --skip-docker, the seven-image
Docker install matrix, 9 semantic-search tests, all 9 Node 22 smoke steps, all
25 Node compatibility tests, and the offline full gate. This pass exposed and
fixed host-scheduler and co-located Node/Bun assumptions in three tests; no
production behavior changed.
Live credential-backed agent/LLM calls and native macOS/Windows execution were not run from this Linux host. Their deterministic paths remain covered by the full unit/integration suite; release artifacts still require their normal platform CI/release checks.
Required upgrade checks:
- Before crossing from 0.8 to 0.9, create an independent filesystem backup and
prepare a valid 0.9 config. The installed 0.8 binary does not know the 0.9
migration protocol: install or stage the 0.9 binary, then run
akm migrate apply --config <prepared-0.9-config>before any normal command. - On an existing 0.9 installation, run
akm migrate status. If it reportsready, runakm migrate apply; an already-current active config is used as the target. - Do not continue when status reports
blocked. Preserve the reported backup run and resolve the named artifact or active-operation error first. - Restore is explicit and destructive:
akm-migrate restore --for 0.9.0 --run <backup-run-id> --confirm. It creates and verifies a rescue backup before replacing current artifacts. - Run
akm help migrate 0.9.0for the storage and command-surface checklist. - Run
akm-migrate storage --yesonce if the stash ever usedvaults/. - Rebuild derived search data with
akm indexonly after migration status iscurrent; indexing does not migrate config or durable schemas. - Review agent instructions and docs for old
vault,reflect, anddistillexamples. - Review scheduled improve invocations if they relied on inherited extract or
proactive-maintenance enablement. Standalone extraction remains available
as
akm proposal extract, but every invocation must select--type <harness>or--auto; a bare invocation is invalid. Update any installed extract task toakm proposal extract --autofor all-harness discovery. The bundled template remains an unselected opt-in and now uses that valid command.
0.9.0 command-surface overhaul (hard break, no aliases)
The 0.9.0 CLI surface was restructured in full. Known retired spellings fail
with UNKNOWN_COMMAND and a replacement hint. Update assets,
scripts, task YAML, prompts, and agent instructions (CLAUDE.md quick
references) using this table, then run akm task sync --rebind once so
installed schedules re-emit the new spellings. akm hints prints the complete
agent guide (--detail brief selects the compact version), while akm help agents is short by default; the root akm --help groups the surviving surface
into AGENT LOOP / ASSETS / AUTOMATION / SYSTEM sections, including migrate
under SYSTEM. For migration usage details rather than the bare --help
listing, see the migration guide.
Command renames and moves:
| Old spelling | 0.9.0 replacement |
|---|---|
akm init |
akm bundle create |
akm add <source> |
akm bundle add <source> |
akm list |
akm bundle list |
akm remove <source> |
akm bundle remove <source> |
akm update |
akm bundle update (self-update stays akm upgrade) |
akm tasks <sub> |
akm task add|run|sync|doctor|history (singular; list, show, remove, init, enable, and disable are removed) |
akm extract |
akm proposal extract |
akm propose |
akm proposal new |
akm log list |
akm log (now a single command) |
akm registry search <q> |
akm search <q> --from registry |
akm workflow template |
akm workflow create --print |
akm workflow validate |
akm lint --type workflows (add --fail-on-flagged to keep CI-gate exit semantics) |
akm config show |
akm config list |
Removed outright (with the supported replacement procedure):
| Removed | Use instead |
|---|---|
akm history |
akm log --ref <ref> |
akm graph (all subcommands) |
counts in akm health; refresh via akm improve --strategy graph-refresh |
akm lessons coverage / strength |
lesson strength is indexed; akm search --type lesson |
akm mv |
move the file, then akm index + akm lint; optional bun scripts/rekey-asset-ref.ts <old-ref> <new-ref> (source checkout) carries ranking signal |
akm log tail |
poll akm log --since @offset:<id> (durable cursor) |
akm workflow watch |
akm log --run <run-id> |
akm env set / env unset |
edit the .env file directly; akm loads it as-is |
akm config validate |
config is validated on every load |
akm task enable / disable |
edit enabled: in the task YAML, then akm task sync |
akm task init |
akm setup seeds the default schedules |
akm improve canary |
bun scripts/refresh-canary-set.ts [--refresh] (from a source checkout — helper scripts are not shipped in the npm package) |
akm registry build-index |
bun scripts/build-registry-index.ts (maintainer tooling) |
akm index --background |
removed (the flag never backgrounded; use --quiet) |
akm setup --detect-only / --reset-recommended |
removed; environment detection runs inside akm setup, and akm info reports the configured capabilities |
extract --watch / --debounce-ms |
schedule akm proposal extract --auto as a task |
Flag and value renames:
| Old | New |
|---|---|
search/curate --source stash|registry|both |
--from local|registry|all |
remember/clone/improve/the task group --target <bundle> |
--bundle <bundle> (import, proposal accept, env create, env remove, secret set keep --target) |
Environment and JSON-payload renames ("stash" is retired; the noun is "bundle" everywhere):
| Old | New |
|---|---|
AKM_STASH_DIR |
AKM_BUNDLE_DIR |
akm info field stashDir |
bundleDir |
akm config path --all key stash |
bundle |
bundle create result defaultStashUpdated / previousStashDir |
defaultBundleUpdated / previousBundleDir |
Full changelog: https://github.com/itlackey/akm/blob/main/CHANGELOG.md