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
563 lines (515 loc) • 35.1 kB
Markdown
# Stability policy
`akm-cli` follows [Semantic Versioning](https://semver.org/) on the 0.x line
**with one caveat**: until 1.0, minor releases (0.x → 0.x+1) may include
breaking changes.
**0.9.x series exception.** The 0.9.x releases are a deliberate refactoring
and clean-up series: the goal is to pay off all remaining technical debt and
land every planned breaking change before 0.10. While that work completes,
**0.9.x patch releases may also contain breaking changes** — each one called
out in the CHANGELOG with a migration note. The 0.10.x series returns to bug
fixes and tuning, and aims to restore the normal discipline of breaking
changes only in major and minor releases.
This document classifies **every** user-facing surface by stability so you can
decide which parts of `akm` are safe to script against today and which to
treat as still-evolving. If a surface is not listed here, that is a bug —
please file it.
## How to read this
| Tier | Contract |
| --- | --- |
| **Stable** | Scripted use is supported. Changes are additive within a minor release; breaking changes are called out in the CHANGELOG with a migration note. |
| **Evolving** | Available across minor releases, but flag names, prompts, and payload shapes may shift. Breaking changes are flagged in the CHANGELOG. |
| **Experimental** | Subject to change without notice. Not recommended for scripted use. Some experimental surfaces additionally require an explicit opt-in — see [`akm improve` autonomy](#akm-improve-autonomy--opt-in-in-090). |
| **Internal** | Not a public interface. May change or disappear in any release, without a CHANGELOG note. Listed here only so you can recognize it. |
## Command tier index
The canonical index: every command and subcommand group in the current tree
(enumerated from `main.subCommands` in `src/cli.ts` and each group's own
`subCommands`), with its tier. The prose sections below remain the detailed
explanation of *why*; this table is the lookup. Two spots have no single
explicit sentence naming their tier and were resolved by reading neighbors:
`akm bundle show` is assigned Evolving because it is discussed only inside
the Evolving "Bundles & the workspace model" bullet, alongside the still-
shifting adapter set, unlike its sibling `akm bundle list`, which the Stable
section names explicitly; and `akm proposal list` is assigned Stable — the
Stable section names it explicitly ("list filters"), which takes precedence
over its incidental mention inside the Evolving "Improvement loop" bullet's
enumeration of the whole `proposal` noun group.
| Command | Tier | Notes |
| --- | --- | --- |
| `akm setup` | Stable | |
| `akm index` | Stable | |
| `akm health` | Evolving | Exit codes are Evolving; report *content* and rendered `md`/`html` layout are Experimental — do not script against report layout. |
| `akm metrics` | Experimental | New in 0.9.28. Report content, JSON shape and the `html` dashboard may change. |
| `akm info` | Stable | |
| `akm bundle create` | Stable | |
| `akm bundle add` | Stable | |
| `akm bundle list` | Stable | |
| `akm bundle show` | Evolving | See note above. |
| `akm bundle remove` | Stable | |
| `akm bundle update` | Stable | |
| `akm upgrade` | Stable | Including the plugin step and `--next` (0.9.28), verified on real hosts, in empty containers and on failure paths (#1099). |
| `akm search` | Stable | |
| `akm curate` | Stable | |
| `akm show` | Stable | |
| `akm workflow status` | Experimental | `--all-scopes` added in 0.9.15 (#942), additive. |
| `akm workflow plan` | Experimental | New in 0.9.2; secret-free provenance output; envelope shape may change. |
| `akm workflow list` | Experimental | `--all-scopes` and a top-level `scopeKey` envelope field added in 0.9.15 (#942), both additive. |
| `akm workflow create` | Experimental | |
| `akm workflow resume` | Experimental | |
| `akm workflow abandon` | Experimental | |
| `akm workflow run` | Experimental | Canonical start/resume/execute command. |
| `akm remember` | Stable | |
| `akm import` | Stable | |
| `akm sync` | Stable | |
| `akm clone` | Stable | |
| `akm registry list` | Evolving | |
| `akm registry add` | Evolving | |
| `akm registry remove` | Evolving | |
| `akm migrate status` | Internal | Forwards to the standalone `akm-migrate` tool; renders its result through the normal `--format` pipeline (not exempt — see below). Listed (not hidden) in `--help`/completions. |
| `akm migrate apply` | Internal | Forwards to the standalone `akm-migrate` tool; renders its result through the normal `--format` pipeline (not exempt — see below). Listed (not hidden) in `--help`/completions. |
| `akm config path` | Stable | |
| `akm config list` | Stable | |
| `akm config get` | Stable | Default bare-value shape unchanged; `--show-source` (0.9.15, opt-in) wraps it as `{ value, source }`. |
| `akm config set` | Stable | |
| `akm config unset` | Stable | |
| `akm config diff` | Evolving | New in 0.9.15; compares effective (post-`extends`) configs, secrets redacted. |
| `akm feedback` | Stable | |
| `akm log` | Evolving | |
| `akm agent` | Evolving | |
| `akm command run` | Evolving | Runs stored command templates through the same agent dispatch as `akm agent`. |
| `akm models` | Evolving | `list` and `copy-defaults` for model intent aliases. |
| `akm lint` | Evolving | |
| `akm improve` | Evolving | Review-first by default; mutating lanes require `experimental.improveAutonomy` — see below. |
| `akm proposal list` | Stable | See reconciliation note above. |
| `akm proposal show` | Evolving | |
| `akm proposal diff` | Evolving | |
| `akm proposal accept` | Evolving | |
| `akm proposal reject` | Evolving | |
| `akm proposal reopen` | Evolving | New in 0.9.19; undoes a rejection. |
| `akm proposal revert` | Evolving | |
| `akm proposal drain` | Evolving | |
| `akm proposal extract` | Experimental | Former top-level `akm extract`. Session extraction quality is still being measured (0.10, #1094). |
| `akm proposal new` | Evolving | Former top-level `akm propose`. |
| `akm help` | Stable | |
| `akm help agents` | Stable | |
| `akm help migrate` | Stable | Only renders release notes. |
| `akm hints` | Stable | Format-exempt agent guide; `--detail brief` selects the compact version. |
| `akm completions` | Stable | Format-exempt (emits shell script source). |
| `akm env list` | Stable | Read-and-inject surface. |
| `akm env path` | Stable | Read-and-inject surface. |
| `akm env export` | Stable | Read-and-inject surface. |
| `akm env run` | Stable | Read-and-inject surface. |
| `akm env create` | Experimental | Write verb. |
| `akm env remove` | Experimental | Write verb. |
| `akm secret list` | Stable | Read-and-inject surface. |
| `akm secret run` | Stable | Read-and-inject surface. |
| `akm secret set` | Experimental | Write verb. |
| `akm task add` | Evolving | |
| `akm task run` | Evolving | |
| `akm task history` | Evolving | |
| `akm task sync` | Evolving | |
| `akm task doctor` | Evolving | |
| `akm task explain` | Evolving | New in 0.9.2; secret-shaped values in provenance output are redacted on a best-effort heuristic basis (not a guarantee). |
| `akm task validate` | Evolving | New in 0.9.11; read-only, and the only `task` subcommand that takes a bare filesystem path instead of a ref — the file need not belong to any configured bundle. |
| `akm task list` | Evolving | New in 0.9.15 (#951); a pure delegating alias for `akm search --type task` — same envelope, no separate implementation. |
## Stable
- **Asset ref syntax** — `[bundle//]conceptId[#fragment]`. A `conceptId` is
subdir-qualified within its bundle: `memories/<name>`, `lessons/<name>`,
`knowledge/<name>`, `skills/<name>`, `scripts/<name>`, `workflows/<name>`,
`env/<name>`, `secrets/<name>`, `tasks/<name>`, `facts/<name>`,
`sessions/<name>`, `commands/<name>`, `agents/<name>`. Other adapters
declare their own conceptId layouts. The optional `bundle//` prefix names an
installed bundle; omit it and the ref resolves against the workspace
`defaultBundle`, then the remaining bundles in installation-priority order.
Durable state always stores the fully-qualified `bundle//conceptId`; the
short form is accepted input only, at the CLI, the programmatic surface, and
inside bundle content (where it resolves against the containing bundle). The
older `<type>:<name>` grammar is no longer accepted.
- `#fragment` is **input-only** and never stored. On markdown-document items
the core resolves it as a section selector — `akm show <ref>#<heading-slug>`
returns that one section, no fragment returns the whole item, and an
unmatched fragment lists the available slugs. Elsewhere it is an
adapter-owned selector opaque to the core. See
[`docs/architecture/specs/ref.md`](https://github.com/itlackey/akm/blob/main/docs/architecture/specs/ref.md).
- **Refs in prose** must be fully qualified (`bundle//conceptId`) or a native
adapter link form. A bare conceptId in prose is ordinary text, not a ref,
and no akm tool rewrites it.
- **ConceptId-prefix enumeration** — `akm search "memories/"`,
`"memories/projecta/"`, `"bundle//"`, `"bundle//skills/"`. A trailing `/` is
required. The prefix matches the **conceptId** — the spelling every emitted
`ref` carries — so a ref copied out of search output can be truncated to a
prefix and pasted back in. Enumeration is not tied to any adapter's type set,
so every adapter's items browse the same way, and `bundle//` lists a whole
bundle (this replaced `akm bundle items`). A prefix is explicit intent, so
`search.defaultExcludeTypes` does not apply to it. The pre-0.9.0
`"<type>:"` / `"<type>:<prefix>/"` spelling was removed; a query in that
shape is now an ordinary keyword search whose empty-result tip names the
conceptId spelling that replaces it.
- **Read commands** — `akm search`, `akm show`, `akm bundle list`, `akm curate`,
`akm info`, `akm config get`, `akm config list`, `akm config path`,
`akm env list`, `akm secret list`, `akm proposal list` (list filters),
`akm help`, `akm help agents`, `akm hints`, `akm completions`.
- **Write commands core surface** — `akm bundle add`, `akm bundle update`,
`akm bundle remove`, `akm clone`, `akm import`, `akm sync`, `akm index`,
`akm bundle create`, `akm setup`, `akm remember`, `akm feedback`,
`akm config set`, `akm config unset`.
- **Renames are delete + create** — moving or renaming an item gives it a new
identity; learned state does not follow it. Cross-bundle movement is
copy/import plus delete. The procedure is a plain filesystem move, then
`akm index`, then `akm lint` to catch inbound refs the move left dangling.
`akm mv` was **removed in 0.9.0**: it claimed to preserve identity across a
rename, but its inbound-ref rewriting targeted bare conceptIds rather than
the anchored `bundle//conceptId` prose form, so it could rewrite non-refs
while leaving real refs dangling. To carry an asset's earned signal
(feedback, usage, salience/outcome history) across a rename, the maintainer
script `scripts/rekey-asset-ref.ts` re-keys those rows old -> new; it is
Internal tooling, not a supported command surface.
- **Asset `type` is a free-form, open string** — `--type` filtering is an
exact match against an open set and is deliberately **not validated**: an
unrecognized type returns zero hits, not an error. Adapters emit types
outside the built-in set, so there is no closed list to validate against —
`--type website` or `--type wiki-source` are ordinary, valid filters.
- **Output contracts** — JSON output shape (the top-level keys) and the error
envelope `{ok: false, error, code?, hint?}` on envelope surfaces: `ok` and
`error` are always present; `code` is a stable machine-readable identifier
present on every classified failure (exit 1 / 2 / 78) and absent only on
unexpected internal errors (exit 70); `hint` is best-effort and may be absent. Prefer
`code` over matching on `error` prose. Plus the exit-code table below.
**All six** `--format` values (`json|jsonl|yaml|text|md|html`) are available
on every non-exempt command. `json`, `jsonl`, and `yaml` serialize the
envelope; `text`, `md`, and `html` render it. A command may register a bespoke
renderer for a document format — `akm health` does, for its per-run and
window-compare tables and its full HTML report — and anything unregistered
falls back to a generic rendering derived from the envelope's own shape. No
command emits one format's bytes when another was asked for, none rejects a
format outright, and **no command reads `--format` to decide what data to
fetch**: a registered renderer fires on the shape of the result (`akm health
--report` carries the report dataset in the envelope, so the same data is
available as JSON), never on the format alone.
`--detail` is verbosity only (`brief|normal|full`);
`--shape` (`human|agent|summary`) is the output-projection axis (see
Experimental). A small set of commands is **format-exempt** because their
output is not a result envelope at all: `completions` (shell script source),
child-process passthrough in `env run` / `secret run`, a bare-path payload
from `env path`, and document payloads from `help` (bare, `help agents`, and
`help migrate`). The set is declared in
`src/output/format-exempt.ts`, and
passing `--format` to one of them warns rather than silently doing something
else. Scripted `setup` modes emit a normal format-aware result; interactive
`setup` is a terminal UI and emits no result document. `agent` leaves
inherited child streams raw and formats its final result envelope.
`migrate status`/`apply` both spawn the standalone `akm-migrate` tool but are
NOT in the exempt set: `src/commands/migrate-cli.ts` parses the child's
final JSON result line and renders it through the same `output()` pipeline
(registered shape `src/output/shapes/migrate.ts`, text renderer
`src/output/text/migrate.ts`), so all six `--format` values work on them
like any other command. Any progress-event lines the child prints during a
real `apply` (content migration, proposal-ref repair) still print verbatim,
ahead of the formatted result — those are operational logging, not part of
the result envelope.
| Exit code | Meaning |
| --- | --- |
| `0` | Success |
| `1` | Not found / command-reported failure |
| `2` | Usage / bad input |
| `4` | Health warning (`akm health` only) |
| `70` | Internal / unclassified |
| `75` | Transient — retry shortly (`TransientError`, sysexits `EX_TEMPFAIL`); another akm process holds a lock or is writing `state.db` right now |
| `78` | Configuration error |
**From 0.9.12**, every success envelope produced by the passthrough stamp
(`config`, `clone`, `models`, `task-*`, `workflow-*`, `registry-*`, …) also
carries `ok: true`; a command that already computes its own `ok` keeps it.
- **Install scripts** — `install.sh` and `install.ps1` URLs; the `--prefix`
/ `AKM_INSTALL_DIR` environment override.
- **Runtime** — the npm package requires Node.js >= 22 as its bootstrap and
prefers a working Bun >= 1.0 for execution when both are available; old,
unusable, or absent Bun installations fall back to Node.js. Standalone
binaries are runtime-free.
- **On-disk storage** — durable workspace state (events, proposals, history,
workflow runs, salience) lives in `state.db`; the search index (`index.db`)
is a fully **regenerable** cache rebuilt by `akm index`; high-volume logs stay
in a separate `logs.db`. Asset metadata lives as file-local frontmatter plus
the index (there is no separate metadata sidecar). Treat the on-disk schema
as internal (use `akm` commands, not direct SQL).
## Evolving
These surfaces are in active iteration as we learn from users. They will
remain available across minor releases, but flag names, prompts, and
proposal-queue shape may shift. Breaking changes will be flagged in the
CHANGELOG with a migration note.
- **Improvement loop** — `akm improve` and the proposal noun group
`akm proposal {extract,new,list,show,diff,accept,reject,reopen,revert,drain}`
(`extract` and `new` are the former top-level `akm extract`/`akm propose`,
moved under `proposal` in 0.9.0). Output JSON keys
are stable; CLI flags (`--strategy`, `--task`, `--generator`) may add
options or tighten validation across releases. `akm improve` stays on by
default and is **review-first**: the lanes that mutate assets without review
require `experimental.improveAutonomy` — see
[`akm improve` autonomy](#akm-improve-autonomy--opt-in-in-090).
`--auto-accept` was removed in 0.9.0. It is now accepted-and-warned rather
than silently absorbed: passing it prints a deprecation warning naming the
replacement, and the space-separated form (`--auto-accept 90`) no longer
poisons the asset-type positional — its value is discarded with a second
warning instead of silently reducing the run to a zero-match no-op. It
becomes a hard error in 0.10. The replacement is
`akm improve && akm proposal drain --promote --yes`, or a `triage` block
with `applyMode: "promote"` in your strategy.
- **Tasks** — `akm task` subcommand surface (`add | run | sync | doctor |
history | explain | validate`; no alias, no
`list`/`remove`/`init`/`enable`/`disable`); task source v4 YAML (typed
`inputs:`, optional `schedule:`) is the only accepted version — task v3 and
task v2 sources are converted by `akm migrate apply`. Command tasks use
named engines and task history metadata is versioned. Schema additions in
patch releases; removals only at minor. Bare `akm task` is a usage error
naming the subcommands (`akm task doctor` reports scheduler diagnostics).
`akm task explain <ref>` (new in 0.9.2) and `akm workflow plan <ref>` are
both zero-write provenance surfaces: they show what a task or workflow
would do — resolved target, input bindings, child expansion — without
starting or publishing a run. `akm workflow plan` is secret-free **by
construction** (the excluded data never reaches the command). `akm task
explain` instead **redacts** secret-shaped input values on a best-effort
heuristic basis — a value that doesn't match the heuristic can still
print unredacted. `akm task validate <path>` (new in 0.9.11) is the same
kind of zero-write introspection as `explain`, but takes a bare filesystem
path rather than a bundle-qualified ref — it reports whether that ONE file
would parse cleanly (`valid`), need `akm migrate apply` first (`blocked`:
task v2/v3, or a retired `schedule[].enabled`),
fail schema validation (`invalid`), or isn't a task source at all
(`not-a-task`) — exactly the diagnostic `akm task sync` would produce for
it, before the file is ever wired into a bundle or the scheduler.
- **Workflow plan** — `akm workflow plan <ref>`, new in 0.9.2: zero-write
compile+freeze introspection (the canonical step graph, task/child
expansion, input bindings, and lowering notices for a workflow, without
starting or publishing a run). The envelope shape may still change. Like every
`workflow` verb it is Experimental from 0.9.28 (see Experimental below).
- **Events / log** — `akm log` is the event-stream surface (0.9.0: the
asset-scoped `akm history` surface, and `log`'s own `tail` subcommand, were
both removed; `log` is now a leaf command — the former `list` surface).
- **Bundles & the workspace model** — installed sources are *bundles*; each is
recognized by a built-in *adapter* (native Agent Skills, Claude and OpenCode
commands/agents, knowledge, YAML workflows, tasks, env/secret files, scripts,
OKF and LLM-wiki knowledge bases). Config is keyed by `bundles` and
`defaultBundle`. The adapter set, bundle-recognition rules, and the
`bundles` config shape may still shift; the `okf`, `llm-wiki` and
`generic-files` adapters in particular are Evolving. Bundles are inspected through
`akm bundle list` / `akm bundle show <name>` and enumerated through
`akm search "bundle//"`. (An earlier `akm bundle items` noun group was
removed in 0.9.0 as duplicative of `akm search`; the current `akm bundle`
group — `create | add | list | show | remove | update` — is the
lifecycle-management surface consolidated from the former top-level
`init`/`add`/`list`/`remove`/`update` commands, not a revival of that one.)
OKF is the
first-class baseline for Markdown concept identity and generic reads; every
applicable OKF conformance case is required to pass. AKM-authored Markdown is
an OKF-compatible superset whose adapter adds native behavior progressively.
- **LLM Wiki bundles** — the Karpathy-style LLM wiki is a first-class built-in
bundle format (the `llm-wiki` adapter owns `schema.md` / `index.md` /
`log.md` / `raw/` / `pages/` and its ingest flow); wiki pages are addressed
as ordinary concepts inside their bundle. Adapter behavior and page
conventions are still iterating.
- **Agent dispatch** — `akm agent` and `akm command run`. Supported backends:
`claude`, `opencode-sdk` (the primary OpenCode interface), `codex`, and the
`opencode` CLI path, `copilot`, `pi`, `gemini`, `aider`, `amazonq`,
`openhands`. Every harness is Evolving: the harness implementation is being
reworked so harnesses are easy to add, remove and update (0.10), and the
`opencode` CLI dispatch path is a deprecation candidate once `opencode-sdk`
covers it. The set will grow.
- **Model aliases** — `akm models list|copy-defaults` and the intent-alias
defaults they expose.
- **Proposal queue** — quality classifications (`accepted`, `pending`,
`proposed`, `rejected`, `archived`) are stable; the JSON shape of a
proposal record may add fields.
- **Registries** — `akm registry {list,add,remove}`. Searching registries is
`akm search --from registry` (0.9.0: `registry search` was folded into
`search`). Building a registry index is maintainer tooling (Internal) and
lives outside the CLI, in `scripts/build-registry-index.ts`.
- **Upgrade** — `akm upgrade`. Checksum verification is not optional; the
recovery hatch is the `AKM_UPGRADE_SKIP_CHECKSUM` environment variable
(Internal), not a flag. The harness plugin step and `--next` (new in 0.9.28)
are targeted to become Stable before the 0.9 series ends, once verified on
real hosts.
- **Lint** — `akm lint`. The rule set and finding shapes iterate; the
`--fail-on-flagged` CI contract and the exit codes are stable.
- **Health** — `akm health` and its exit codes (0 pass / 4 warn / 1 fail) are
Evolving; the *content* of the report (metrics, advisories) and the rendered
`md` / `html` layouts are Experimental — do not script against report layout.
## Experimental
Subject to change without notice within minor releases. Not yet recommended
for scripted use.
- **Workflows** — the whole `akm workflow` surface (`run`, `status`, `list`,
`create`, `resume`, `abandon`, `plan`), the workflow asset format and the
workflow engine are Experimental from 0.9.28 and throughout 0.10. The 0.10
series stabilizes the feature and trims what is not useful, then either
promotes it out of Experimental or removes it if stabilization does not
produce a quality feature.
- **`akm metrics`** — new in 0.9.28. What it reports, its JSON shape and the
`--format html` dashboard may change in any release; do not script against
them.
- **`lesson` asset type** — schema (`when_to_use`, `description`) is
stable, but lesson-distillation triggers and ranking are tuning targets.
- **`--shape agent` and `--shape summary`** — the output-projection axis
(`--shape human|agent|summary`). `summary` is implemented only on
`akm show`; `agent` is implemented on `search`, `show`, and `curate`.
Coverage will expand. `--detail` is verbosity only (`brief|normal|full`).
- **Protected env & secret values** — `env` (a whole `.env` group; key names
are surfaced for discoverability, values never are) and `secret` (a single
sensitive value). Values are never written to stdout, the index, or
structured output; the safe injection path is `akm env run <name> --
<command>` (or `akm secret run <name> <VAR> -- …`). The `env` / `secret`
**write** verbs (`create`, `set`, `unset`, `remove`) are Experimental; the
`list` / `path` / `run` / `export` read-and-inject surface is Stable.
- **Memory belief-state transitions** — `captureMode`, `beliefState`,
contradiction edges, and the consolidate journal are observable but
the algorithm that writes them is tuning across patch releases.
- **Improve built-in strategies and lanes** — the built-in strategies other
than `default` and `consolidate` (`quick`, `reflect-distill`, `thorough`,
`catchup`) and the proactive-maintenance and high-salience lanes. 0.10
measures each and keeps, folds or removes it (#1094).
- **Session extraction** — `akm proposal extract` and the `extract` process:
what it extracts, its quality gates and its output may change while 0.10
measures it (#1094).
- **Improve tuning config** — `improve.strategies.*.processes.*` (per-process
engines, limits, gates, and the anti-collapse / CLS / fidelity knobs) and
the `index.*` per-pass config. The 0.9.x series is explicitly still settling
the design of the improve processes, so **keys in these two families may be
added, renamed, or dropped in any 0.9.x or 0.10.x release**. The `akm
improve` *command* surface is Evolving (above); its tuning config is not.
### `akm improve` autonomy — opt-in in 0.9.0
**`akm improve` is review-first by default in 0.9.0.** The command itself is ON
— its schedules and reflect/distill proposals all run — but the lanes that
mutate assets *without* review require an explicit opt-in:
```sh
akm config set experimental.improveAutonomy true
```
Without it, these three lanes are downgraded, and each downgrade is **reported,
not silent**: it warns on stderr naming the lane and the key, appends an
`improve_skipped` event with `reason: "autonomy_gated"`, is counted in
`akm health`'s improve skip-reason summary, and is listed by `akm task doctor`
under `improveAutonomy.gatedLanes` — which is where to look when a *scheduled*
run stops doing something it used to. `akm task doctor` also reports the
**effective** `improveTriage.applyMode`, so a `promote` strategy under a
review-first config correctly shows `queue`.
| Lane | What it does when enabled | With autonomy off |
| --- | --- | --- |
| `memoryInference` | Writes `.derived.md` children and rewrites parent frontmatter | disabled |
| memory cleanup | Belief-state frontmatter rewrites, archive moves | analyzed but not applied |
| `triage` `applyMode: "promote"` | Auto-accepts queued proposals into the bundle | downgraded to `queue` — triage still runs, it just does not auto-accept |
Consolidation remains enabled with autonomy off: both its passes (promotion,
and the pair pass's duplicate/subsumed/supersedes judging) only ever emit a
reviewable proposal, and a pair-pass `retire` proposal is never auto-accepted
by `triage` `applyMode: "promote"` regardless of this gate.
Because the gate is applied before the LLM preflight, a review-first workspace
also needs fewer engines configured: a strategy whose only model-backed process
is a gated lane resolves without an engine at all.
**Three direct writes are deliberately NOT gated**, because they are additive or
already independently controlled:
| Write | Why it stays ungated |
| --- | --- |
| `extract` session indexing | Additive `sessions/**` writes; nothing is overwritten or deleted |
| distill's encoding-salience stamp | Frontmatter metadata only |
| `sync.push` | Publishes already-committed content to a remote the user configured for that purpose, and has its own `improve.strategies.<name>.sync.push: false` and `--no-push` |
Autonomy is never inferred: an absent `experimental` section, an absent key, and
an explicit `false` all read as off, so a partially-written or older config is
review-first rather than accidentally permissive.
Reflect, distill, extract candidates, validation, and proactive-maintenance
selection are proposal-only and never write assets directly. Two further
direct writes are ungated by design: `extract`'s session
indexing (additive `sessions/**` writes,
`processes.extract.indexSessions`, default on) and distill's
encoding-salience frontmatter stamp (metadata only).
## Internal
Not public interfaces. Listed so you can recognize them, not so you can rely
on them.
- **Migration surfaces** — the standalone `akm-migrate` tool owns the one-time
0.8→0.9 cutover, storage migration, and recovery backups (`akm-migrate
backup` / `restore`). `akm migrate` is a thin process forwarder; `akm backup`
and `akm config migrate` are removed. `akm help migrate <version>` is Stable
and only renders release notes.
- **`bun scripts/build-registry-index.ts`** — maintainer tooling for building a
registry index. It is a repository script, not a CLI command (the former
`akm registry build-index` subcommand was removed).
- **Environment variables** — see the table below.
### Environment variables
**Supported** — documented interfaces; changes get a CHANGELOG note:
| Variable | Purpose |
| --- | --- |
| `AKM_BUNDLE_DIR`, `AKM_CONFIG_DIR`, `AKM_DATA_DIR`, `AKM_CACHE_DIR` | Filesystem layout overrides |
| `AKM_LLM_API_KEY`, `AKM_EMBED_API_KEY`, `AKM_ENGINE_<NAME>_API_KEY` | Credential provision for `$VAR` config references |
| `AKM_LLM_ENDPOINT`, `AKM_LLM_BASE_URL` | Setup provider inference |
| `AKM_VERBOSE`, `AKM_DEBUG` | Diagnostics |
| `AKM_REGISTRY_URL` | akm registry mirror override |
| `AKM_NPM_REGISTRY` | npm mirror override — redirects BOTH the trusted-tarball host allowlist and package metadata lookups (`npm view`-equivalent resolution) to the given registry base, replacing `registry.npmjs.org` wholesale rather than merging with it |
| `AKM_SQLITE_JOURNAL_MODE` | SQLite journal mode (network filesystems) |
| `AKM_BIN` | Absolute `akm` path for scheduler registration |
| `AKM_INSTALL_DIR` | Install-script prefix |
| `AKM_UPGRADE_SKIP_CHECKSUM` | Recovery hatch for a broken upgrade checksum |
**Internal** — no compatibility guarantee, may vanish without notice:
`AKM_NODE_ENTRY`, `AKM_EVENT_SOURCE`, `AKM_SESSION_ID`, `AKM_AGENT_HARNESS`,
`AKM_EMBED_DETERMINISTIC`, `AKM_CLAUDE_PROJECTS_DIR`,
`AKM_FORCE_INIT_TMP_STASH`, `AKM_STATE_DIR`.
Anything matching `AKM_TEST_*` is test-only fault injection. Never set it.
`AKM_VERSION` is the only variable actually stripped from release builds, via
`bun build --define` (see `.github/workflows/release.yml`); no `src/` code
reads an `AKM_TEST_*` variable, so the compiled `akm` binary itself carries
none. That said, three fault-injection hooks are NOT compiled out and DO ship
in every install: `AKM_TEST_MIGRATION_FAIL_INDEX_QUARANTINE`,
`AKM_TEST_MIGRATION_FAIL_WORKFLOW_DELETE`, and
`AKM_TEST_MIGRATION_FAIL_RESTORE_AFTER` (`scripts/akm-migrate/`). The migration
tool ships separately from the compiled `akm` binary, so these throw-only hooks
remain physically present. At rest they are runtime-guarded no-ops unless the
exact internal test value is set. Never set them.
## On the horizon
These changes are planned and will land in a known future release. They
are not part of the current stability contract; you should plan migrations
around them.
**The 0.9.0 decision record is fully shipped.** The
[decision record](https://github.com/itlackey/akm/blob/main/docs/architecture/specs/0.9.0-decisions.md) settles a set of
breaking changes; every one of them is now in the code, and each decision
carries its own shipped status.
Shipped from that record: **D1** (`#fragment` section selection),
**D2** (the `akm show <ref> toc|section|lines|frontmatter|full` view grammar is
gone — `#fragment` is the only section selector), **D4** (conceptId /
`bundle//` prefix browse), **D5** (`akm bundle` removed), **D6** (open `type`
set at runtime), **D7** (all six `--format` values everywhere), **D8** (the
`experimental.improveAutonomy` gate), **D9** (`--auto-accept` warn-and-ignore),
and partially **D10** (an `akm-migrate` binary now exists, though the code still
lives in this repo). **D3** shipped too, in the end: `akm mv` was removed in
0.9.0 (see the Renames bullet above), with `scripts/rekey-asset-ref.ts` as the
Internal replacement for the one capability nothing else covered.
- **0.10 — `config set`/`config unset` may drop the config dump** in favor of
a compact `{ok, shape, key}` result; `akm config list` remains the full read.
- **0.10 — migration extraction.** The migration machinery leaves the CLI for
a separately published `akm-migrate` package (see Internal above).
- **0.10 — `--auto-accept` hard error.** It is currently accepted-and-warned;
see the Improvement loop entry.
- **0.10 — `BundleAdapter.placeNew()` wiring.** The interface declares
`placeNew()` as an optional capability method, and 9 of the 11 built-in
adapters already implement it (all but `okf` and `website-snapshot`;
`claude` and `opencode` inherit theirs from the shared tool-dir factory),
but nothing in the write path calls it —
writes still resolve through AKM's native flat type→directory table.
Placement for every existing bundle is already correct today; this is a
deliberately sequenced routing change, not unfinished behavior. See
[D12](https://github.com/itlackey/akm/blob/main/docs/architecture/specs/0.9.0-decisions.md#d12--bundleadapterplacenew-stays-unwired-until-010)
for why it is scoped out of 0.9.0. Nothing user-visible changes in 0.10 for
this alone.
- **1.0 contract freeze** — the `[bundle//]conceptId[#fragment]` ref grammar,
the supported source model, search behavior, and write-target rules are
frozen at 1.0. The SDK and in-process plugin story ship on top of that
frozen core.
## Reporting stability regressions
If you script against a stable surface and a release breaks it without a
CHANGELOG migration note, please open an issue at
<https://github.com/itlackey/akm/issues> labeled `regression`. We treat
stable-surface regressions as priority bugs.
For experimental surfaces, expect change — but file an issue if a change
isn't called out in the CHANGELOG, since that's still a documentation gap
worth fixing.
## See also
- [`CHANGELOG.md`](./CHANGELOG.md) — every release's behavior changes.
- [`SECURITY.md`](./SECURITY.md) — security supported-version policy
(independent of the feature-stability policy above).
- [`docs/architecture/specs/ref.md`](https://github.com/itlackey/akm/blob/main/docs/architecture/specs/ref.md) — the
normative ref grammar.
- [`docs/architecture/specs/0.9.0-decisions.md`](https://github.com/itlackey/akm/blob/main/docs/architecture/specs/0.9.0-decisions.md)
— the decision record behind the 0.9.0 surface changes.
- [`docs/reference/data-and-telemetry.md`](./docs/reference/data-and-telemetry.md) — what
state akm reads and writes locally.