akm-cli 0.9.15 → 0.9.16-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/CHANGELOG.md +144 -0
  2. package/dist/assets/tasks/core/index-refresh.yml +1 -1
  3. package/dist/cli/retired-commands.js +2 -0
  4. package/dist/cli/unknown-flags.js +36 -3
  5. package/dist/commands/improve/collapse-detector.js +2 -2
  6. package/dist/commands/improve/consolidate.js +6 -4
  7. package/dist/commands/improve/improve-cli.js +1 -1
  8. package/dist/commands/proposal/repository.js +12 -3
  9. package/dist/commands/read/curate.js +34 -44
  10. package/dist/commands/read/search.js +50 -2
  11. package/dist/commands/sources/index-status.js +99 -0
  12. package/dist/commands/sources/info.js +8 -8
  13. package/dist/commands/sources/installed-stashes.js +33 -12
  14. package/dist/commands/sources/source-add.js +21 -6
  15. package/dist/commands/sources/stash-cli.js +119 -111
  16. package/dist/core/adapter/adapters/akm-adapter.js +35 -3
  17. package/dist/core/adapter/adapters/akm-metadata.js +11 -1
  18. package/dist/core/asset/asset-placement.js +35 -0
  19. package/dist/core/config/schema/embedding.js +7 -30
  20. package/dist/core/config/schema/search.js +11 -9
  21. package/dist/core/errors.js +5 -2
  22. package/dist/core/hash.js +18 -0
  23. package/dist/core/maintenance-barrier.js +8 -6
  24. package/dist/core/paths.js +0 -11
  25. package/dist/core/run-lock.js +5 -2
  26. package/dist/core/state/migrations.js +26 -1
  27. package/dist/core/state-db.js +63 -27
  28. package/dist/indexer/drain.js +306 -0
  29. package/dist/indexer/embedding-identity.js +20 -0
  30. package/dist/indexer/enrich.js +260 -0
  31. package/dist/indexer/ensure-index.js +5 -0
  32. package/dist/indexer/index-written-assets.js +133 -171
  33. package/dist/indexer/indexer.js +458 -1621
  34. package/dist/indexer/lookup/adapter-concept-owner.js +19 -5
  35. package/dist/indexer/passes/metadata.js +18 -1
  36. package/dist/indexer/reconcile.js +890 -0
  37. package/dist/indexer/scan/drain-dir.js +27 -70
  38. package/dist/indexer/scan/parse-file.js +66 -0
  39. package/dist/indexer/search/db-search.js +373 -89
  40. package/dist/indexer/search/ranking-contributors.js +21 -16
  41. package/dist/indexer/search/ranking.js +135 -57
  42. package/dist/indexer/units/unit.js +159 -0
  43. package/dist/llm/client.js +10 -1
  44. package/dist/llm/embedder.js +10 -3
  45. package/dist/llm/embedders/provider-limits.js +288 -0
  46. package/dist/llm/embedders/remote.js +133 -104
  47. package/dist/llm/feature-gate.js +4 -2
  48. package/dist/llm/rerank-client.js +3 -3
  49. package/dist/output/shapes/passthrough.js +1 -0
  50. package/dist/output/text/command-format.js +19 -13
  51. package/dist/output/text/helpers.js +1 -1
  52. package/dist/output/text/index.js +5 -2
  53. package/dist/scripts/akm-migrate-node.js +1141 -1237
  54. package/dist/scripts/akm-migrate.js +1141 -1237
  55. package/dist/setup/semantic-assets.js +2 -2
  56. package/dist/setup/steps/connection.js +3 -2
  57. package/dist/storage/repositories/files-repository.js +181 -0
  58. package/dist/storage/repositories/index-connection.js +1 -3
  59. package/dist/storage/repositories/index-entries-repository.js +77 -68
  60. package/dist/storage/repositories/index-entry-schema.js +16 -25
  61. package/dist/storage/repositories/index-fts-repository.js +29 -263
  62. package/dist/storage/repositories/index-meta-repository.js +0 -29
  63. package/dist/storage/repositories/index-schema.js +115 -122
  64. package/dist/storage/repositories/index-utility-repository.js +1 -1
  65. package/dist/storage/repositories/index-vec-repository.js +21 -334
  66. package/dist/storage/repositories/units-repository.js +510 -0
  67. package/docs/migration/release-notes/0.9.15.md +34 -36
  68. package/docs/migration/release-notes/0.9.16.md +110 -0
  69. package/docs/migration/release-notes/README.md +5 -0
  70. package/docs/reference/cli.md +93 -87
  71. package/docs/reference/configuration.md +128 -89
  72. package/docs/reference/data-and-telemetry.md +2 -1
  73. package/package.json +1 -1
  74. package/schemas/akm-config.json +2 -58
  75. package/dist/indexer/index-db-contention.js +0 -56
  76. package/dist/indexer/index-rebuild-lock.js +0 -73
  77. package/dist/indexer/materialize-embeddings.js +0 -771
  78. package/dist/indexer/passes/dir-staleness.js +0 -161
  79. package/dist/storage/repositories/embedding-salvage-repository.js +0 -184
