akm-cli 0.10.261016-beta → 0.10.261017-beta
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.
- package/CHANGELOG.md +100 -0
- package/README.md +8 -10
- package/SECURITY.md +7 -99
- package/STABILITY.md +57 -98
- package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +2 -2
- package/dist/assets/stash-skeleton/facts/conventions/organization.md +11 -17
- package/dist/cli.js +32 -41
- package/dist/commands/feedback-cli.js +5 -4
- package/dist/commands/health.js +15 -16
- package/dist/commands/proposal/proposal-cli.js +1 -1
- package/dist/commands/read/registry-search.js +4 -1
- package/dist/commands/read/search.js +6 -6
- package/dist/commands/sources/self-update.js +9 -5
- package/dist/commands/tasks/tasks.js +12 -13
- package/dist/core/adapter/adapters/agent-skills-adapter.js +7 -7
- package/dist/core/adapter/adapters/akm-task-adapter.js +1 -1
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +1 -1
- package/dist/core/adapter/adapters/claude-adapter.js +1 -1
- package/dist/core/adapter/adapters/dotenv-adapter.js +1 -1
- package/dist/core/adapter/adapters/generic-files-adapter.js +1 -1
- package/dist/core/adapter/adapters/llm-wiki-adapter.js +1 -1
- package/dist/core/adapter/adapters/opencode-adapter.js +1 -1
- package/dist/core/adapter/adapters/website-snapshot-adapter.js +1 -1
- package/dist/core/bundle-rename.js +17 -7
- package/dist/indexer/bundle-identity-guard.js +6 -6
- package/dist/indexer/index-written-assets.js +3 -3
- package/dist/indexer/indexer.js +12 -8
- package/dist/indexer/materialize-embeddings.js +12 -2
- package/dist/indexer/passes/metadata.js +103 -46
- package/dist/indexer/search/ranking.js +7 -3
- package/dist/indexer/search/search-fields.js +1 -1
- package/dist/indexer/usage/usage-events.js +30 -8
- package/dist/indexer/walk/walker.js +1 -1
- package/dist/output/shapes/helpers.js +3 -3
- package/dist/output/text/command-format.js +5 -6
- package/dist/scripts/akm-migrate-node.js +31 -3
- package/dist/scripts/akm-migrate.js +31 -3
- package/dist/sources/providers/git-provider.js +2 -4
- package/dist/sources/providers/provider-utils.js +8 -13
- package/dist/sources/snapshot-fetchers/website-ingest.js +6 -7
- package/dist/storage/repositories/events-repository.js +15 -0
- package/dist/storage/repositories/improve-ledger-repository.js +13 -0
- package/dist/storage/repositories/index-entries-repository.js +43 -5
- package/dist/storage/repositories/outcome-repository.js +12 -0
- package/dist/storage/repositories/proposals-repository.js +5 -5
- package/dist/storage/repositories/salience-repository.js +13 -0
- package/dist/storage/repositories/task-history-repository.js +8 -7
- package/dist/storage/repositories/workflow-runs-repository.js +10 -8
- package/docs/README.md +24 -60
- package/docs/agents/README.md +3 -8
- package/docs/architecture/README.md +18 -20
- package/docs/architecture/adapters.md +40 -43
- package/docs/architecture/architecture.md +171 -151
- package/docs/architecture/improvement.md +95 -91
- package/docs/architecture/internals/classification.md +101 -119
- package/docs/architecture/internals/fresh-host-rebuild-runbook.md +33 -35
- package/docs/architecture/internals/health-advisories.md +59 -46
- package/docs/architecture/internals/improve-workflow.md +166 -693
- package/docs/architecture/internals/indexing.md +65 -465
- package/docs/architecture/internals/storage-locations.md +301 -848
- package/docs/architecture/persisted-data-compat.md +6 -6
- package/docs/architecture/specs/okf-support.md +67 -95
- package/docs/architecture/specs/ref.md +67 -125
- package/docs/architecture/testing/testing-workflow.md +107 -167
- package/docs/architecture/workflow-engine.md +34 -33
- package/docs/guides/README.md +5 -5
- package/docs/guides/author-bundles.md +72 -98
- package/docs/guides/author-workflows.md +11 -18
- package/docs/guides/bundles.md +91 -123
- package/docs/guides/capture-knowledge.md +10 -9
- package/docs/guides/concepts.md +45 -30
- package/docs/guides/discover-and-load.md +39 -32
- package/docs/guides/getting-started.md +24 -24
- package/docs/guides/improve-the-library.md +98 -80
- package/docs/guides/recipes/headless-install.md +4 -4
- package/docs/guides/recipes/website-source.md +9 -5
- package/docs/guides/run-workflows.md +10 -11
- package/docs/guides/scheduling.md +11 -17
- package/docs/guides/use-with-any-agent.md +15 -14
- package/docs/guides/wikis.md +6 -9
- package/docs/integration/bundling-akm.md +21 -26
- package/docs/maintainers/README.md +2 -2
- package/docs/maintainers/local-development.md +3 -16
- package/docs/migration/README.md +2 -1
- package/docs/migration/release-notes/0.10.0.md +167 -22
- package/docs/migration/release-notes/README.md +2 -2
- package/docs/migration/v0.9-to-v0.10.md +47 -7
- package/docs/product-surface.md +10 -8
- package/docs/reference/README.md +26 -15
- package/docs/reference/asset-types.md +11 -12
- package/docs/reference/bundle-types.md +6 -5
- package/docs/reference/cli.md +52 -28
- package/docs/reference/configuration.md +46 -60
- package/docs/reference/data-and-telemetry.md +204 -421
- package/docs/reference/env-and-secrets.md +80 -83
- package/docs/reference/memory.md +1 -1
- package/docs/reference/refs.md +23 -36
- package/docs/reference/registry.md +138 -348
- package/docs/reference/supported-formats.md +8 -8
- package/docs/reference/tasks.md +13 -19
- package/docs/reference/website-sources.md +23 -15
- package/docs/reference/workflow-schema.md +28 -47
- package/docs/reference/workflows.md +33 -37
- package/package.json +1 -1
|
@@ -2,12 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
akm is a Bun-based CLI for discovering and using agent assets from local
|
|
4
4
|
filesystem sources, cache-backed sources (git, website, npm), and registry
|
|
5
|
-
catalogs.
|
|
6
|
-
|
|
7
|
-
This document is the operating summary of the current architecture and is the
|
|
8
|
-
current-truth reference.
|
|
9
|
-
|
|
10
|
-
---
|
|
5
|
+
catalogs. This page summarizes how it is put together.
|
|
11
6
|
|
|
12
7
|
## Invariants
|
|
13
8
|
|
|
@@ -119,12 +114,11 @@ canonical source directory through `src/core/asset/asset-placement.ts`'s
|
|
|
119
114
|
`PLACEMENT_SPECS` map. See
|
|
120
115
|
[Bundle Types](../reference/bundle-types.md) for the full table.
|
|
121
116
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
not a per-file type stamped by the classifier (see
|
|
117
|
+
`env` holds whole `.env` files and `secret` holds single-value secret files.
|
|
118
|
+
`wiki` is not an item type: multi-page wikis are a bundle *format* owned by the
|
|
119
|
+
`llm-wiki` adapter, not a per-file type stamped by the classifier (see
|
|
126
120
|
[Classification](internals/classification.md) and
|
|
127
|
-
[Bundle Types](../reference/bundle-types.md) for the other
|
|
121
|
+
[Bundle Types](../reference/bundle-types.md) for the ten other formats akm
|
|
128
122
|
recognizes besides its own native one).
|
|
129
123
|
|
|
130
124
|
---
|
|
@@ -145,9 +139,9 @@ All four kinds expose the same minimal `SourceProvider` interface
|
|
|
145
139
|
```ts
|
|
146
140
|
interface SourceProvider {
|
|
147
141
|
readonly name: string;
|
|
148
|
-
readonly kind:
|
|
142
|
+
readonly kind: SourceKind; // "filesystem" | "git" | "website" | "npm"
|
|
149
143
|
path(): string; // directory the indexer walks
|
|
150
|
-
sync?(options?:
|
|
144
|
+
sync?(options?: SyncOptions): Promise<void>; // refresh from upstream (no-op for filesystem)
|
|
151
145
|
}
|
|
152
146
|
```
|
|
153
147
|
|
|
@@ -155,17 +149,14 @@ Providers do **not** implement `search`, `show`, `canShow`, or any read method.
|
|
|
155
149
|
The indexer walks `path()`, classifies files, and answers all queries from the
|
|
156
150
|
local FTS5 index.
|
|
157
151
|
|
|
158
|
-
File semantics are owned by the selected bundle adapter
|
|
159
|
-
least-common-denominator for
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
environment, secret, memory, and
|
|
163
|
-
|
|
164
|
-
validation, redaction, and placement
|
|
165
|
-
|
|
166
|
-
The legacy `LiveStashProvider` / `SyncableStashProvider` split is gone, as is
|
|
167
|
-
any "remote-only" provider tier. API-backed sources (mem0, Notion, etc.) are
|
|
168
|
-
deferred to a separate `QuerySource` tier post-v1.
|
|
152
|
+
File semantics are owned by the selected bundle adapter (see
|
|
153
|
+
[Adapters](adapters.md)). OKF is the first-class least-common-denominator for
|
|
154
|
+
Markdown path identity, open types, content, links, and heading fragments. The
|
|
155
|
+
`akm` format is an OKF-compatible Markdown superset: its adapter progressively
|
|
156
|
+
adds native command, script, workflow, task, environment, secret, memory, and
|
|
157
|
+
lesson behavior. Non-Markdown formats retain their native serialization and
|
|
158
|
+
every adapter retains its own capability, validation, redaction, and placement
|
|
159
|
+
rules.
|
|
169
160
|
|
|
170
161
|
### Cache-backed sources are still indexed locally
|
|
171
162
|
|
|
@@ -174,6 +165,19 @@ deferred to a separate `QuerySource` tier post-v1.
|
|
|
174
165
|
indexing pipeline as filesystem sources. There is no parallel scoring system
|
|
175
166
|
for "remote" content.
|
|
176
167
|
|
|
168
|
+
A cache-backed source is fetched when it is added and when `akm bundle update`
|
|
169
|
+
forces a sync. `akm index` calls `sync()` without `force`, so it fetches a
|
|
170
|
+
source only if it has never been materialized on this host; nothing refreshes
|
|
171
|
+
on a timer. A git or npm install recorded in the lockfile whose files are
|
|
172
|
+
missing is reported with a warning that names `akm bundle update`; index does
|
|
173
|
+
not fetch it. A configured npm bundle with no lock entry has no walkable path,
|
|
174
|
+
so index skips it with a warning that names `akm bundle update` instead of
|
|
175
|
+
calling `sync()`.
|
|
176
|
+
|
|
177
|
+
`akm index` indexes each source through its bundle's adapter. A source that
|
|
178
|
+
could not be walked completely keeps its previously indexed rows and the index
|
|
179
|
+
run warns; a bundle whose adapter id is unknown is skipped with a warning.
|
|
180
|
+
|
|
177
181
|
---
|
|
178
182
|
|
|
179
183
|
## Refs
|
|
@@ -185,16 +189,17 @@ User-facing item refs are path-identified:
|
|
|
185
189
|
```
|
|
186
190
|
|
|
187
191
|
- the subdir-qualified `conceptId` (`skills/code-review`) identifies an item
|
|
188
|
-
within a bundle; `type` is
|
|
192
|
+
within a bundle; `type` is not a ref segment
|
|
189
193
|
- the fully qualified `bundle//conceptId` spelling is canonical in index rows
|
|
190
194
|
and durable state; index-backed local read output keeps the short form for the
|
|
191
195
|
default bundle and qualifies every non-default bundle
|
|
192
196
|
- optional `bundle//` narrows input lookup to a configured bundle
|
|
193
197
|
- refs are parsed by `parseBundleRef` in `src/core/asset/asset-ref.ts`
|
|
194
198
|
- markdown-backed items strip `.md` from canonical names
|
|
195
|
-
- `#fragment` is input-only and never stored
|
|
196
|
-
core resolves it as a
|
|
197
|
-
|
|
199
|
+
- `#fragment` is input-only and never stored, and `akm show` is the only command
|
|
200
|
+
that accepts one: on markdown-document items the core resolves it as a
|
|
201
|
+
section selector (`knowledge/api-guide#authentication`); on any other item
|
|
202
|
+
`akm show` ignores the fragment, warns, and shows the whole item
|
|
198
203
|
- refs embedded in prose must be fully qualified (`bundle//conceptId`) or a
|
|
199
204
|
native adapter link form — a bare conceptId in prose is ordinary text, and no
|
|
200
205
|
tool rewrites it
|
|
@@ -215,11 +220,10 @@ Examples:
|
|
|
215
220
|
- `workflows/release/train`
|
|
216
221
|
- `team//commands/deploy`
|
|
217
222
|
|
|
218
|
-
URI schemes
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
`
|
|
222
|
-
`akm add` / `akm clone`.
|
|
223
|
+
URI schemes are **not** asset refs. Install locators like `github:owner/repo`,
|
|
224
|
+
`git+https://...`, `npm:@scope/pkg`, and `./local/path` are a
|
|
225
|
+
separate grammar parsed by `parseRegistryRef` in `src/registry/resolve.ts` and
|
|
226
|
+
consumed by `akm bundle add` and `akm clone`.
|
|
223
227
|
|
|
224
228
|
---
|
|
225
229
|
|
|
@@ -235,12 +239,17 @@ There is **one** ranking for all indexed content: reciprocal rank fusion
|
|
|
235
239
|
through the model's embedding profile (`src/llm/embedders/profile.ts`)
|
|
236
240
|
|
|
237
241
|
Filters (type, source, scope, belief, proposed quality, default-excluded
|
|
238
|
-
types)
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
242
|
+
types) drop ineligible entries from each list before its 100 candidates are
|
|
243
|
+
taken. The fused score is then multiplied by
|
|
244
|
+
`1 + 0.03 × (ln(1 + positives) − ln(1 + negatives))` over the user's recorded
|
|
245
|
+
feedback for the asset (`applyFeedback` in `src/indexer/search/ranking.ts`;
|
|
246
|
+
[`akm feedback`](../reference/cli.md#feedback) says which feedback counts, and
|
|
247
|
+
an asset with none keeps its fused score), and the list is re-sorted, equal
|
|
248
|
+
scores by fully qualified ref (`<bundle>//<conceptId>`). A hit's `score` is
|
|
249
|
+
that adjusted score. One-hit-per-file deduplication, and keeping only
|
|
250
|
+
the highest-ranked of entries with identical indexed content, then drop entries
|
|
251
|
+
from the sorted list without reordering it. Nothing else — name, type, tag,
|
|
252
|
+
graph, utility score or belief-state signals — changes the order.
|
|
244
253
|
|
|
245
254
|
Notes:
|
|
246
255
|
|
|
@@ -250,11 +259,13 @@ Notes:
|
|
|
250
259
|
- the query embedding is requested before the FTS query runs and is bounded
|
|
251
260
|
by `embedding.queryTimeoutMs` (default 3000); on timeout or failure the
|
|
252
261
|
search is served by the lexical list alone
|
|
253
|
-
- Markdown fragments are not searched; `
|
|
254
|
-
|
|
255
|
-
- `hints`
|
|
256
|
-
|
|
257
|
-
- `content` is bounded
|
|
262
|
+
- Markdown fragments are not searched; they are a `show` feature (see
|
|
263
|
+
[Show Resolution](#show-resolution))
|
|
264
|
+
- `hints` carries search hints, examples, usage, intent fields, cross-references,
|
|
265
|
+
page kind, and when-to-use text
|
|
266
|
+
- `content` is bounded body text plus TOC headings and parameter metadata; `env`
|
|
267
|
+
and `secret` entries index key names and file names only, and session bodies
|
|
268
|
+
are not indexed
|
|
258
269
|
- registry results live in `registryHits`, never in `hits`
|
|
259
270
|
- `--from all` keeps registry results in `registryHits` — they are not
|
|
260
271
|
rank-merged with source hits
|
|
@@ -265,12 +276,12 @@ Notes:
|
|
|
265
276
|
- local search and curate expose the actual execution in `searchMode`:
|
|
266
277
|
`semantic`, intentional/unavailable `keyword`, or `fts-fallback` when a
|
|
267
278
|
ready semantic runtime failed during the query; that degradation also
|
|
268
|
-
surfaces as one
|
|
269
|
-
- usage-event writes are best-effort;
|
|
270
|
-
|
|
279
|
+
surfaces as one `warnings[]` entry, including in agent shape
|
|
280
|
+
- usage-event writes are best-effort; a read-only filesystem drops them
|
|
281
|
+
silently and does not change `searchMode`
|
|
271
282
|
|
|
272
283
|
`akm search` is implemented in `src/commands/read/search.ts` and queries the
|
|
273
|
-
indexer's local search (`src/indexer/search/db-search.ts`).
|
|
284
|
+
indexer's local search (`src/indexer/search/db-search.ts`).
|
|
274
285
|
|
|
275
286
|
---
|
|
276
287
|
|
|
@@ -283,23 +294,21 @@ Local show flow (`src/commands/read/show.ts`):
|
|
|
283
294
|
1. parse `[bundle//]conceptId`
|
|
284
295
|
2. `lookup(ref)` by indexed `item_ref` and materialized source root
|
|
285
296
|
3. return the indexed canonical ref and read `file_path` from disk
|
|
286
|
-
4. report not-found when no index row resolves
|
|
287
|
-
a lower-priority source from retargeting a ref, but never authorizes a
|
|
288
|
-
direct file read
|
|
297
|
+
4. report not-found when no index row resolves
|
|
289
298
|
5. apply generic Markdown content/fragment presentation for OKF, or the owning
|
|
290
299
|
adapter's progressively enhanced native presentation
|
|
291
300
|
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
selected fragments from that same indexed
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
301
|
+
A friendly heading fragment (`#authentication`) selects a section of the live
|
|
302
|
+
file. An opaque `#akm-fragment-...` selector resolves against the safe Markdown
|
|
303
|
+
revision persisted in `entry_fragments`, so it stays consistent if the
|
|
304
|
+
materialized file changes before it is reindexed. The opt-in `--context lead`
|
|
305
|
+
projection assembles the first and selected fragments from that same indexed
|
|
306
|
+
revision under a character budget (`--max-chars` or `--max-tokens`), labels the
|
|
307
|
+
selected match, and keeps it last. Opaque and contextual show JSON exposes the
|
|
308
|
+
selected and parent refs, one-based ordinal and count, source-line bounds,
|
|
309
|
+
neighbor refs, and separate fragment and parent size estimates; the canonical
|
|
310
|
+
`ref` remains the parent. An exact friendly-heading show stays source-live and
|
|
311
|
+
omits indexed provenance.
|
|
303
312
|
|
|
304
313
|
There is **no provider or local-disk fallback** for asset refs. The file is
|
|
305
314
|
read only after an indexed row resolves it.
|
|
@@ -308,26 +317,25 @@ read only after an indexed row resolves it.
|
|
|
308
317
|
|
|
309
318
|
Agent-shaped search, show, and curate results for materialized local assets
|
|
310
319
|
include the index-backed `ref`, absolute `path`, and `editable`. `editHint` is
|
|
311
|
-
included only when `editable` is `false`; it is secondary guidance and
|
|
312
|
-
|
|
320
|
+
included only when `editable` is `false`; it is secondary guidance and does not
|
|
321
|
+
replace the normal show, run, or use action (or curate follow-up). Registry-only
|
|
313
322
|
results have no local path or editability fields.
|
|
314
323
|
|
|
315
|
-
`editable` means
|
|
316
|
-
|
|
317
|
-
the current resolved source roots
|
|
318
|
-
|
|
324
|
+
`editable` means the asset's file belongs to a configured source whose
|
|
325
|
+
effective `writable` policy is true. It is computed when the response is built
|
|
326
|
+
from the current resolved source roots, is not stored in the index, and is
|
|
327
|
+
`false` when no configured source owns the path.
|
|
319
328
|
|
|
320
329
|
---
|
|
321
330
|
|
|
322
331
|
## Writing to Sources
|
|
323
332
|
|
|
324
|
-
Writes go through one helper: `src/core/write-source.ts`.
|
|
325
|
-
place
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
kind-neutral wrapper that absorbs the guard and no-ops otherwise:
|
|
333
|
+
Writes go through one helper: `src/core/write-source.ts`. It is the only
|
|
334
|
+
place that should branch on `source.kind`; command layers do not hold provider
|
|
335
|
+
knowledge. That is a convention that code review holds (core principle 2), not
|
|
336
|
+
a lint rule. Where a step is meaningful only for a publication-backed target,
|
|
337
|
+
`write-source.ts` exposes a kind-neutral wrapper that does the work for a git
|
|
338
|
+
target and does nothing otherwise:
|
|
331
339
|
`prepareWriteTargetForMutation`, `commitWriteTargetBoundary`, and
|
|
332
340
|
`withWriteTargetMutation` (write the file, `git add` exactly the recorded
|
|
333
341
|
paths, commit, push with `--force-with-lease` when configured). Recording a
|
|
@@ -341,9 +349,11 @@ deleteAssetFromSource(source, config, ref)
|
|
|
341
349
|
|
|
342
350
|
The flow:
|
|
343
351
|
|
|
344
|
-
1. Refuse if the source is not `writable
|
|
345
|
-
|
|
346
|
-
|
|
352
|
+
1. Refuse if the source is not `writable`, is not a `filesystem` or `git`
|
|
353
|
+
source, or belongs to a bundle whose adapter is not on the write allowlist
|
|
354
|
+
(see [Adapters](adapters.md#write-allowlists)).
|
|
355
|
+
2. Atomic filesystem write to `path.join(source.path, …)` with no commit. A git
|
|
356
|
+
target records the path for the boundary commit.
|
|
347
357
|
|
|
348
358
|
Git-backed targets are committed in a single batch at the operation boundary via
|
|
349
359
|
`commitWriteTargetBoundary(target, message, { push })`, which delegates to
|
|
@@ -351,10 +361,9 @@ Git-backed targets are committed in a single batch at the operation boundary via
|
|
|
351
361
|
boundary, which stages and commits only those files (so unrelated staged work,
|
|
352
362
|
including work under the same asset directory, is not included). Improve
|
|
353
363
|
auto-sync similarly subtracts the Git dirty-path baseline captured at invocation
|
|
354
|
-
start. Push
|
|
355
|
-
|
|
356
|
-
config
|
|
357
|
-
schema (`src/core/config/schema/sources-bundles.ts`).
|
|
364
|
+
start. Push happens when the target is writable, has an upstream, and `push` is
|
|
365
|
+
not `false`. `options.pushOnCommit` is not supported: config load reports it
|
|
366
|
+
(`src/core/config/schema/sources-bundles.ts`).
|
|
358
367
|
|
|
359
368
|
`writable` is a config flag, not an interface concern. Defaults: `true` for
|
|
360
369
|
`filesystem`, `false` for everything else. `writable: true` on `website` or
|
|
@@ -363,11 +372,10 @@ refresh.
|
|
|
363
372
|
|
|
364
373
|
Write-target resolution (`resolveWriteTarget`) follows: an explicit
|
|
365
374
|
destination flag (`--bundle`) -> `config.defaultWriteTarget` -> working
|
|
366
|
-
bundle (`defaultBundle`) -> `ConfigError`.
|
|
367
|
-
|
|
368
|
-
that must re-resolve a destination
|
|
369
|
-
state rows always use `source.name`.
|
|
370
|
-
no selector but has durable identity `stash`.
|
|
375
|
+
bundle (`defaultBundle`) -> `ConfigError`. There is no fallback to the first
|
|
376
|
+
writable source. The resolved target keeps the optional configured selector
|
|
377
|
+
separate from the stable `source.name`: APIs that must re-resolve a destination
|
|
378
|
+
use the selector, while durable refs and state rows always use `source.name`.
|
|
371
379
|
|
|
372
380
|
On mutation surfaces that accept asset refs, a qualified ref implies its
|
|
373
381
|
bundle as the write target. A matching explicit destination flag is allowed;
|
|
@@ -382,16 +390,16 @@ combined with `--bundle`.
|
|
|
382
390
|
|
|
383
391
|
### Improve durable-state identity
|
|
384
392
|
|
|
385
|
-
Improve readers and writers use one current key for each asset
|
|
386
|
-
indexed entry uses its fully
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
convergence state.
|
|
393
|
+
Improve readers and writers use one current key for each asset (`stateKey`,
|
|
394
|
+
`src/commands/improve/ledger.ts`). A resolved indexed entry uses its fully
|
|
395
|
+
qualified `item_ref`; a direct or provenance-free ref uses its current concept
|
|
396
|
+
ID. There is no alternate root-based key, bare alias merge, or second state
|
|
397
|
+
lookup, so a duplicate concept in another installation does not inherit
|
|
398
|
+
unrelated feedback, proposal-cursor, salience, or convergence state.
|
|
391
399
|
|
|
392
400
|
Retrieval demand is scoped separately through usage-event entry IDs and selected
|
|
393
|
-
source roots, with qualified refs covering detached events. Improve
|
|
394
|
-
retrieval counts or last-use timestamps
|
|
401
|
+
source roots, with qualified refs covering detached events. Improve does not
|
|
402
|
+
merge retrieval counts or last-use timestamps by bare ref across sources.
|
|
395
403
|
|
|
396
404
|
### Proposal queues and destinations
|
|
397
405
|
|
|
@@ -399,10 +407,9 @@ retrieval counts or last-use timestamps solely by bare ref across sources.
|
|
|
399
407
|
whose proposal queue is read or adjudicated; it does not override the proposal's
|
|
400
408
|
write destination. Qualified proposals and unqualified proposals created in a
|
|
401
409
|
configured secondary queue record the destination source name and materialized
|
|
402
|
-
root. Diff, accept, and revert use that binding by default and
|
|
403
|
-
`--bundle` that resolves elsewhere. An unbound short proposal
|
|
404
|
-
|
|
405
|
-
inherit a default write target.
|
|
410
|
+
root. Diff, accept, and revert use that binding by default and refuse an
|
|
411
|
+
explicit `--bundle` that resolves elsewhere. An unbound short proposal needs
|
|
412
|
+
either `--bundle` or `--queue`; it does not inherit a default write target.
|
|
406
413
|
|
|
407
414
|
---
|
|
408
415
|
|
|
@@ -419,19 +426,17 @@ interface RegistryProvider {
|
|
|
419
426
|
```
|
|
420
427
|
|
|
421
428
|
The contract is a single `search()` method — the orchestrator's only entry
|
|
422
|
-
point. Implementations
|
|
423
|
-
|
|
429
|
+
point. Implementations return errors as `warnings[]` on the result instead of
|
|
430
|
+
throwing.
|
|
424
431
|
|
|
425
432
|
Built-in registries:
|
|
426
433
|
|
|
427
434
|
| Kind | Role |
|
|
428
435
|
| --- | --- |
|
|
429
|
-
| `static-index` | Reads the v2 or v3 JSON index schema, same `stashes[]` wire format (official akm registry, team mirrors). `scripts/build-registry-index.ts` emits v3
|
|
436
|
+
| `static-index` | Reads the v2 or v3 JSON index schema, same `stashes[]` wire format (official akm registry, team mirrors). `scripts/build-registry-index.ts` emits v3. |
|
|
430
437
|
| `skills-sh` | Wraps the skills.sh REST API. |
|
|
431
438
|
|
|
432
|
-
Context Hub is **not** a registry provider type.
|
|
433
|
-
kit installable through the official static-index registry like any other
|
|
434
|
-
source.
|
|
439
|
+
These two are the only registry provider types, and Context Hub is **not** a registry provider type.
|
|
435
440
|
|
|
436
441
|
---
|
|
437
442
|
|
|
@@ -441,7 +446,9 @@ Workflow definitions live in `workflows/`, but workflow run state is separate
|
|
|
441
446
|
durable runtime state. `workflow_runs`, `workflow_run_steps`,
|
|
442
447
|
`workflow_run_units`, and `workflow_run_unit_attempts` live in `state.db`
|
|
443
448
|
alongside events, tasks, and proposals. `index.db` remains rebuildable search
|
|
444
|
-
state, while `logs.db` stores task/run log lines.
|
|
449
|
+
state, while `logs.db` stores task/run log lines. See
|
|
450
|
+
[The Workflow Engine](workflow-engine.md) for how a run is frozen, driven, and
|
|
451
|
+
resumed.
|
|
445
452
|
|
|
446
453
|
- workflow discovery and search use the shared asset index
|
|
447
454
|
- workflow run records survive index rebuilds
|
|
@@ -462,28 +469,31 @@ improve's salience work; search ranking does not read it.
|
|
|
462
469
|
|
|
463
470
|
## Errors
|
|
464
471
|
|
|
465
|
-
`ConfigError`, `UsageError`, and `
|
|
466
|
-
carry a stable `code` and a `hint(): string |
|
|
467
|
-
surfaces hints by calling `error.hint()` directly —
|
|
468
|
-
parsing error messages.
|
|
469
|
-
|
|
470
|
-
All
|
|
471
|
-
discriminant (`"config" | "usage" | "not-found"`). The CLI
|
|
472
|
-
(`classifyExitCode` in `src/cli/shared.ts`) switches
|
|
473
|
-
(`never`-checked via `assertNever`), so adding a new
|
|
474
|
-
compile-time error until its exit code is mapped. Any thrown
|
|
475
|
-
**not** an `AkmError` is treated as an unexpected internal
|
|
476
|
-
the distinct INTERNAL exit code **70** (sysexits
|
|
477
|
-
scripts tell "akm threw unexpectedly" apart from an
|
|
478
|
-
(exit 1).
|
|
472
|
+
`ConfigError`, `UsageError`, `NotFoundError`, and `TransientError` (in
|
|
473
|
+
`src/core/errors.ts`) each carry a stable `code` and a `hint(): string |
|
|
474
|
+
undefined` method. The CLI surfaces hints by calling `error.hint()` directly —
|
|
475
|
+
there is no regex chain parsing error messages.
|
|
476
|
+
|
|
477
|
+
All four extend a shared abstract base `AkmError` carrying a `kind`
|
|
478
|
+
discriminant (`"config" | "usage" | "not-found" | "transient"`). The CLI
|
|
479
|
+
exit-code classifier (`classifyExitCode` in `src/cli/shared.ts`) switches
|
|
480
|
+
exhaustively on `kind` (`never`-checked via `assertNever`), so adding a new
|
|
481
|
+
error class is a compile-time error until its exit code is mapped. Any thrown
|
|
482
|
+
value that is **not** an `AkmError` is treated as an unexpected internal
|
|
483
|
+
failure and maps to the distinct INTERNAL exit code **70** (sysexits
|
|
484
|
+
`EX_SOFTWARE`) — this lets scripts tell "akm threw unexpectedly" apart from an
|
|
485
|
+
ordinary `NotFoundError` (exit 1).
|
|
479
486
|
|
|
480
487
|
| Class / case | Exit code |
|
|
481
488
|
| --- | --- |
|
|
482
489
|
| `ConfigError` (`kind: "config"`) | 78 |
|
|
483
490
|
| `UsageError` (`kind: "usage"`) | 2 |
|
|
484
491
|
| `NotFoundError` (`kind: "not-found"`) | 1 |
|
|
492
|
+
| `TransientError` (`kind: "transient"`) — another akm process holds a lock; retry shortly | 75 |
|
|
485
493
|
| unclassified / non-`AkmError` (INTERNAL) | 70 |
|
|
486
494
|
|
|
495
|
+
`akm health` exits 4 when it reports a warning (`EXIT_CODES.HEALTH_WARN`).
|
|
496
|
+
|
|
487
497
|
---
|
|
488
498
|
|
|
489
499
|
## Connections and Harnesses
|
|
@@ -539,6 +549,11 @@ explicit `null`, zero, and empty values stay distinct. The result's
|
|
|
539
549
|
`provenance` names the layer behind each field (`akm task explain`,
|
|
540
550
|
`command run --dry-run`).
|
|
541
551
|
|
|
552
|
+
An agent asset is a persona (a system prompt), not executable work. An
|
|
553
|
+
`agents/<name>` selector (optionally `bundle//`-qualified) is resolved by akm
|
|
554
|
+
into a persona; any other agent string is a native harness selector that
|
|
555
|
+
replaces the persona.
|
|
556
|
+
|
|
542
557
|
`buildExecution` hands the request to the selected harness's own builder
|
|
543
558
|
(registered on `HARNESS_REGISTRY`), to the runtime's lowerer, or builds chat
|
|
544
559
|
messages for a direct request. A harness builder is a thin shell: it names the
|
|
@@ -582,32 +597,37 @@ which includes every earlier plan with a command step, is marked abandoned and
|
|
|
582
597
|
refused, naming the upgrade. AKM does not support full GitHub Actions semantics
|
|
583
598
|
or arbitrary remote action execution.
|
|
584
599
|
|
|
600
|
+
Tasks are `tasks/<name>.yml` documents in task source v4 (`parseTaskSource`).
|
|
601
|
+
Version 2 and 3 files are not read at runtime: they are refused with a message
|
|
602
|
+
naming `akm migrate apply`, which converts them. Historical task-run metadata
|
|
603
|
+
remains readable.
|
|
604
|
+
|
|
585
605
|
### In-tree LLM helpers (`src/llm/`)
|
|
586
606
|
|
|
587
607
|
Every helper under `src/llm/` is a **bounded, single-shot, stateless** call.
|
|
588
608
|
Concretely:
|
|
589
609
|
|
|
590
610
|
- Each public export is either a stateless function (`chatCompletion` performs
|
|
591
|
-
one HTTP request and keeps nothing between calls; `
|
|
592
|
-
`
|
|
593
|
-
|
|
611
|
+
one HTTP request and keeps nothing between calls; `resolveIndexPassExecution`,
|
|
612
|
+
`parseJsonResponse` in `src/core/parse.ts`, …) or a factory that returns a
|
|
613
|
+
one-shot client tied to the symbolic runner/config the caller passes in.
|
|
594
614
|
- No module under `src/llm/` keeps session, conversation, or response state at
|
|
595
|
-
module scope. The
|
|
596
|
-
|
|
597
|
-
stateless model handle
|
|
598
|
-
|
|
599
|
-
- `callStructured()` is the common bounded
|
|
600
|
-
already-resolved symbolic runner into an
|
|
601
|
-
and dispatches it through `runExecution`,
|
|
602
|
-
key at dispatch like every other dispatch
|
|
603
|
-
|
|
615
|
+
module scope. The module-level state is the local embedder pipeline and the
|
|
616
|
+
embedding cache in `src/llm/embedder.ts` — an expensive-to-build but
|
|
617
|
+
stateless model handle and an LRU of vectors. `resetLocalEmbedder()` lets
|
|
618
|
+
tests construct a fresh pipeline.
|
|
619
|
+
- `callStructured()` (`src/llm/structured-call.ts`) is the common bounded
|
|
620
|
+
structured-LLM seam: it adapts an already-resolved symbolic runner into an
|
|
621
|
+
inline resolved request, lowers it, and dispatches it through `runExecution`,
|
|
622
|
+
which materializes the connection's key at dispatch like every other dispatch
|
|
623
|
+
and re-runs no alias resolution. Index callers use
|
|
624
|
+
`resolveIndexPassExecution()` (`src/llm/index-passes.ts`) to freeze the typed
|
|
604
625
|
`{ runner, notices }` selection once per invocation; there is no separate
|
|
605
|
-
readiness projection. Which improve processes run is chosen
|
|
606
|
-
|
|
626
|
+
readiness projection. Which improve processes run is chosen by
|
|
627
|
+
`improve.strategies`, and where each runs by `improve.processes`; see
|
|
607
628
|
`docs/reference/configuration.md` for canonical config paths.
|
|
608
629
|
|
|
609
|
-
Review holds the seam
|
|
610
|
-
`src/llm/*` entry was deleted.
|
|
630
|
+
Review holds the seam.
|
|
611
631
|
|
|
612
632
|
### External agents (`src/integrations/agent/`, `src/integrations/harnesses/`)
|
|
613
633
|
|
|
@@ -628,8 +648,7 @@ Agent programs are reachable by two execution paths, both behind
|
|
|
628
648
|
([How akm runs a harness](../reference/configuration.md#how-akm-runs-a-harness)).
|
|
629
649
|
- The `AgentRunResult` envelope carries `{ ok, exitCode, stdout, stderr,
|
|
630
650
|
durationMs, reason?, error?, ... }` where `reason` is a typed code such as
|
|
631
|
-
`"timeout"`, `"spawn_failed"`, `"non_zero_exit"` or `"parse_error"`.
|
|
632
|
-
never see raw process errors.
|
|
651
|
+
`"timeout"`, `"spawn_failed"`, `"non_zero_exit"` or `"parse_error"`.
|
|
633
652
|
|
|
634
653
|
**akm's OpenCode runtime** (`src/integrations/harnesses/opencode/runtime/`):
|
|
635
654
|
|
|
@@ -687,17 +706,16 @@ Agent programs are reachable by two execution paths, both behind
|
|
|
687
706
|
(no binary and no registry to fetch it from) fails as `spawn_failed`, naming
|
|
688
707
|
the package, the URL and the cache path.
|
|
689
708
|
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
execution boundary. Historical task-run metadata remains readable.
|
|
709
|
+
---
|
|
710
|
+
|
|
711
|
+
## Locks
|
|
694
712
|
|
|
695
713
|
Long-lived mutable operations each take their own lock file, one `O_EXCL`
|
|
696
|
-
create (`src/core/file-lock.ts`): index writers, improve
|
|
697
|
-
locks, lockfile writers, the scheduler lock, and each
|
|
698
|
-
lock whose holder process is gone is reclaimed
|
|
699
|
-
|
|
700
|
-
`BEGIN IMMEDIATE`.
|
|
714
|
+
create (`src/core/file-lock.ts`, `src/core/run-lock.ts`): index writers, improve
|
|
715
|
+
and extract process locks, lockfile writers, the scheduler lock, and each
|
|
716
|
+
workflow run's lock. A lock whose holder process is gone is reclaimed; nothing
|
|
717
|
+
expires by age. There is no shared barrier or activity registry around them;
|
|
718
|
+
`state.db` writers serialize on SQLite's own `BEGIN IMMEDIATE`.
|
|
701
719
|
|
|
702
720
|
---
|
|
703
721
|
|
|
@@ -709,12 +727,13 @@ activity registry around them; `state.db` writers serialize on SQLite's own
|
|
|
709
727
|
| `src/cli/` | citty composition helpers |
|
|
710
728
|
| `src/core/asset/asset-placement.ts` | asset type registry and canonical source directories (`PLACEMENT_SPECS`) |
|
|
711
729
|
| `src/core/asset/asset-ref.ts` | asset ref parsing and normalization (`parseBundleRef`) |
|
|
730
|
+
| `src/core/adapter/` | the `BundleAdapter` contract and the built-in adapters (see [Adapters](adapters.md)) |
|
|
712
731
|
| `src/core/config/config.ts` | config loading, validation, env resolution; the default connection and harness |
|
|
713
732
|
| `src/core/config/credentials.ts` | `credentials.json` and the dispatch-time resolution of a connection's key (`$VAR`, else the stored entry) |
|
|
714
733
|
| `src/core/config/convert-engines.ts` | the one conversion of the older `engines` / `defaults` form to `connections` / `harnesses`, called by the loader and by `akm migrate apply` |
|
|
715
734
|
| `src/core/errors.ts` | error classes with stable codes and hints |
|
|
716
735
|
| `src/core/parse.ts` | shared JSON parsing: think/fence stripping, balanced-brace extraction |
|
|
717
|
-
| `src/core/concurrent.ts` | bounded concurrency pool (`concurrentMap`, default 1 worker) |
|
|
736
|
+
| `src/core/concurrent.ts` | bounded concurrency pool (`concurrentMap`, default 1 worker) and keyed serialization |
|
|
718
737
|
| `src/core/write-source.ts` | the single write helper (branches on `source.kind`) |
|
|
719
738
|
| `src/execution/resolved-request.ts` | the versioned resolved execution request and its canonical wire form (tolerant decode) |
|
|
720
739
|
| `src/integrations/agent/resolution.ts` | `resolveTarget`: the connection or harness a call runs on, and its model, timeout and request fields |
|
|
@@ -726,10 +745,11 @@ activity registry around them; `state.db` writers serialize on SQLite's own
|
|
|
726
745
|
| `src/sources/provider.ts` | minimal `SourceProvider` interface |
|
|
727
746
|
| `src/sources/providers/` | filesystem / git / website / npm implementations |
|
|
728
747
|
| `src/sources/resolve.ts` | filesystem path resolution for refs |
|
|
748
|
+
| `src/storage/repositories/` | SQL for `index.db`, `state.db`, and `logs.db` (entries, FTS, proposals, task history, workflow runs, …) |
|
|
729
749
|
| `src/indexer/indexer.ts` | walking, metadata generation, index rebuilds, embeddings, utility recompute |
|
|
730
750
|
| `src/indexer/walk/` | walker, matchers, path/file/index context — the walk phase |
|
|
731
751
|
| `src/indexer/db/` | `llm-cache` — the persistence phase (entries/embeddings persistence lives in `src/storage/repositories/`) |
|
|
732
|
-
| `src/indexer/search/` | `db-search`, ranking, search-fields, search-source, enrichers — the search phase |
|
|
752
|
+
| `src/indexer/search/` | `db-search`, `fts-query`, ranking, search-fields, search-source, enrichers — the search phase |
|
|
733
753
|
| `src/indexer/passes/` | memory-inference, dir-staleness, metadata — LLM/metadata passes |
|
|
734
754
|
| `src/indexer/usage/` | usage-events |
|
|
735
755
|
| `src/commands/read/search.ts` | `akm search` orchestration |
|
|
@@ -741,10 +761,10 @@ activity registry around them; `state.db` writers serialize on SQLite's own
|
|
|
741
761
|
| `src/commands/tasks/` | scheduled-task command surface |
|
|
742
762
|
| `src/commands/agent/` | contribute/agent command surface |
|
|
743
763
|
| `src/registry/providers/` | registry provider implementations (static-index, skills-sh) |
|
|
744
|
-
| `src/output/shapes/`, `src/output/text/` | JSON-envelope and text-output registries per command
|
|
764
|
+
| `src/output/shapes/`, `src/output/text/` | JSON-envelope and text-output registries per command — a parallel concern to `src/output/renderers.ts`'s per-asset-type `show` renderers, which register themselves when the module loads |
|
|
745
765
|
| `src/workflows/authoring/` | workflow authoring |
|
|
746
766
|
| `src/workflows/runtime/runs.ts` | workflow run persistence (raw SQL lives in `src/storage/repositories/workflow-runs-repository.ts`) |
|
|
747
|
-
| `src/workflows/runtime/` | run lifecycle: runs,
|
|
767
|
+
| `src/workflows/runtime/` | run lifecycle: runs, run-plan decoding, run outputs, agent-identity |
|
|
748
768
|
| `src/llm/client.ts` | OpenAI-compatible chat completions client (stateless, single request/response) |
|
|
749
769
|
| `src/llm/index-passes.ts` | per-pass connection or harness resolution for `akm index` (`index.*`) |
|
|
750
770
|
| `src/llm/memory-infer.ts` | atomic-fact split helper (runs where `improve.processes.memoryInference` or `index.memory` says) |
|