UNPKG

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

741 lines (648 loc) • 45.3 kB
# Public API review — tracked issue backlog (v0.9.0-rc.10) Status: proposed — reconciled 2026-07-26 against the maintainer rulings on Q-01..Q-19. Items carrying a `> Ruled 2026-07-26 (Q-NN)` note below are settled, re-scoped, or partially cancelled by a ruling; where a ruling bears on an item, **the ruling is authoritative**. Source: implementation-only review of the CLI surface and code (documentation claims deliberately ignored). Line references are against the tree at the time of review and may drift; each item names the file and the observable behavior so it can be re-verified independently. Note: items below cite `docs/agents/AGENTS.md` / `AGENTS.full.md`. Those files were deleted during the 0.9.0 docs sweep — they fed nothing at runtime after R-006 and kept re-diverging from the embedded copy. Their still-true content now lives in `src/assets/hints/cli-hints-full.md` / `cli-hints-short.md`, which is what `akm hints` prints and what `loadHints` reads. Baseline: items were found against `a8464f2` and re-verified 2026-07-26 against the base branch `claude/0-9-0-release-review-bcjxxu` @ `453a0ba`, which has since fixed some of them. A further pass on 2026-07-27 @ `2d2edc1` (code identical to `453a0ba`) re-checked the contested items individually and added `> Status 2026-07-27:` notes where the tree disagrees with the item as written — including two items this register had over- or under-reported (R-004 fixed-in-surface; R-046 superseded by the D6 ruling). Items carrying a **Fixed / Reframed / Rejected on the base branch** note have been re-checked; the rest were not re-verified individually and may have been incidentally affected. See the "Implementation status against the base branch" table in the companion drift register for per-ruling status. Companion: `0.9.0-docs-code-drift-register.md` covers the docs-vs-code comparison this review deliberately excluded — including the intent questions (Q-01..Q-19) where the decision record and the code conflict. All 19 were ruled by the maintainer on 2026-07-26; see the **"Maintainer rulings — 2026-07-26"** table in that register for the authoritative direction. ## Framing This backlog evaluates akm as what it has grown into: **a self-contained agent toolkit** — one CLI that gives AI agents the capabilities that normally require a stack of tools and a database server (indexed knowledge retrieval, secret/env management, harness-agnostic workflow execution and delegation, scheduling), while staying agent-, harness-, and content-format-agnostic (e.g. OKF alongside markdown). Under that identity, the env/secret manager, the workflow engine, the agent dispatcher, the OS-scheduler integration, and the improve loop are **in-scope features, not scope creep**, and no issue below asks for their removal. The identity instead raises the bar in three specific ways, and most of this backlog follows from them: 1. **Agents are the primary consumers.** Machine-facing guidance (`akm hints`, rendered command suggestions, help text, completions) is the product's API documentation *and* its runtime behavior. Every place it misleads an agent is a P0, not a docs nit. 2. **The abstraction claims must hold at the seams.** "Harness-agnostic" and "format-agnostic" are testable properties; half-wired normalizers and format special-cases are gaps in the core value proposition. 3. **An autonomous toolkit must be trustworthy by default.** Defaults that schedule LLM rewrites, push git remotes, or mine other tools' session transcripts need explicit opt-in or loud disclosure. Severity legend: - **P0** — the surface actively misleads its consumers, or an advertised path is broken/unreachable. - **P1** — incorrect or surprising behavior/semantics; wrong results or side effects. - **P2** — coherence, naming, and abstraction-seam debt. - **P3** — cleanup: dead code, stale comments, duplication. Counts: 9 × P0, 26 × P1, 21 × P2, 12 × P3 (68 tracked). The counts reflect the tier labels as written; two items carry ruling-driven re-tier recommendations not yet applied — R-045 (Q-18 makes it mandated feature work) and the `--format` half of R-050 (Q-04 makes it Stable-tier contract work, and the item should be split first). Recompute when those land. --- ## A. Agent-facing guidance correctness (P0) - **R-001 (P0) — `akm hints` documents a `wiki` command that does not exist.** The short and full hints corpora instruct agents to run `akm wiki list`, `akm wiki show <name>`, `akm wiki ingest <name>`, use `--type wiki`, and `akm show wiki:<name>`. No `wiki` subcommand is registered in `src/cli.ts:509-550`; an agent following the tool's own onboarding issues failing commands. Either ship the command or strip it from `src/assets/hints/cli-hints-*.md` and `docs/agents/AGENTS*.md`. > Note (Q-02, ruled 2026-07-26): the quoted `akm show wiki:<name>` example > uses the colon grammar Q-02 removes — the hints sweep hits these lines > either way; if the wiki content is kept (ship-the-command path), its ref > examples must move to the slash form. - **R-002 (P0) — `akm show --format text` renders copy-pasteable commands in the retired `type:name` ref grammar.** `appendShowDirectives` builds `` `${assetType}:${r.name}` `` and emits e.g. `akm feedback 'knowledge:guide' --positive` (`src/output/show-directives.ts:26,57,75,87`), which the 0.9 parser rejects. The same file renders `workflows/${name}` correctly two lines down. Every APPLY footer suggestion currently fails when executed. > Ruled 2026-07-26 (Q-02): the colon grammar is removed entirely — no alias, > no deprecation window — so re-accepting `type:name` in the parser is not a > fix option. `appendShowDirectives` must emit slash refs (as it already does > for `workflows/${name}`); include `show-directives.ts` in the Q-02 colon > sweep alongside `search --help`, `akm hints`, and the ref-prefix tests. > **Still open at base `0475870`** — and now strictly worse: Q-02 landed > (the colon browse grammar is gone) while `show-directives.ts:26` still > builds `` `${assetType}:${r.name}` ``. Raise with the Q-02 sweep. > Status 2026-07-27: confirmed still open; the file now lives at > `src/output/text/show-directives.ts` (`:26` builds the colon ref that > `:37,57,75` interpolate into `akm feedback` suggestions). The fix is one > line — build `assetRef` from the entry's conceptId (`workflows/${name}` > two lines down shows the pattern) — plus refreshing the show-format text > goldens that pin the footer. - **R-003 (P0) — `akm feedback` help contradicts the implementation.** Help (`src/cli.ts` command description; `src/commands/feedback-cli.ts:189-206`) states negative feedback "does NOT immediately lower the asset's ranking — run `akm index` after". The code applies the EMA utility update unconditionally and immediately for both signals (`feedback-cli.ts:170-176`). Fix the text or the behavior — currently agents are told to run an unnecessary reindex. - **R-004 (P0) — feedback threshold hint references a nonexistent command.** `feedback-cli.ts:365` prints "run `akm events list --type improve_review_needed`"; the command is `akm log`. (`events-list`/`events-tail` shape names and text formatter headers carry the same retired name — see R-060.) > Status 2026-07-27: ✅ **fixed in surface** — the printed hint no longer > exists; `akm events list` survives only in two code comments > (`feedback-cli.ts:341,365`). Downgrade to comment cleanup and fold into > R-065; the R-060 shape-name half is unaffected. - **R-005 (P0) — the shipped conventions fact contradicts `akm mv`.** The scaffolded `facts/conventions/organization.md` asset teaches "A rename is delete plus create. There is no command that preserves an asset's identity or learned state across one" and demonstrates raw `mv` + manual grep — while top-level `akm mv` exists precisely to move the file, rewrite inbound refs, and re-key the index row plus usage/salience history in place (`src/commands/mv-cli.ts`). Agents reading the stash's own guidance will avoid the safe command and hand-roll the dangerous procedure it automates. > Ruled 2026-07-26 (Q-01): `akm mv` stays; D3 is superseded. The fix is > one-directional — rewrite `facts/conventions/organization.md` and the other > D3-side docs to teach `mv`, and add the missing Experimental tier entry for > `mv` to STABILITY.md. Removing `mv` is off the table. - **R-006 (P0) — `akm hints` output depends on install method, and the copies have drifted.** `loadHints` prefers `<pkgroot>/docs/agents/AGENTS[.full].md` on disk and falls back to embedded `src/assets/hints/cli-hints-*.md` (`src/commands/observability-cli.ts:240-257`). npm packs neither `docs/agents/` nor `src/` (`package.json` `files`), so npm installs always get the embedded copy while repo checkouts get `docs/` — and the two corpora already differ in size and content. Single-source the corpus. > Note (Q-02/Q-08, ruled 2026-07-26): both rulings mandate spelling sweeps of > `akm hints` (colon→slash ref grammar; `env:`/`secret:`→slash) — land the > single-sourcing first, or sweep both copies atomically, so the ruled > changes don't re-drift the corpora. - **R-007 (P0) — advertised `owner/repo` shorthand is unreachable.** `add-cli.ts:234` and `git-install.ts:489` advertise the form, but `isPathLikeRef` returns true for any string containing `/` (`src/registry/resolve.ts:298`), so `tryParseLocalRef` throws `Local path not found` before the `parseGithubShorthand` fallback at `resolve.ts:86-90` can run. The fallback is dead code; `akm add itlackey/akm-stash` fails. Reorder the dispatch (try shorthand when the local path doesn't exist). > Note (Q-19, ruled 2026-07-26): the resolver fix (`resolveSourcesForOrigin` > matching `github:owner/repo` install refs) confirms install-ref shorthand is > intended surface, so the fix direction here — reorder the dispatch, don't > retire the advertised form — is sanctioned. Land both together so > `show //meta`'s "Run: akm add …" hint chain works end to end. - **R-008 (P0) — `akm registry search` ignores registries added via `akm registry add`.** `registry-cli.ts:128` calls `searchRegistry` without a `registries` option; the fallback resolves `DEFAULT_CONFIG.registries`, never the on-disk config (`src/commands/read/registry-search.ts:35,166`). Meanwhile `akm search --source registry` passes `config.registries` and honors them. Configured registries are listed by `registry list` but never searched by `registry search`. - **R-009 (P0) — `akm search` rejects the empty query its own help advertises.** The positional's description says "omit to list all assets" (`src/commands/read/search-cli.ts:36-39`) but the handler throws `MISSING_REQUIRED_ARGUMENT` for an empty query (`:79-86`), making the `enumerateEntries` browse path reachable only via `<type>:` prefix queries or queries that sanitize to empty. Allow the bare listing or fix the description. > Note (Q-02, ruled 2026-07-26): the `<type>:` escape hatch named here is > removed with the colon grammar; post-ruling the browse path is reachable via > the slash forms (`memories/`, `bundle//`). The empty-query question itself > is unaffected — update the parenthetical when Q-02 lands. --- ## B. Broken or surprising command behavior (P1) - **R-010 (P1) — the lockfile locks nothing.** `akm.lock` records `resolvedVersion`/`resolvedRevision`/`integrity`, but the only field consumed for behavior is `localRoot` (`src/integrations/lockfile.ts:122-130`). `akm update` re-resolves the original ref (npm `latest`, git branch HEAD) and overwrites the lock (`installed-stashes.ts:384`); nothing reproduces a locked state; stored integrity is never re-verified. Either implement lock-consumption (frozen installs, integrity re-check) or stop recording the fields and drop the "lockfile" concept from the surface. - **R-011 (P1) — git/github installs have no integrity verification at all.** `verifyArchiveIntegrity` returns early for git sources (`src/sources/providers/tar-utils.ts:42`); the sha256 computed at install time is stored and never compared. - **R-012 (P1) — corrupt lockfile fails silently open.** Unparseable JSON → `return []`; malformed entries silently filtered (`lockfile.ts:99-106`). Every managed bundle vanishes from `akm list` with no warning. - **R-013 (P1) — `akm add --provider` combinations are broken.** `providerType` is honored only when the target is a remote URL (`source-manage.ts:71-100`): `akm add lodash --provider npm` silently creates a *filesystem* bundle at `./lodash`; `akm add <url> --provider npm` stores the URL as an npm path that later resolves as a filesystem path (`config-sources.ts:102-104`, `npm.ts:54-59`). - **R-014 (P1) — `akm add`'s two paths return two incompatible response shapes.** Path A (`--provider`) returns `SourceAddResult`, Path B returns `AddResponse`; the shared text renderer reads Path B fields and prints `Installed undefined (0 directories scanned, 0 total assets indexed)` for Path A (`output/text/command-format.ts:510-514`). - **R-015 (P1) — `akm update --all` silently skips plain (non-lock-backed) sources.** `selectManagedTargets` returns lock-backed installs only (`installed-stashes.ts:519-522`); a configured plain `git`/`website` bundle is never refreshed by `--all` and must be named individually. Skip should at minimum be reported. > Note (Q-09, ruled 2026-07-26): the user-facing kind axis stays > `filesystem`/`git`/`npm`/`website`, so the lock-backed "managed" split stays > behavioral-only with no taxonomy surface — making the skip report asked for > here the sole disclosure of it. - **R-016 (P1) — `akm setup --yes` silently skips 7 of 8 wizard steps.** Only the `stash-dir` step sets `nonInteractive: true` (`setup/setup.ts:436`; skip logic `setup/steps.ts:98`); embedding, llm, semantic-search, registries, stash-sources, agent-cli, and output steps never run, while the call-site comment claims defaults are applied (`setup.ts:776`). Also `runSetupWithDefaults` hardcodes `online: false` yet still runs network detection (`setup.ts:779,788`). - **R-017 (P1) — `akm setup --config/--from` silently drops five valid config keys.** `ALLOWED_KEYS` (`setup.ts:1013-1027`) omits `index`, `search`, `feedback`, `workflow`, `archiveRetentionDays` — all present in `AkmConfigShape` — deleting them with only a stderr warn. - **R-018 (P1) — `akm curate --type` bypasses the entire curation algorithm.** With an explicit type the result is `stashHits.slice(0, limit)` — no family collapse, no intent nudges, no score floor (`curate.ts:255-262`). Two qualitatively different products under one command name. - **R-019 (P1) — curate hard-caps registry results at 2 regardless of `--limit`** (`curate.ts:264-265`), and the fallback path can issue up to 7 registry searches per invocation (`curate.ts:549-566`). - **R-020 (P1) — `akm show` drops the canonical `ref` from default and summary output.** `showLocal` computes it, brief/summary builders include it, and the shaper's `pickFields` allow-lists omit `"ref"` for human and summary shapes (`output/shapes/helpers.ts:453-496`). Only `--shape agent` emits the one identifier agents need for follow-up commands. - **R-021 (P1) — `--detail brief` behaves differently as a flag vs as config default.** `showCommand` detects only the literal CLI token via `getFlagValue("--detail")` to trigger `buildBriefResponse` (`search-cli.ts:223-227`); config `output.detail: "brief"` reaches only the shaper, which treats brief and normal identically. Same nominal level, two payloads. - **R-022 (P1) — `akm index --dry-run` alone performs a full real index.** The flag is only consulted inside the `--clean` branch (`indexer.ts:715-726`). - **R-023 (P1) — `akm index --background` claims to manage a PID file; none exists.** The flag only suppresses the spinner and the final output (`stash-cli.ts:95-99,127,157`) — the command still runs in the foreground and prints nothing. - **R-024 (P1) — `akm graph update --source <bundle>` validates the name, then extracts the primary stash anyway.** The validated result is discarded and extraction always uses `sources[0]` (`graph.ts:529-538`, `graph-extraction.ts:406`). - **R-025 (P1) — `akm config get <scalar>` returns secrets unredacted.** `redactConfigValue` only redacts inside objects (`config-cli.ts:66`): `akm config get embedding.apiKey` prints the literal value while `akm config get embedding` redacts it. (Mitigated by write-time sanitization, but the read surface is inconsistent.) - **R-026 (P1) — `akm env unset` argv workaround can silently drop keys.** The positional filter removes any token equal to a global flag's *value* (`env-cli.ts:474-482`), so unsetting a key literally named `json` while `--format json` is set is a silent no-op; `--target` is wrongly included in the global-flag list; the comment cites `cli.ts:1335` in a 666-line file. > Status 2026-07-27: ✅ **fixed** (`0475870`) — the workaround is deleted > outright. The root cause was citty parsing each command level against only > its own declared args; `GLOBAL_OUTPUT_ARGS` now declares the global output > flags on every leaf so their values are consumed by the parser, and keys > literally named `json` unset correctly (verified end-to-end alongside the > `sync --format json` case). See R-051's companion note. - **R-027 (P1) — `akm secret path`/`remove` can resolve to different files than the read path for the same ref.** Reads use `findEnvSource` (all sources); mutations use `resolveMutationTarget` (`core/env-secret-ref.ts:64-85` vs `198-255`). - **R-028 (P1) — `akm import <url>`'s private-host allowance is gated on a test-shaped predicate in production.** `allowPrivateHosts` defaults to `shouldAllowPrivateWebsiteUrlForTests(source)` (`stash-cli.ts:256`, `knowledge.ts:141-146`). - **R-029 (P1) — `akm backup` does not back up the stash.** Artifact set is `config.json`, `state.db`, `workflow.db`, `index.db` (`scripts/akm-migrate/migration-backup.ts:57-61`) — the markdown assets, env files, and secrets are excluded. Additionally `--for` accepts only the literal `"0.9.0"` (`backup-cli.ts:9-16`), and both `backup` and `migrate` hard-require Bun on PATH under the supported Node install (`migration-tool.ts:21`). Rename the command to match its migration-snapshot scope, or extend it to cover the knowledge. > Note (Q-14, ruled 2026-07-26): `backup` must receive a stability tier and > either a cli.md section or an explicit internal listing — make the > rename-vs-extend decision as part of that follow-through. > Ruled 2026-07-27: **removed from the CLI** — neither renamed nor extended. > `backup-cli.ts` deleted and the `backup` registration dropped; the > capability remains at `akm-migrate backup` / `akm-migrate restore` (already > present in that binary's surface). A cleaner backup story is deferred past > 0.9.0. Migration guide + 0.9.0 release notes swept to the new spelling; the > Q-14 tier question for `backup` is moot. ✅ landed same day. - **R-030 (P1) — `akm health` writes to the append-only event stream on every run.** The state-db round-trip probe appends a `health_probe` event (`health/metrics.ts:35-38`); CI polling accumulates rows indefinitely. Use a transaction-rollback probe or a dedicated probe table. - **R-031 (P1) — `akm health --format html` overrides `--group-by`** (forces `groupBy: "run"`, `cli.ts:341-360`) and runs the health computation twice with a second window read — undocumented and inconsistent with the other formats. > **Fixed on the base branch (`0475870`).** `akm health` no longer branches on > `--format` anywhere: `--report` is now a data flag carrying runs/deltas/the > pending-proposal queue in the envelope, the md/html renderers are pure > functions of the result, `setHealthHtmlContext` is gone, and the html-only > `--compare` was removed in favor of `--window-compare`. Breaking: bare > `akm health --format html` renders the plain check generically — use > `--report`. Verify and close. > Follow-up in `453a0ba`: `--report` had been seeding `windowCompare` from > `--since` unconditionally, so an absolute date/ISO/epoch `--since` reached a > duration-only parser and threw, and an explicit `--windows` tripped the > mutual-exclusivity guard. Precedence is now `--window-compare`, then a > duration-valued `--since`, and nothing alongside `--windows`. - **R-032 (P1) — unknown-command handling is inconsistent with the exit-code contract.** `akm totally-bogus` exits 1; `akm wiki list` prints top-level usage and exits **0**; the CLI's own table says usage errors are exit 2. Verified against the running CLI. - **R-033 (P1) — `akm feedback --tag` reads raw argv, including tokens after `--`.** The declared citty arg is decorative; `parseAllFlagValues("--tag")` scans the whole argv (`feedback-cli.ts:220,288`). Also `--applied-to` is a silent no-op for non-lesson refs (`:397`). - **R-034 (P1) — feedback silently skips the ranking update for non-`user` event sources.** With `AKM_EVENT_SOURCE` set to anything else — including invalid values coerced to `"unknown"` — the usage event is recorded but the utility score is untouched, with no output signal (`feedback-cli.ts:170`, `usage-events.ts:31-35`). - **R-035 (P1) — the `AKM_NPM_REGISTRY` hint is false.** The env var only widens the tarball-host allowlist (`resolve.ts:332-344`); metadata fetches are hardcoded to `registry.npmjs.org` (`resolve.ts:375`), so installs from a private mirror do not work despite the error hint saying they do (`resolve.ts:322`). --- ## C. Trust and safety defaults (P1) - **R-036 (P1) — `akm setup` installs five cron/launchd/schtasks entries by default** (hourly/4-hourly/nightly `akm improve` variants, `commands/tasks/default-tasks.ts:51-92`), and embedded task templates add `akm extract --auto` every 30 minutes. An OS-scheduler mutation deserves an explicit, itemized opt-in step in the wizard and a flag in `--yes` mode. > Ruled 2026-07-26 (Q-05/Q-14): `experimental.improveAutonomy` ships as > STABILITY.md documents it, and `extract` is tiered Experimental. The > scheduled `improve` entries must sit behind that off-by-default gate, and > the embedded `akm extract --auto` template schedules an Experimental-tier > command — implement the opt-in asked for here as the gate plus an explicit > wizard step (and a flag in `--yes` mode). - **R-037 (P1) — `akm improve` commits and pushes the stash by default** for git-backed stashes (`improve-cli.ts:145-154`). Combined with R-036 this means a default setup schedules unattended LLM rewrites that push to a remote. Default should be commit-only (or off) with push as explicit opt-in. > **Rejected on the base branch (`84bba7a`, 2026-07-26)** — supersedes this > item's recommendation and the earlier Q-05 note here. `sync.push` stays > default-on and *outside* the autonomy gate: it publishes already-committed > content to a remote configured for that purpose rather than mutating or > deleting assets without review, and it already has two documented opt-outs > (`sync.push: false`, `--no-push`). D8 gates five lanes — consolidate > merge/delete/contradict, memory-cleanup and contradiction passes, > memory-inference writes, and triage `applyMode: "promote"` — and `push` > joins extract's session indexing as an ungated-by-design write. The R-036 > half (scheduling unattended runs) is unaffected and still stands. - **R-038 (P1) — `akm extract` mines other harnesses' private session transcripts (claude-code JSONL, opencode storage) and sends content to the configured LLM** (`improve/extract.ts`, `integrations/session-logs/`), with a `--watch` mode that tails those directories indefinitely (`extract-cli.ts:267-319`). Legitimate feature; needs first-run consent and prominent disclosure given it reads data the user may not consider akm's. > Ruled 2026-07-26 (Q-14): `extract` is tiered **Experimental** and must be > documented (or explicitly listed internal) in cli.md. Land the first-run > consent and prominent-disclosure requirements in that new STABILITY.md tier > entry and reference section rather than as a standalone fix. - **R-039 (P1) — default `akm index` attempts an implicit ~130 MB embedding model download.** With `semanticSearchMode: "auto"` and no endpoint, `embedBatch` falls through to `@huggingface/transformers` → `Xenova/bge-small-en-v1.5` (`llm/embedder.ts:158-176`). Failure downgrades gracefully, but the download itself should be prompted. > Ruled (owner ruling 9, X-RULING-9, `f04932f`): `semanticSearchMode` now > defaults to `"off"` — a bare/headless install never attempts the > download; the interactive `akm setup` wizard still pre-selects it on, > with the download warning moved ahead of the prompt. - **R-040 (P1) — dynamic code loading from the stash.** Wiki snapshot fetchers `import()` arbitrary `.ts`/`.js` from `<stashDir>/scripts/wiki-fetchers/` (`sources/snapshot-fetchers/registry.ts:34-46`) — a code-execution surface reachable from synced content. Should be gated by the same third-party/first-party activation policy used for env keys. Related: the built-in YouTube fetcher calls the private InnerTube API with a hardcoded key impersonating the Android client (`snapshot-fetchers/youtube.ts:35-42`) — fragile and worth an explicit support decision. - **R-041 (P1) — `akm graph export --out` writes anywhere with default 0644** (`graph.ts:302-315`) while `akm env export` enforces 0600. Graph contents are LLM-extracted from the user's knowledge; align the posture. --- ## D. Abstraction-seam gaps (P2) — where the agnosticism claims leak - **R-042 (P2) — harness result normalization is half-wired.** All harnesses ship `result-extractor.ts` normalizers, but only the workflow native engine consumes them (`workflows/exec/native-executor.ts:1259-1267`); `akm agent`, `akm propose`, and reflect return raw harness stdout. Harness-agnosticism currently holds only inside `workflow run`. - **R-043 (P2) — OKF is special-cased in `akm show`.** OKF-adapter entries bypass the renderer registry for a hand-rolled markdown path (`show.ts:369-370,545-586`). If format-agnosticism is the goal, OKF should go through the same adapter/renderer seam as markdown assets. > Ruled 2026-07-26 (Q-07): the parser half of this special-casing is settled > — the ref-parser seam is fixed centrally so opaque conceptIds are accepted > across graph, tasks, improve, proposals, the utility repo, and the indexer > walk, removing `show`'s need to bypass `parseRefInput`. The > renderer-registry half remains this item's ask and aligns with the ruling. > **Largely fixed on the base branch (`453a0ba`).** `show`'s > `indexedEntry?.adapterId === "okf"` branch became `usesIndexedProjection` > (`read/show.ts:536-559`): OKF plus any indexed item whose type AKM does not > place keeps its adapter's projection, so a `website` entry no longer comes > back typed as AKM placement and a generic `file` no longer loses its > content. OKF is still named explicitly — deliberately, since its `type` is > open frontmatter and may collide with an AKM placement type — and > `env`/`secret` stay pinned to the dotenv renderer so values are never > dumped. What remains of this item is only that residual OKF name-check; > the general seam now exists. - **R-044 (P2) — two disjoint secret systems; the toolkit doesn't dogfood its own.** akm's LLM/embedding keys come from env vars or `$VAR` config refs (`config.ts:437-444`) and cannot be supplied from `akm secret`. Letting config reference `secrets/<name>` would close the loop and demonstrate the feature. > Ruled 2026-07-26 (Q-08): slash spelling only, no colon alias — if config > learns to reference managed secrets, the spelling must be the slash form > `secrets/<name>` (e.g. `secrets/OPENAI_KEY`), not the `secret:NAME` form > this item originally proposed. - **R-045 (P2) — the `instruction` asset type is half-registered.** It exists in `KNOWN_TYPES`/`TYPE_PRESENTATION` but not `PLACEMENT_SPECS` (`core/asset/asset-placement.ts:89-166` vs `core/recognition-util.ts:92-106`), so it is invisible to `akm info`, unbrowsable via prefix queries, and its refs don't round-trip. Register or remove it; add a compile-time exhaustiveness check tying the two registries together. > Ruled 2026-07-26 (Q-18): "register or remove" is settled — **register**. > The two-registry split stays the core truth (`KNOWN_TYPES` = presentation > vocabulary, `PLACEMENT_SPECS` = stash-resident subset), so the > exhaustiveness check is a **subset** assertion (placement keys ⊆ known > types), not equality. `instruction` gains a `PLACEMENT_SPECS` entry with an > `instructions/` stash dir on the markdown spec, becoming creatable, > browsable, and listed by `akm info` like knowledge; adapter-emitted > `instruction` docs round-trip via the Q-07 opaque-conceptId fix. This is now > mandated 0.9.0 feature work — **raise to P1**. - **R-046 (P2) — `--type` is unvalidated everywhere, and the help enumerates 11 of the 13 real types** (missing `fact`, `task`, `session`; `search-cli.ts:41-43,125-127`). `--type bogus` silently returns zero hits. Validate against `placementTypes()` and generate the help list from it. > Note (Q-18, ruled 2026-07-26): `instruction` becomes a placement type, > shifting the real-type count from 13 to 14 — a further reason to generate > the help list and validation from `placementTypes()` rather than > re-hardcoding. > Status 2026-07-27: **superseded by the D6 decision** — the validation half > of this item conflicts with a maintainer ruling this register missed. > `type` is a free-form open string BY DESIGN (adapters emit `website`, > `wiki-source`, OKF frontmatter types outside any placement list), so > validating against `placementTypes()` would reject valid filters; D6 and > `STABILITY.md`'s Stable-tier bullet both pin "deliberately not validated: > an unrecognized type returns zero hits, not an error". The help half is > already fixed: `search`/`curate` `--type` help now enumerates all 14 > built-ins **and states the set is open** (`search-cli.ts:43`). Nothing > remains except keeping that string current — do not implement validation. - **R-047 (P2) — same concept, two flag names: `search --filter` vs `show --scope`** for the identical `user=/agent=/run=/channel=` narrowing. Pick one (keep the other as a hidden alias for one release). > Ruled 2026-07-27: **unify on `--filter`, remove `--scope` with no alias.** > ✅ landed same day: `show` declares `filter`, parses repeatable `--filter` > through the same `parseScopeFilterFlags` helper as `search`; cli.md swept. > The removed spelling fails loudly rather than silently un-narrowing — > citty drops the unknown flag and its value lands in the positional slot, > where `rejectExtraShowPositionals` raises exit 2 (pinned by a new CLI test > in `scope-flags.test.ts`). - **R-048 (P2) — package identity: the npm description still says "package manager".** Under the accepted toolkit framing this misstates the product to its distribution channel and sets the wrong expectations for the verbs in §E. Reposition the one-liner (`package.json:5`). --- ## E. Verb semantics and surface coherence (P2) - **R-049 (P2) — `update` / `upgrade` / `sync` are three unrelated operations wearing package-manager names.** Refresh sources / self-update the akm binary / git-commit-and-push the stash. Given the toolkit identity, consider `akm self update` (or `self-upgrade`) and `akm stash sync` (or `save`) to free the ecosystem-conventional meanings; `sync` still emits `eventType: "save"` and `output("save", …)` from its retired name (`sources-cli.ts:181-185`). - **R-050 (P2) — global flags that are mostly not global.** `--detail` is an identity no-op for `init`/`index`/`info`/`import`/`remember` (and brief==normal on `show`); `--format md|html` is accepted globally but valid only for `health`; `--shape summary` only for `show`. Either scope the flags to the commands that honor them in help output, or implement them uniformly. > Ruled 2026-07-26 (Q-04): for `--format` the either/or is settled — > implement basic support on every non-exempt command, with `text` and `md` > collapsed into a single format, plus alignment of the persisted > `output.format` schema and the `INVALID_FORMAT_VALUE` hint. Only the > `--detail`/`--shape` halves of this item remain an open choice. Split the > ruled `--format` work into its own item and **raise it to P1**: it is > mandated Stable-tier contract work, not coherence debt. > Status 2026-07-27: the "implement on every non-exempt command" half > **landed** (D7: renderer registries, generic md/html fallbacks, declared > exemptions in `format-exempt.ts`, `output.format` schema widened to six), > but as SIX formats — the text/md collapse was not applied, and the > `INVALID_FORMAT_VALUE` hint still lists four values (`errors.ts:111`). > The Q-04 conflict in the drift register is the open decision; the hint > fix is deferred until that call so it is corrected once, to the final set. - **R-051 (P2) — per-command `--format/--detail/--shape` declarations are decorative.** Declared on `search`/`curate`/`show` but never read from `args`; values come from the process-wide singleton (`search-cli.ts:63-64, 131-136`). Users see help entries for flags the handler ignores. > **Reframed by the base branch (`0475870`).** The redundant declarations turn > out to be load-bearing: citty parses each command level against only its own > declared args, so a root-declared global was unknown at the leaf and its > space-separated value fell through as a positional (`akm sync --format json` > synced a bundle named "json"). `GLOBAL_OUTPUT_ARGS` now redeclares > `--format`/`--detail`/`--shape`/`--output` on **every** leaf, parse-only, > with the mode still read once from the invocation singleton > (`cli/shared.ts:138-159`). The declarations are no longer decorative — this > item is closed as fixed-by-design; only the help-text clarity ask remains. > **Completed in `453a0ba`:** the first pass covered only `defineJsonCommand` > leaves, so `improve`, `propose`, and `tasks run` (plain `defineCommand`) > still had citty parse `--format` as a boolean and spill its value into the > next positional — `improve --dry-run --format md` read "md" as the scope, > `tasks run --format md nightly` lost the task id. Each leaf now declares > the flags. - **R-052 (P2) — bash completions advertise wrong values.** `FLAG_VALUES` offers `--detail … summary` (a `--shape` value that errors) and omits `md`/`html` from `--format` (see the Q-04 note below); the table is keyed globally by flag name, so `graph --source <TAB>` suggests search's `stash registry both` (`commands/completions.ts:15-21`). The `completions` handler is also the only one not wrapped in `runWithJsonErrors`, so a non-bash shell error surfaces as `UNHANDLED_REJECTION`/exit 1 instead of a usage error/exit 2 (`cli.ts:449-452`). > Ruled 2026-07-26 (Q-04): `text` and `md` collapse into a single format, so > the accepted `--format` value set is changing — fix the completions table > against the post-Q-04 set rather than adding `md`/`html` to today's list. - **R-053 (P2) — bare-group behavior is inconsistent three ways.** `akm log`/`akm lessons` print help and exit 0; `akm backup`/`akm migrate` throw usage errors (exit 2); `akm env`/`akm config`/`akm graph` run a default action. Pick one convention. - **R-054 (P2) — `akm lessons` advertises "strength queries" that don't exist.** The group description promises them (`observability-cli.ts:205`); `lessonStrength` is written by feedback and read by ranking but not queryable from any command. Implement `lessons strength <ref>` or fix the description. - **R-055 (P2) — reads are writes, undisclosed.** `search`/`show`/`curate` append events, insert usage rows, and search bumps EMA utility scores — running a search changes future rankings (`search.ts:393`). Legitimate design for a learning index, but it should be stated on the command surface and offer an opt-out (the internal `skipLogging` already exists). - **R-056 (P2) — `akm index` writes to `config.json`** (persisting detected adapters via `mutateConfig`, `indexer.ts:600-622`). Surprising for an "build the index" command; disclose or relocate to `add`/`setup`. - **R-057 (P2) — `akm info` omits the most basic facts.** No `stashDir`, no `defaultBundle`, no per-type asset counts (`info.ts:64-78`); `searchModes` reports semantic readiness from a cached status file, not a live probe; its stats warning writes raw `process.stderr`, bypassing `--quiet` (`info.ts:103`). - **R-058 (P2) — remove/update destructive-action asymmetry.** `akm remove` prompts for confirmation; `akm update`, which can `rm -rf` the prior materialized root (`installed-stashes.ts:421-428`), does not. Also removing a plain git/website bundle leaves its mirror cache behind, and `akm clone` of an unregistered origin downloads a full package into the cache with no bundle or lock record (orphaned disk). - **R-059 (P2) — two parallel cache schemes for the same upstream.** Managed installs key `getRegistryCacheDir()` by version/revision; plain git/website mirrors key `getRegistryIndexCacheDir()` by URL hash — adding the same repo both ways stores two copies. - **R-060 (P2) — `akm log` is still `akm events` internally.** Output shapes `events-list`/`events-tail`, text headers, and the R-004 hint all use the old name. Rename the shapes at the next schemaVersion bump. - **R-061 (P2) — argv is parsed in three layers with four workaround patterns.** citty; the pre-citty `normalizeShowArgv` rewrite; the `ParsedInvocation` raw-argv singleton for repeatable flags; plus ad-hoc `process.argv.includes("--no-init")` and the `remember` positional-swallowing heuristic that covers `--format`/`--detail` but not `--shape`/`--output` (`remember.ts:303-370`). Consolidate on one parse or replace the framework — each workaround has already produced user-visible bugs (R-026, R-033). > Ruled 2026-07-26 (Q-03): `normalizeShowArgv` and the hidden `--akm*` flags > it feeds are deleted with the show view modes, removing one of the four > workaround patterns outright. Consolidate the remaining three; do not invest > further in the pre-citty rewrite layer. > Status 2026-07-27: two of the four are gone — `normalizeShowArgv` (Q-03) > and the env-unset value filter (R-026, root-caused by > `GLOBAL_OUTPUT_ARGS`). Remaining: the `ParsedInvocation` singleton (now > load-bearing by design — the one-parse rule), ad-hoc > `process.argv.includes` probes, and the `remember` positional-swallowing > heuristic, which `GLOBAL_OUTPUT_ARGS` on the `remember` leaf may make > deletable — verify against `remember.ts:303-370` before consolidating. - **R-062 (P2) — `--showSimilar` is the CLI's only camelCase flag** (`remember-cli.ts:141-144`); everything else is kebab-case, and `migrate apply` declares `dryRun` where the codebase convention is `"dry-run"`. --- ## F. Cleanup batch (P3) - **R-063 (P3) — confirmed dead code.** `parseGithubShorthand` branch (unreachable, see R-007); `injectIntoEnv` (`env.ts:115` — mutates `process.env`, forbidden by its own module docstring); secret `listNames` (`secret.ts:96`); `loadGraphMetaOnly` / `loadGraphEntitiesByPath` (`graph-db.ts:343,403`); `parseConfigValue` shim and the unreachable `toggleComponent` throw and dead `--list` flag (`config-cli.ts:44,129,136`); `listStashes`/`SourceListResult` (`source-manage.ts:36-39`); `resolveRegistries` on the search path (`registry-search.ts:35`); the `semanticSearch` projection branch (`helpers.ts:290`); curate's colon-grammar family regexes (`curate.ts:769,779`); the `session-log-failures` advisory hardwired to pass (`checks.ts:464-482`); `setup.taskSchedules` schema key nothing reads or writes. > Note (Q-02, ruled 2026-07-26): curate's colon-grammar family regexes > (`curate.ts:769,779`) are now part of the mandated colon-removal sweep — > schedule their deletion with the Q-02 work, not as standalone cleanup. - **R-064 (P3) — dead fields threaded through live signatures.** `IndexOptions.reEnrich` (flag removed, parameter still threaded three layers; `stash-cli.ts:103-112`, `indexer.ts:179-183`); `IndexResponse.graphQuality` (declared, never assigned); `acceptedActions` "always 0 since the 0.9.0 confidence-gate deletion" (`loop-stages.ts:746-750`); `durationMs` computed then `void`-ed (`improve-cli.ts:359-360`); `SourceEntry.updatable` and `.provider` set-but-never-read; `installedKitCount` (retired "Agent Kit Manager" naming) still in the public JSON envelope of add/remove/update; `workflow.db` still in the backup artifact set after the 0.9 state.db merge. - **R-065 (P3) — stale comments that assert the opposite of adjacent code.** `init.ts:9` ("ensures ripgrep is available" — nothing uses ripgrep); `info.ts:57-61` (claims to avoid the `getDbPath()` call it makes); `graph-extraction.ts:34-37` (describes retired fs.writeFile storage); `history.ts:11-15` (`events.jsonl` vs actual `state.db`); the four `TODO(R2)` markers in `workflows/program/{parser,schema}.ts` and `ir/compile.ts` describing gate loops / retry / isolation / schema validation as unimplemented — all four are implemented in `native-executor.ts`; `reflect.ts:6` / `distill.ts` / `consolidate.ts` headers documenting `akm reflect` etc. as CLI commands that were never registered; `metrics.ts:270-274` documenting a deleted metric; `setup.ts:776` (R-016). - **R-066 (P3) — duplicated logic.** Two secret-directory walkers (`secret.ts:96-115` vs `secret-cli.ts:50-74`); `ACTIVE_RUN_WARN_MS` defined twice (`health/types-result.ts:37`, `health/checks.ts:20`); the `--limit` guard copy-pasted five times in `graph.ts`; `assertSetupSandbox` invoked 2–3× per setup path; `getEffectiveRegistries()` exists but `registry list` re-implements it inline. - **R-067 (P3) — `process.exit()` mid-command bypasses cleanup.** `env run`, `secret run` (`env-cli.ts:305`, `secret-cli.ts:257`), and `runMigrationTool` exit directly, skipping the `disposeDispatchResources()` finally in `cli.ts:663-665`. - **R-068 (P3) — misc small fixes.** `show lines` coerces `start` with `Number` and `end` with `parseInt` (NaN accepted, `search-cli.ts:206-212`); `init` never checks `git init`'s exit status (`init.ts:183-188`); `.akm-include` referenced in seven comments but the real mechanism is `package.json` `akm.include`; the `semver` npm package is a runtime dependency imported nowhere in `src/` while a hand-rolled subset rejects valid ranges (`registry/semver.ts:58-99`); `graphPath` in every graph command's output is the index.db path (field name fossil, `graph-db.ts:471`); graph read commands open/close index.db twice per invocation; `--belief` is described as memory-only but filters any entry with a `beliefState` (`db-search.ts:770-787`). > Ruled 2026-07-26 (Q-03): drop the `show lines` coercion sub-item — the > `lines` view mode and the `normalizeShowArgv`/`--akmStart`/`--akmEnd` > plumbing it lives in are deleted per D2, with fragment refs as the > successor. The remaining sub-items stand. > Status 2026-07-27: D2 has landed, so the `show lines` sub-item is now moot > in code, not just ruled away. The remaining sub-items were not > individually re-verified. --- ## Explicitly reclassified as in-scope (no issue filed) Under the agent-toolkit identity, the following were reviewed and are **not** defects of scope, only subject to the coherence/safety issues above: `akm env`/`akm secret` (including run-injection and `${secret:}` interpolation), `akm agent` and the ten harness integrations, the workflow engine including the `brief`/`report` external-driver protocol, `akm tasks` and its three OS backends, the improve/proposal/collapse-detector loop, and the health observability surface. Also noted as genuinely strong and worth preserving: the journaled fs-transaction promotion/revert machinery, tar-extraction and website-crawl SSRF hardening, git-URL scheme allowlisting, the exact-path git staging in stash sync, the values-never-in-stdout secret discipline, and the uniform `{ok, error, code, hint}` error envelope.