@@ -0,0 +1,110 @@
1
+ Migration notes for akm v0.9.16
2
+
3
+ The index is redesigned end to end (`docs/plans/index-redesign.md`): `akm
4
+ index` is now reconcile-then-drain instead of a walk/clean/embed/finalize
5
+ phase pipeline, everything derived from a file is keyed by the hash of what
6
+ it was derived from, and there is exactly one text table
7
+ (`unit_texts`/`units_fts`) and one vector table (`units`/`units_vec`) instead
8
+ of the old entry-level and fragment-level duplicates. The derived `index.db`
9
+ generation changes from v23 to v24.
10
+
11
+ **First run after upgrade.** On the first normal read (or an explicit `akm
12
+ index`), akm detects the v23 cache cannot serve queries under v24 and
13
+ rebuilds the derived generation: `entries` and every unit are re-derived from
14
+ your files (a stat walk plus a parse of everything, since the old generation
15
+ has no `files` stat cache to diff against — this is CPU-bound and fast, not
16
+ network-bound). The new unit vector store starts empty: the old
17
+ `embeddings`/`entries_vec` tables it replaces are not carried forward, so
18
+ every unit is embedded once at your configured provider, the same as a fresh
19
+ install. On a large corpus this is a real, paid cost, once per embedding
20
+ model, and it is never repeated for unchanged text again:
21
+ not on a rename, not on the next `akm index --full`, not on a future
22
+ generation bump, only on a genuine content or model change. Search works
23
+ lexically from the first minute of the rebuild and gains semantic results as
24
+ the embedding queue drains in the background. `akm index status` reports the
25
+ queue's progress (units with a vector for the active identity, versus
26
+ still-pending) without triggering any writes. Do not run an older akm against
27
+ an index this release has already rebuilt: upgrade that binary instead.
28
+
29
+ **Config keys removed.** `embedding.maxInputTokens`, `embedding.maxTokens`,
30
+ `embedding.batchSize`, and `embedding.contextLength` are gone from the
31
+ schema entirely (0.9.15 had already stopped reading them for packing;
32
+ 0.9.16 removes them outright). `akm index` packs every embedding request
33
+ against the provider's own probed context window and slot count — this is
34
+ unchanged from 0.9.15, only what it packs (units instead of whole entries)
35
+ moved. `search.minScore` is also gone: reciprocal-rank fusion was tried and
36
+ measured worse (0.918 mean vs. a 0.933 pre-redesign baseline, full table in
37
+ `docs/plans/index-redesign.md`) and rejected. What ships instead scores
38
+ lexical evidence by magnitude through the calibrated BM25 transform
39
+ (`stableFtsScore`) and fuses it with cosine similarity at a 0.7/0.3 split,
40
+ with the exact/prefix/relaxed lexical tier a hit came from ranking ahead of
41
+ that fused score — the transform's realized output band turned out to be
42
+ only 0.021 wide after weighting, too narrow on its own to separate a strong
43
+ match from a weak one. No separate floor is applied over any of it, which
44
+ is why `minScore` has nothing left to tune. A config file that still sets any of these five keys
45
+ loads without error — they are simply ignored, like `embedding.chunkSize`
46
+ before them — see [Retired
47
+ Configuration](../../reference/configuration.md#retired-configuration).
48
+
49
+ **`--skip-if-locked` is deprecated and does nothing.** Index runs no longer
50
+ take a rebuild lock at all — every write is a short, idempotent,
51
+ content-addressed transaction, and two concurrent `akm index` runs converge
52
+ on the same end state instead of contending — so there is nothing left to
53
+ skip around. Passing the flag prints one deprecation warning and the run
54
+ proceeds exactly as an ordinary `akm index` would; it is kept only so an
55
+ existing script or scheduled task does not fail on an unknown flag.
56
+
57
+ **`--enrich` and `--re-enrich` are removed.** Plain `akm index` now always
58
+ performs metadata enrichment when an LLM engine is configured (the same
59
+ behavior `--enrich` used to opt into); re-enrichment of index-time LLM
60
+ passes is not exposed in this slice. Both flags now fail with a `UsageError`
61
+ (exit 2) naming the replacement, rather than silently doing nothing.
62
+
63
+ **`--clean` and `--dry-run` are removed.** Every `akm index` run already
64
+ removes stale entries as part of reconcile — the same work `--clean` used to
65
+ opt into — so there is no longer a distinct pass for `--dry-run` to preview.
66
+ Both flags now fail with a `UsageError` (exit 2) instead of being silently
67
+ accepted.
68
+
69
+ **`akm index`'s result envelope renames two fields and drops one.**
70
+ `generatedMetadata` is now `entriesUpserted`: it always counted the files
71
+ reconcile added or changed, never LLM-generated metadata, so a script reading
72
+ it as enrichment coverage was being misled. `directoriesScanned` is now
73
+ `sourcesScanned`, because reconcile is a flat per-file stat walk with no
74
+ directory granularity left to count, and it reports configured source roots.
75
+ `directoriesSkipped` is gone: it could only ever be `0` under the new walk.
76
+ The text output's summary line follows the same change. A script reading the
77
+ old names gets `undefined` and should switch to the new ones.
78
+
79
+ **`akm index status` is new.** A cheap, read-only snapshot — files tracked,
80
+ entries, distinct units, how many have a vector for the active embedding
81
+ identity, the identity itself, and the last reconcile/build times — with no
82
+ writes. It mirrors `akm info`'s handling of a missing or unreadable index: an
83
+ absent index reads as the ordinary first-run state, and one that exists but
84
+ cannot be read is reported, never silently presented as empty.
85
+
86
+ **Exit codes are unchanged.** `INDEX_DB_CONTENDED` (exit 75) already existed
87
+ and still means the same thing — a second connection held a write
88
+ transaction long enough to exhaust SQLite's own busy timeout — but it now
89
+ covers genuinely rare contention instead of also standing in for the old
90
+ rebuild lock's own failure modes, which no longer exist because the rebuild
91
+ lock itself is gone.
92
+
93
+ **The optional cross-encoder rerank pass moves from `akm curate` to `akm
94
+ search`.** It was always meant for search; `search.curateRerank` (0.9.15,
95
+ #951) is renamed `search.rerank` with no compatibility alias — the old key
96
+ shipped hours earlier and default-off, so nobody has it meaningfully set.
97
+ `akm curate` no longer reranks at all.
98
+
99
+ **`"ready-js"` is retired from `akm info`'s `semanticSearch.status` and from
100
+ `akm index`'s verification status.** It named a pure-JS cosine-similarity
101
+ fallback for when the `sqlite-vec` extension was unavailable; the new unit
102
+ vector store has no BLOB-table fallback to fall back to, so nothing produces
103
+ that value any more. The two surfaces now diverge in what replaces it:
104
+ `akm info`'s `semanticSearch.status` reports `"pending"` until the
105
+ embedding queue finishes draining and `"ready-vec"` once it has — a host
106
+ without the extension can never reach `"ready-vec"` (`vecAvailable` false
107
+ rules it out) and stays `"pending"` indefinitely; that status has no
108
+ `"blocked"` value at all. `akm index`'s own verification status reports the
109
+ same `"pending"`/`"ready-vec"`, plus `"blocked"` when a run makes no
110
+ embedding progress at all.
@@ -7,6 +7,11 @@ live one level up in `docs/migration/`.
7
7
 
8
8
  ## Available notes
9
9
 
10
+ - [0.9.16](0.9.16.md) — the index redesign: `akm index` is now
11
+ reconcile-then-drain over one content-addressed text table and one vector
12
+ table, index generation v23-to-v24, five retired config keys, `--enrich`/
13
+ `--re-enrich`/`--clean`/`--dry-run` removed, `--skip-if-locked` now a
14
+ no-op, and the new `akm index status`
10
15
  - [0.9.15](0.9.15.md) — exit-code 75 for lease/state.db contention,
11
16
  `--require-engines` scheduled task templates, `--no-probe` cli-version
12
17
  skip, thinking-control wire forms, embedding re-embed safety and
@@ -218,97 +218,87 @@ and builds the search index.
218
218
  Build or refresh the search index.
219
219
 
220
220
  ```sh
221
- akm index # Incremental (only changed directories)
222
- akm index --full # Full rebuild (reuses unchanged embeddings — see below)
221
+ akm index # Reconcile: diff every configured root against the index, drain the embedding queue
222
+ akm index --full # Force every file to be re-derived, ignoring the unchanged-file shortcut, reconciling in place
223
223
  akm index --verbose # Print phase progress to stderr
224
- akm index --clean # Normal index + remove stale entries from the DB
225
- akm index --clean --dry-run # Report stale entries without deleting
226
- akm index --reembed # Force re-embedding of every entry
227
- akm index --skip-if-locked # for scheduled/opportunistic runs: skip (exit 0) if a run is already in progress
224
+ akm index --reembed # Drop the active embedding identity's vectors, then re-embed every unit from scratch
225
+ akm index status # Report file/entry/unit counts, active identity, and last-reconcile time — no writes
228
226
  ```
229
227
 
230
- Returns stats: `totalEntries`, `generatedMetadata`, `directoriesScanned`,
231
- `directoriesSkipped`, `verification`, optional `warnings`, and `timing`
232
- breakdown in milliseconds. Use `--verbose` to print the indexing mode,
228
+ Returns stats: `totalEntries`, `entriesUpserted`, `sourcesScanned`,
229
+ `verification`, optional `warnings`, and `timing` breakdown in milliseconds.
230
+ Use `--verbose` to print the indexing mode,
233
231
  semantic-search settings, and phase-by-phase progress to stderr while the
234
232
  index is being built. Malformed workflow assets are skipped with file-path
235
233
  warnings instead of aborting the full run.
236
234
 
237
- **Progress in non-verbose JSON mode (default output format, #954):** even
238
- without `--verbose`, phase-start messages and the embedding heartbeat
239
- (`Still generating embeddings: X/N stored, F failed; waiting on embedding
240
- provider.`) are now written to stderr, and a failed embedding batch logs at
241
- the default level instead of `--verbose`-only — a long-running index build
242
- against a slow or unresponsive provider is no longer silent until the whole
243
- run finishes. Text-mode output keeps its spinner instead (no stderr line
244
- growth); JSON stdout output is unaffected either way. The high-frequency
245
- per-batch `Embedded N/M entries.` line stays out of non-verbose stderr (it
246
- fires after every committed batch) — pass `--verbose` for that level of
247
- detail.
248
-
249
- **`--clean` flag:** After indexing completes, verifies every indexed entry's source
250
- file still exists on disk. Removes any entries whose file is missing (for local
251
- bundle sources only; remote entries are skipped). Returns a `clean` block in the
252
- JSON result with `checked`, `removed`, `removedRefs` arrays, and `dryRun` flag.
253
- Use `--clean` to resolve the edge case where a deleted file in an unchanged
254
- directory lingers in the index across incremental runs. With `--dry-run`, reports
255
- which entries would be removed without modifying the database.
256
-
257
- **`--full` no longer re-embeds unchanged content (#955):** a full rebuild
258
- (and an index-generation bump on first open under a new binary) used to
259
- delete every embedding unconditionally, forcing a full re-embed of the
260
- whole corpus even when nothing changed. Vectors about to be discarded are
261
- now salvaged (keyed by a hash of their content plus the fingerprint they
262
- were generated under) and handed straight back to unchanged entries at the
263
- start of the next embedding pass, with zero provider calls for them — a
264
- progress line reports the split (`Reused N embeddings from the previous
265
- generation; embedding M new.`). Content that changed even by one byte, or
266
- a fingerprint that no longer matches, still goes through the provider
267
- normally. `--reembed` is the way to force a full re-embed regardless.
268
-
269
- **`--reembed` flag:** Forces a full purge and re-embed of every entry,
270
- independent of the embedding-model-rename compatibility check described
271
- below. Ordinary indexing already tells a config-only rename of
272
- `embedding.model` (e.g. a gateway that changes how it names the same model)
273
- apart from a genuine model change, and keeps the stored vectors when they
274
- are still compatible; `--reembed` skips that check and forces a rebuild
275
- regardless of what it would have decided.
276
-
277
- **`--skip-if-locked` flag:** Every explicit `akm index` run acquires an
278
- opt-in, PID-liveness-only rebuild lock and releases it on exit — this is
279
- advisory, never the blocking lock #872 removed (see
280
- [Locks](https://github.com/itlackey/akm/blob/main/docs/architecture/internals/indexing.md#locks)). A human-typed
281
- `akm index` with no flag is never gated by it: if another run already holds
282
- the lock, it warns and proceeds anyway, contending with the existing run. If
283
- that contention makes index.db genuinely busy (SQLite `database is locked`)
284
- long enough to exhaust the driver's retry window, the run now fails with
285
- exit 75 (`TransientError`, code `INDEX_DB_CONTENDED`) instead of the raw
286
- driver error at exit 70 — the same retry-shortly contract as
287
- `STATE_DB_CONTENDED`, so a scheduler can branch on it instead of alerting.
288
- The rebuild lock itself is registered through a brief internal barrier
289
- (`getMaintenanceBarrierPath()`) shared with every other akm lock/lease; two
290
- `akm index` runs launched close enough together to collide on that
291
- registration step retry briefly and then, if it is still busy, also exit 75
292
- (code `MAINTENANCE_BARRIER_BUSY`) rather than the config-error exit 78 a
293
- 2026-09-10 field report found — a busy registration barrier is ordinary
294
- contention between two legitimate runs, never a broken config file.
295
- `--skip-if-locked` changes that only for the invocation that passes it: if
296
- the lock is already held by a live process, it skips gracefully (exit 0,
297
- `{ ok: true, skipped: { reason: "lock-held", pid, launcherPid, startedAt } }`
298
- — `launcherPid` is the holder's launcher pid when known, `null` otherwise,
299
- #956) instead of contending. `akm index` and `akm curate` are both safe to call frequently —
300
- `curate` never blocks on a rebuild in progress ([read-path indexing stays
301
- non-blocking](#curate)) — but a hook, cron job, or scheduled task that
302
- invokes `akm index` directly should pass `--skip-if-locked` so it steps
303
- aside instead of piling up behind a longer rebuild (the shipped
304
- `index-refresh` task does this).
305
-
306
- `akm index` always rebuilds the search index and keeps metadata in the index.
307
- When a selected named LLM engine (`defaults.llmEngine` or an indexing-pass
308
- override) is configured and the per-pass gate allows it, metadata
309
- enhancement runs during indexing. In text mode, the default CLI UI shows a
310
- spinner with processed-versus-total source counts; structured output modes
311
- (`json`, `yaml`, `jsonl`) stay clean and machine-readable.
235
+ **Progress in non-verbose JSON/yaml/jsonl mode:** phase-start messages and
236
+ each phase's summary line — including `[embed] endpoint ...` and `[drain]
237
+ done: ...` — reach stderr regardless of `--verbose`: a long-running index
238
+ build against a slow or unresponsive provider is no longer silent until the
239
+ whole run finishes. Two high-frequency, one-line-per-unit-of-work lines are
240
+ the exception and stay suppressed without `--verbose`: drain's per-batch
241
+ commit line (`[drain] batch N: ...`) and reconcile's per-root line
242
+ (`Reconciled "<path>": N files scanned.`) — printing one of those per batch
243
+ or per root would be spam, not a heartbeat. Pass `--verbose` to print those
244
+ two as well, alongside the same summary lines. Text mode is where
245
+ `--verbose` also matters for everything else: without it, progress updates a
246
+ single spinner line in place; with it, every line is printed as it arrives
247
+ instead. JSON stdout output is unaffected either way.
248
+
249
+ **Reconcile, not a walk-and-rebuild pipeline:** `akm index` diffs every
250
+ configured root's files against the index (stat cache: unchanged files are
251
+ skipped without a re-parse), upserts what changed, removes what is genuinely
252
+ gone, then drains the content-addressed embedding queue. Every write is a
253
+ short, idempotent transaction — there is no rebuild lock, no writer lock on
254
+ the index path, and no per-command background reindex spawn: two concurrent
255
+ `akm index` runs simply converge on the same end state instead of
256
+ contending. `akm index status` (no writes) reports file/entry/unit counts,
257
+ the active embedding identity, and the last-reconcile time.
258
+
259
+ **`--full`:** does NOT drop or wipe anything first. It reconciles with every
260
+ walked file treated as needing re-derivation — the stat-hint "unchanged"
261
+ shortcut is skipped, so every file is re-parsed — but each file's existing
262
+ row (keyed by its stable `item_ref`) is updated in place, not deleted and
263
+ reinserted: the row keeps its id, its embeddings, and its learned utility
264
+ scores. Content-addressed units (`units`/`units_vec`, keyed by content hash,
265
+ never by entry id) are never at risk from a reindex at all, `--full`
266
+ included — there is nothing to re-embed for unchanged content. Gone-path
267
+ detection (files genuinely removed) is unaffected by `--full`; a root whose
268
+ walk could not be trusted this run (an unreachable path, a mid-walk stat
269
+ failure) has its entire existing snapshot preserved rather than partially
270
+ wiped over a transient scan failure.
271
+
272
+ **`--reembed`:** drops the active embedding identity's vectors, then the
273
+ drain re-embeds every unit from scratch under that identity. Ordinary
274
+ indexing does not need a separate rename-compatibility check: the identity a
275
+ unit's vector is keyed under is exactly what the provider's response
276
+ reported (model id and vector width), so a config-only rename of
277
+ `embedding.model` that still resolves to the same server-reported model
278
+ keeps the same identity — and its stored vectors — automatically, while a
279
+ genuine model or dimension change lands under a different identity and its
280
+ units are simply "missing" until the next drain.
281
+
282
+ **`--skip-if-locked`:** deprecated, no effect — index runs no longer take a
283
+ rebuild lock, so there is nothing left to skip around. Passing it prints one
284
+ deprecation warning; the run proceeds exactly as an ordinary `akm index`
285
+ would. Kept only so an existing script or scheduled task does not fail on an
286
+ unknown flag. If index.db is genuinely busy (a second connection holds a
287
+ write transaction) long enough to exhaust the driver's own SQLite
288
+ `busy_timeout`, the run fails with exit 75 (`TransientError`, code
289
+ `INDEX_DB_CONTENDED`) instead of the raw driver error at exit 70 — the same
290
+ retry-shortly contract as `STATE_DB_CONTENDED`, so a scheduler can branch on
291
+ it instead of alerting.
292
+ Locks that do still exist (`akm improve`, `akm workflow run`) are registered through a brief
293
+ internal barrier shared by every akm lock and lease; two runs launched close enough together to
294
+ collide on that registration step retry briefly and then, if it is still busy, exit 75 (code
295
+ `MAINTENANCE_BARRIER_BUSY`) rather than the config-error exit 78 a 2026-09-10 field report
296
+ found — a busy registration barrier is ordinary contention between two legitimate runs, never a
297
+ broken config file.
298
+
299
+ In text mode, the default CLI UI shows a spinner with processed-versus-total
300
+ source counts; structured output modes (`json`, `yaml`, `jsonl`) stay clean
301
+ and machine-readable.
312
302
 
313
303
  ### info
314
304
 
@@ -337,12 +327,16 @@ Returns a JSON object with:
337
327
  | `indexStats` | Index stats: `entryCount`, `byType` (per-asset-type breakdown), `lastBuiltAt`, `hasEmbeddings`, `vecAvailable` |
338
328
 
339
329
  `semanticSearch.status` values:
340
- - `"ready-vec"` — native sqlite-vec extension active (fastest)
341
- - `"ready-js"` — pure JS fallback active (correct but slower at scale)
330
+ - `"ready-vec"` — embeddings present, `sqlite-vec` active
342
331
  - `"pending"` — not yet initialized (run `akm index` to set up)
343
- - `"blocked"` — setup failed (see `reason` and `message` fields)
344
332
  - `"disabled"` — semantic search is turned off in config
345
333
 
334
+ (`"ready-js"`, a pure-JS cosine fallback for when the extension was
335
+ unavailable, is retired — the unit vector store has no BLOB fallback to fall
336
+ back to. A degraded/failed embedding run is reflected here as `"pending"`,
337
+ not a separate `"blocked"` value; see `akm index`'s own `verification.semanticStatus`,
338
+ which does distinguish `"blocked"`, for that detail.)
339
+
346
340
  Use `akm info` to verify that semantic search is working after setup.
347
341
 
348
342
  Scripts that need akm's resolved paths (for example a health check that
@@ -499,6 +493,18 @@ query. The last case also adds one sanitized, endpoint-naming entry to
499
493
  preserved by `--shape agent` so machine consumers can lower their confidence
500
494
  instead of treating keyword fallback as healthy semantic ranking.
501
495
 
496
+ An optional cross-encoder rerank pass (#951, `search.rerank.*` —
497
+ `docs/reference/configuration.md`) can run over local hits before `--from
498
+ local`/`--from all` diverge; disabled by default, and registry hits (`--from
499
+ registry`, and the registry half of `--from all`) are never reranked. When it
500
+ runs, it changes hit **ORDER** only — each hit's `score` stays the retrieval
501
+ score `akm search` computed, not the reranker's own relevance value. A
502
+ consumer that wants the reranked ranking must read hits in ARRAY ORDER, not
503
+ by re-sorting on `score`: `score` is a fixed `[0,1]` contract (see the
504
+ callout below) that a reranker's own scale — provider-defined, not
505
+ calibrated to `[0,1]` — would break if it overwrote it, and a re-sort would
506
+ silently undo the rerank for exactly the consumers it exists to serve.
507
+
502
508
  | Flag | Values | Default | Description |
503
509
  | --- | --- | --- | --- |
504
510
  | `--type` | `skill`, `command`, `agent`, `knowledge`, `instruction`, `workflow`, `script`, `memory`, `env`, `secret`, `lesson`, `task`, `session`, `fact`, `any` | `any` | Filter by asset type. Free-form and unvalidated — an unknown type returns no hits. Also accepts any adapter-defined type (e.g. `website`) — see [Bundle Types](bundle-types.md) for the open types each adapter emits. |