Migration notes for akm v0.7.0
0.7.0 is the last pre-1.0 ship in the v1 cycle. It introduces the
proposal queue, agent reflection commands, the lesson asset type, the
llm.features.* per-call-site gates, and the first cut of akm-bench.
It also rolls in a batch of pre-prod hardening (security, UX, hygiene)
landed via PR #275.
The CLI surface, configuration schema, provider interfaces, and ref
grammar continue to match the v1 architecture spec
(docs/technical/v1-architecture-spec.md).
0.7.0 commits to maintaining those surfaces through the 0.8.x / 0.9.x
pre-releases — the formal freeze itself happens at 1.0 GA.
If you are coming from 0.6.x, the archived pre-1.0 migration plan covers the historical per-surface delta and is the canonical upgrade reference. This file is the executive summary of what's new in 0.7.0.
For stash authors on the 0.7.x pre-release line: .stash.json remains supported
for compatibility in this release, but it is deprecated and will be removed in
v0.8.0. That timeline is intentional: during this aggressive pre-release
phase-out window, compatibility shims do not stay around until 1.0 unless they
still earn their cost. Prefer frontmatter for markdown assets and structured
code comments for scripts, and migrate any remaining .stash.json metadata
before taking the 0.8 upgrade.
Major new surfaces in 0.7.0
Proposal queue (akm proposal *) — new (#225, #226, #233)
All proposal-producing commands (akm reflect, akm propose,
akm distill, plus any plugin-emitted proposals) write through one
durable queue. The queue lives outside the asset tree so unaccepted
drafts never leak into search or commits. Promotion runs full validation
before routing through writeAssetToSource() — the same single
write path used by akm remember and akm import.
akm proposal list # list pending proposals
akm proposal show <id> # render one proposal
akm proposal diff <id> # diff vs. the live ref
akm proposal accept <id> # validate, then promote
akm proposal reject <id> --reason "…" # archive with reason
Multiple proposals for the same ref coexist without filesystem
collisions. Auto-accept is gated per-source via the source config
(autoAcceptProposals: true); the default is off and requires a
writable source. See the archived pre-1.0 migration spec §11 at
docs/archive/pre-1.0-migration.md.
akm reflect, akm propose, akm distill — new CLI surfaces (#225, #226, #227)
Three new commands produce proposals into the queue:
akm reflect [ref] [--task ...] # reflection proposals — doclint:ignore (0.7.0-era, folded into `akm improve` later)
akm propose <type> <name> --task "..." # generation proposals — doclint:ignore (0.7.0-era spelling; moved to `akm proposal new` in 0.9.0)
akm distill <ref> # bounded LLM → `lesson` proposal — doclint:ignore (0.7.0-era, folded into `akm improve` later)
reflect and propose shell out via the agent CLI (agent.* config,
spec §12) and write only to the proposal queue — they never mutate
live stash content. distill is the canonical bounded in-tree LLM call
gated behind llm.features.feedback_distillation. All three emit usage
events (reflect_invoked, propose_invoked, distill_invoked). See
v1 spec §11.3 and §12.4.
lesson asset type — new (#227)
lesson is a first-class well-known type with required frontmatter
description and when_to_use. Lessons are stored under
lessons/<name>.md in the working stash, parallel to memories/.
Normally produced by akm distill <ref> as a proposed-quality
proposal and promoted via akm proposal accept. Direct authoring via
akm import and akm remember-style flows is also supported. See v1
spec §13.
llm.features.* map with default-false gates — new (#227)
Every bounded in-tree LLM call site is gated behind exactly one feature
flag. All defaults are false so adding the schema is a non-event
until the user opts in. Seven keys ship in 0.7.0:
| Key | Use site |
|---|---|
curate_rerank |
LLM rerank in akm curate |
tag_dedup |
LLM tag dedup during indexer enrichment |
memory_consolidation |
akm remember --enrich consolidation |
feedback_distillation |
akm distill <ref> |
embedding_fallback_score |
scorer fallback when embeddings unavailable |
memory_inference |
indexer split of pending memories into atomic facts |
graph_extraction |
indexer entity/relation extraction → SQLite graph tables |
Every gated call site uses tryLlmFeature(feature, config, fn, fallback)
from src/llm/feature-gate.ts. The wrapper guarantees:
- Disabled →
fallbackis returned without ever callingfn. - Throw → the error is swallowed;
fallbackis returned. - Timeout → a 30-second hard timeout (override via
timeoutMs) raisesLlmFeatureTimeoutError;fallbackis returned.
Failure events surface through an optional onFallback sink so callers
can emit a structured warnings entry. See v1 spec §14.
quality: "proposed" and --include-proposed — new
SearchHit.quality is an open string set with three well-known values:
"generated", "curated", and "proposed". The first two are
included in default search; "proposed" is excluded from default
search and surfaces only via akm search ... --include-proposed or
via akm proposal *. Unknown values parse-warn-include — they remain
searchable so plugin authors can introduce new values without crashing
the indexer. SearchHit gains optional quality? and warnings?
fields. See v1 spec §4.2.
akm-bench v1 — new (#234, PRs #266 / #268 / #269)
Bench grows beyond the 0.6.x smoke run into a paired-utility framework:
- Track A — paired noakm/akm runs. For each task, bench runs an agent CLI twice (without and with akm available), captures per-tool-call utility, and emits a comparable score pair.
- Track B — registry attribution. Utility deltas are mapped back
to specific
[origin//]type:namerefs so operators can see which assets actually contributed. akm-bench compareaggregates paired runs into a delta report.akm-bench attributesurfaces the per-ref attribution report.akm-bench evolveis a stub for the closed-loop evolution workflow that lands in 0.8.
The bench technical reference lives in
docs/technical/benchmark.md.
Removed legacy fields
- The legacy registry boolean
curatedis removed. Legacy v2 index JSON parses and silently ignores it. Renderers no longer surface acuratedcolumn; the per-assetqualityfield replaces it. Publishers do not need to migrate existing JSON. - Earlier 0.7.x pre-release work (#220–#223) finalised the registry curation surface removal, classification pipeline rewrites, and error envelope shape that 0.7.0 ships. Operators upgrading from a 0.6.x baseline should read the archived pre-1.0 plan for the per-surface migration recipe.
CLI surface as of 0.7.0
add | remove | list | update | search | show | clone | index | setup |
remember | import | feedback | info | curate | workflow * | vault * |
wiki * | enable | disable | completions | upgrade | save | help |
hints | config * | registry * |
agent | reflect | propose | proposal * | distill
This is the surface 0.7.0 commits to maintain through 0.8.x / 0.9.x. Renaming or removing any of these commands at 1.0 GA would be a major version bump.
Post-0.7.0 additive surfaces
These landed after the 0.7.0 cut without changing the existing command grammar:
akm import <url>now fetches one HTTP/HTTPS URL, converts it to markdown, and writes it intoknowledge/using a URL-path-derived default name.akm wiki stash <name> <url>now fetches one HTTP/HTTPS URL, converts it to markdown, and writes it intowikis/<name>/raw/.- Both flows are one-shot ingest only: they do not register a persistent website source and they do not crawl linked pages.
- Website source sync (
akm add <url> --provider website) and one-shot URL ingest now share the samesrc/sources/website-ingest.tsmodule for URL validation, fetch/convert, and mirror generation behavior.
Pre-prod hardening (PR #275)
PR #275 batched five issues plus the bench tmp follow-up that operators should be aware of:
Security
- #270 — git message sanitization. Commit messages and remote URLs written by akm are sanitized to prevent shell-substitution and control-character injection through user-supplied content.
- #271 — bench env isolation.
akm-benchruns each agent invocation in a scrubbed environment so host secrets do not leak into bench transcripts or paired-run logs. - #272 — LLM body redact + npm tarball host validation. Outbound
LLM request/response bodies are redacted in error reporting before
surfacing to stderr or warnings, and
akm add npm:…validates the tarball download host against the configured npm registry rather than blindly following arbitrarydist.tarballURLs.
UX
- #273 — workflow noise gate, sources deprecation warn, setup
--help.akm workflow next/complete/statusno longer print spurious progress noise on quiet runs.- Configs still using the legacy
stashes[]key emit a single deprecation warning per process (was: per call site). akm setup --helpnow renders the same help block asakm setupwith no args plus the documented agent-detection summary.
Hygiene
- #274 — tsconfig + HF pin + shapes throw.
tsconfig.jsonnow includestests/sobunx tsc --noEmitcovers test files. The HF embeddings model is pinned to a specific revision to avoid silent upstream changes. The output-shape registry now throws on a missing shape rather than silentlyJSON.stringify-ing.
Bench
- #276 — bench tmp redirect.
akm-benchno longer writes scratch state under/tmp; everything lands under the AKM cache dir (~/.cache/akm/bench/) so cleanup is bounded and CI sandboxes that ban/tmpwrites work out of the box.
Surfaces 0.7.0 commits to maintain (toward 1.0 GA)
These are the contract surfaces 0.7.0 ships and intends to carry forward through the 0.8.x / 0.9.x pre-releases into 1.0 GA. They are not yet frozen — the freeze happens at 1.0 — but operators authoring against 0.7.0 should expect them to remain stable through the final pre-release cycle. The full list lives in v1 spec §9.
writabledefaults totrueonfilesystem,falseotherwise.- Registry results are off by default in
akm search; pass--include-registryto merge them. Registry hits never land inhits— they live underregistryHits. - Write target resolves as
--target→defaultWriteTarget→ working stash →ConfigError. writable: trueis rejected onwebsite/npmat config load.SearchHit.scoreis[0, 1], higher = better. One scoring pipeline for all indexed content.- Asset refs are
[origin//]type:name. No URI schemes. quality: "proposed"is excluded from default search.- External agents are CLI shell-out only. The in-tree LLM stays
bounded and stateless, gated per call site by
llm.features.*.
Manual actions
None for users on a 0.6.x or earlier 0.7.x pre-release with no agent
or llm.features blocks set. Everything new is opt-in.
If you want to use the new surfaces:
akm setup # detects installed agent CLIs;
# persists `agent.default`
akm config set llm.features.feedback_distillation true
akm distill memory:my-debugging-notes # produces a lesson proposal — doclint:ignore (0.7.0-era command + ref grammar, folded into `akm improve` / bundle refs later)
akm proposal list
akm proposal accept <id>
Full migration guides
- Archived pre-1.0 migration plan — per-surface delta from any 0.6.x baseline. The canonical reference for upgrading.
- v0.5 → v0.6 — the older terminology cut and registry schema v3.
- v1 architecture spec — the architecture contract that 0.7.0 commits to maintain through 1.0 GA.