akm-cli 0.9.26-alpha.2 → 0.9.27-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 (39) hide show
  1. package/CHANGELOG.md +294 -0
  2. package/dist/assets/hints/cli-hints-full.md +16 -10
  3. package/dist/assets/hints/cli-hints-short.md +5 -5
  4. package/dist/assets/prompts/consolidate-system.md +2 -2
  5. package/dist/assets/prompts/extract-session.md +2 -2
  6. package/dist/assets/stash-skeleton/README.md +4 -3
  7. package/dist/commands/feedback-cli.js +244 -43
  8. package/dist/commands/improve/consolidate/pair-pass.js +1 -1
  9. package/dist/commands/improve/consolidate.js +14 -4
  10. package/dist/commands/improve/distill.js +70 -7
  11. package/dist/commands/improve/extract-prompt.js +61 -39
  12. package/dist/commands/improve/extract.js +2 -1
  13. package/dist/commands/improve/loop-stages.js +16 -1
  14. package/dist/commands/improve/memory/memory-belief.js +1 -1
  15. package/dist/commands/improve/preparation.js +46 -0
  16. package/dist/commands/improve/reflect.js +51 -8
  17. package/dist/commands/improve/retrieval-gate.js +1 -1
  18. package/dist/commands/improve/session-asset.js +3 -2
  19. package/dist/commands/improve/stage.js +1 -1
  20. package/dist/commands/proposal/repository.js +22 -6
  21. package/dist/core/asset/akm-markdown.js +40 -16
  22. package/dist/core/asset/frontmatter.js +67 -7
  23. package/dist/core/config/config-schema.js +1 -1
  24. package/dist/core/config/config.js +0 -4
  25. package/dist/core/config/schema/feedback.js +2 -19
  26. package/dist/indexer/indexer.js +35 -19
  27. package/dist/integrations/harnesses/codex/agent-builder.js +23 -15
  28. package/dist/llm/client.js +44 -14
  29. package/dist/llm/memory-infer.js +1 -1
  30. package/dist/scripts/akm-migrate-node.js +26 -22
  31. package/dist/scripts/akm-migrate.js +26 -22
  32. package/dist/storage/repositories/index-entry-schema.js +20 -4
  33. package/dist/storage/repositories/index-fts-repository.js +44 -3
  34. package/dist/storage/repositories/index-schema.js +14 -8
  35. package/docs/reference/cli.md +36 -17
  36. package/docs/reference/configuration.md +12 -6
  37. package/docs/reference/data-and-telemetry.md +3 -3
  38. package/package.json +1 -1
  39. package/schemas/akm-config.json +0 -14
package/CHANGELOG.md CHANGED
@@ -6,6 +6,300 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.9.27-alpha.1] - 2026-10-06
10
+
11
+ ### Fixed
12
+
13
+ - **A codex dispatch with an output schema no longer leaves a temp folder
14
+ behind.** Every build of the codex command for a request with a schema made a
15
+ new `akm-codex-schema-*` folder in the OS temp dir for `--output-schema` and
16
+ nothing ever removed it (the builder has no post-run hook, and the file is read
17
+ after it returns), so a machine whose `/tmp` is tmpfs held a folder in RAM per
18
+ dispatch until reboot. The schema is now written once to akm's cache dir, in a
19
+ file named by its hash: concurrent units dispatching the same schema share it,
20
+ a rewrite is an atomic rename of identical bytes, and the only residue is one
21
+ small file per distinct schema.
22
+ - **An index that has been updated ranks like a fresh index of the same files,
23
+ and `akm index --full` no longer doubles the full-text totals.** `entries_fts`
24
+ is contentless, and FTS5 cannot take a deleted row out of a contentless
25
+ table's BM25 totals (its row count, and the token counts the average document
26
+ length comes from). Every replaced or removed row left them one row too high:
27
+ 40 notes read 40, then 41 after one edit, then 81 after `--full`, and a delete
28
+ never lowered them, so scores drifted away from what a fresh index gives.
29
+ SQLite has no command that recomputes them (`delete` and `rebuild` are refused
30
+ on a contentless table), so a delete that removes a row now stamps
31
+ `index_meta.ftsTotalsStale` in its own transaction, whichever process made it,
32
+ and the next `akm index` rebuilds the table from `entries` before it finishes:
33
+ about a second at 25,000 entries, and only when rows have left the table. A
34
+ row the write-path index replaced after an accepted proposal is settled the
35
+ same way, and an index that has already drifted is corrected by the first run
36
+ that replaces or removes a row.
37
+ - **`akm improve` runs against an API that rejects `chat_template_kwargs`,
38
+ OpenAI's among them.** Improve's reflect, consolidate and judge calls always
39
+ ask for thinking off, and the client sends that as
40
+ `chat_template_kwargs.enable_thinking` and a top-level `enable_thinking`. A
41
+ strict API answers 400 `Unknown parameter: 'chat_template_kwargs'`, the retry
42
+ without the response schema sent both fields again, and `akm improve judge`
43
+ reported `judge timeout/error — routed to review`. No engine setting could
44
+ stop it: the call sites override the engine's `enableThinking`, and
45
+ `extraParams` can only add fields. A 4xx that names either field is now
46
+ answered by one retry without both (which may in turn fall back without the
47
+ schema), and akm stops sending them to that endpoint and model for the rest
48
+ of the process, as it already does for `response_format`.
49
+ - **A lesson the model wrote without a `when_to_use` is no longer thrown away
50
+ silently by `akm proposal extract`.** The extract schema left `when_to_use`
51
+ optional while the parser dropped a lesson without one (or with one under 15
52
+ characters) and said nothing, so a model that followed the schema could
53
+ write a sound lesson that akm discarded and the session reported no
54
+ candidates: on akm-eval's extract eval qwen3.8-27b kept 3 of 11 expected
55
+ insights against 9 for gpt-oss-120b. Every property of the schema is now
56
+ required, `when_to_use` and `rationale_if_empty` included, with an empty
57
+ string for none (a memory or knowledge candidate needs no trigger, a
58
+ non-empty answer no rationale), which is also what a strict structured-output
59
+ provider needs; the prompt's output contract says the same. Any candidate the
60
+ contract still refuses, for this reason or another, is named in its session's
61
+ `warnings` as `<type>:<name> dropped: <reason>`.
62
+ - **Distill's response schemas are valid for a strict structured-output
63
+ provider.** The client sends a response schema `strict: true`, and OpenAI
64
+ refuses one whose objects leave a property out of `required`: `400 Invalid
65
+ schema for response_format 'akm_response': ... Missing 'tags'`. The lesson
66
+ schema left out `tags`, and the knowledge schema `tags` and `sources`, so
67
+ the first distill request on such a provider always failed. After a 4xx the
68
+ client retries once without the schema, but a gateway that answers the same
69
+ rejection with a 502 is not retried, and every distill call through it
70
+ failed; the workaround, `supportsJsonSchema: false`, loses the guidance that
71
+ keeps a model from leaving out `when_to_use`. Every property is now
72
+ required, and an empty array stands for none (distill already dropped an
73
+ empty `tags` or `sources`).
74
+ - **`akm improve` no longer reflects on an asset whose file a proposal would not
75
+ write, so accepting a reflect proposal no longer adds a second file.** A
76
+ skill's `references/a.md` is indexed as `knowledge/skills/<name>/references/a`,
77
+ but a proposal writes the path derived from that ref,
78
+ `knowledge/skills/<name>/references/a.md`. Nothing is there, so the proposal
79
+ was a `create`, and accepting it wrote a copy beside the skill's own file;
80
+ later proposals then revised the copy while the skill's file drifted. Reflect
81
+ now refuses before it calls the model, naming the file and the path a
82
+ proposal would write, and the loop records it as a skip (`unsupported_type`,
83
+ `file_outside_layout` in the `reflect_completed` event). This is the rule
84
+ 0.9.26 added to `akm feedback --replace`. An asset that another bundle owns is
85
+ still refused by `createProposal` (#1000).
86
+ - **An index that 0.9.1 wrote no longer crashes akm.** Every `akm index` on it
87
+ exited 70 with `null is not an object (evaluating 'doc.xrefs')`, `akm migrate
88
+ apply` and `akm index --full` did not help, and `akm search` failed with
89
+ `null is not an object (evaluating 'item.entry.quality')`; the only way out
90
+ was moving `index.db` aside. That layout (20) keeps the transitional
91
+ `entry_key`, `dir_path`, `stash_dir`, `entry_json` and `entry_type` columns
92
+ that layout 21 removed, each NOT NULL, beside the current columns, and leaves
93
+ `document_json` NULL on every row. The table had every column akm checks for,
94
+ so it was taken for a current one: the links migration read the NULL
95
+ documents, and no insert could ever have succeeded (`NOT NULL constraint
96
+ failed: entries.entry_key`). akm now treats a table that still has a retired
97
+ column as older than layout 21, as the compat notes already said: the
98
+ writable opener recreates its entries-keyed tables (the LLM enrichment cache
99
+ is kept) and the next `akm index` re-walks every source, and a read rebuilds
100
+ inline. An index that a failed open already half-migrated (layout stamp still
101
+ 20, `search_text` dropped, `asset_links` created) recovers the same way.
102
+ - **Two files that claim one ref no longer trade places in the index, and `akm
103
+ index` says so.** A skill's `references/a.md` and a note at
104
+ `knowledge/skills/x/references/a.md` are both the ref
105
+ `knowledge/skills/x/references/a`, and the index holds one row for it. The
106
+ first file a run persisted held it, so a full build followed the filesystem's
107
+ listing order (one bundle indexed on tmpfs and on ext4 held different files),
108
+ and the first incremental run after a full build handed the row to the other
109
+ file, because it drains only the directory that lost: with no file touched,
110
+ the row, its search entry and the text its vector is embedded from changed,
111
+ and the vector was dropped and recomputed. When a smaller-path file was added
112
+ later and then deleted, the ref also left the index until `--full`, although
113
+ its other file was still on disk. The file with the smaller path (code-point
114
+ order, as `akm show`'s refusal lists them) now holds the ref however the
115
+ directories are drained and the walk is ordered, a directory that gives a ref
116
+ up is drained again so the ref passes back when its holder goes, and each
117
+ pair is reported in the `warnings` of `akm index`, naming the file indexed
118
+ and the one skipped.
119
+ - **Consolidate's plan schema and the session summary schema are valid for a
120
+ strict structured-output provider, and a new response schema can no longer
121
+ skip the rule.** The client sends a response schema `strict: true`, and
122
+ OpenAI refuses one whose objects leave a property out of `required`. The
123
+ consolidate plan left out `description` and `confidence`, and the session
124
+ summary `tags`, so the first request of every plan and every summary to such
125
+ a provider was refused. The client then retries without the schema and
126
+ remembers that per connection (endpoint and model), not per schema, so one
127
+ invalid schema also switched the response schema off for every valid one
128
+ that followed on that connection. Every property of both is now required: an
129
+ empty `description` keeps the memory's own, a null `confidence` records none
130
+ and an empty `tags` array is no tags, which is how all three were already
131
+ read. A contract test runs every schema akm sends through the rule, so a
132
+ property added later without being required fails CI.
133
+
134
+ ## [0.9.26] - 2026-10-05
135
+
136
+ The stable release of the 0.9.26 line: 0.9.26-alpha.1 and alpha.2, and the
137
+ changes in this section. When upgrading from 0.9.25:
138
+
139
+ - **Consolidate retires far fewer notes that hold something the kept note
140
+ lacks.** Its pair judge lists what each note alone holds and akm never
141
+ retires a note with anything listed; on 385 held-out pair proposals, 91% of
142
+ its retirements are safe, against 61% before. A duplicate that a second look
143
+ confirms is accepted by the triage drain (alpha.1).
144
+ - **Negative feedback can carry the fix:** `akm feedback --negative --replace
145
+ "<exact text>" --with "<corrected>" --source "<evidence>"` (alpha.2), and
146
+ `--outdated` or `--superseded-by <ref>` to mark a note's history. Either
147
+ becomes one `feedback` proposal for review.
148
+ - **Negative feedback is for wrong or stale content.** The hints and docs say
149
+ so; a note that did not fit the task records nothing. Each feedback event now
150
+ records the hash of the text it judged, and reflect marks feedback given on
151
+ an earlier version.
152
+ - **Distill no longer accepts a lesson unattended.** A lesson that passes its
153
+ judge waits for review instead of the drain, and distill skips a memory
154
+ flagged wrong since its last edit, one whose only feedback is a positive
155
+ without a reason, and a lesson that already exists.
156
+ - **Fixed:** a proposal no longer rewraps a note's frontmatter to add its
157
+ `type`, and accepting one stamps its provenance as lines of its own instead
158
+ of writing the frontmatter out again; a feedback fix for an asset outside the
159
+ bundle's layout is refused instead of queued at the wrong path.
160
+ - **Removed:** `akm feedback --failure-mode` and `feedback.allowedFailureModes`
161
+ (an old config still loads, naming the key once).
162
+
163
+ ### Added
164
+
165
+ - **`akm feedback --negative --superseded-by <ref>` and `--outdated` mark an
166
+ asset's history, in the same single `feedback` proposal as any `--replace`
167
+ edits.** `--superseded-by` (another asset replaces this one) sets
168
+ `beliefState: superseded` and adds the ref to `supersededBy`; akm resolves it
169
+ through the index first, and it must be indexed and not the asset itself, or
170
+ nothing is recorded. The rules are those of `akm remember --supersedes`: an
171
+ asset that already says so is left as it is, `contradicted` and `archived`
172
+ stay, and a scalar `supersededBy` becomes a list. `--outdated` (the asset
173
+ describes a past state and nothing replaces it) sets `beliefState:
174
+ deprecated`, unless the asset already says superseded, contradicted or
175
+ archived. Like every fix, both are for negative feedback and need `--reason`
176
+ and `--source`; they apply to markdown assets and are not used together. akm
177
+ edits only the `beliefState` and `supersededBy` lines of the text, so
178
+ comments, quoting, key order and line endings stay (it writes the frontmatter
179
+ out again only when a line edit cannot follow how a key is spelled), and `fix`
180
+ in the command's output and in the feedback event says what was set.
181
+
182
+ ### Changed
183
+
184
+ - **Each feedback event records the text it judged, and reflect marks feedback
185
+ given on an earlier version of it.** `akm feedback` adds `contentHash`, the
186
+ sha256 of the asset's body without its frontmatter as it stood when the
187
+ feedback was given, to the event and its usage row, for positive and negative
188
+ feedback. It is left out for an env or secret file, whose bytes akm never
189
+ reads, and when the file cannot be read. When reflect gathers an asset's
190
+ recent feedback, a line whose `contentHash` differs from the asset's current
191
+ body ends with ` (given on an earlier version of the text)`, so the model
192
+ knows the text changed since. A line without a `contentHash` (all feedback
193
+ recorded before this change) or with a matching one reads as before, and the
194
+ rest of the prompt is unchanged.
195
+ - **The shipped hints and docs say what negative feedback is for.** Record
196
+ `akm feedback --negative` only when an asset's content is wrong or stale, and
197
+ say what is wrong and what it should say. A note that simply did not fit the
198
+ task is not negative feedback: record nothing for it. Once the correct fact is
199
+ verified, attach the exact fix with `--replace`/`--with`/`--source`. Of the 195
200
+ negative reasons recorded in the last 30 days, 100 named no error in the note,
201
+ and 89 of those only said it did not fit the agent's task, which still lowered
202
+ the note's ranking and sent it to improve. The hints and the guides no longer
203
+ list "unhelpful" among the reasons to flag a note, and their example reasons
204
+ name a wrong fact instead of "wrong framework" or "incomplete-edge-cases". The
205
+ hints also say that an outdated note can be marked with `--outdated`, or
206
+ `--superseded-by <ref>` when another note replaces it.
207
+ - **Distill skips a memory that was flagged wrong and not edited since.** A
208
+ memory with negative feedback in the last 30 days on the text it still has is
209
+ no source for a lesson, so the improve loop skips distill for it: a
210
+ `distill-skipped` action with the reason "flagged wrong since its last edit"
211
+ and an `improve_skipped` event (`distill_flagged_wrong`). The attempt goes in
212
+ the improve ledger as `unchanged`, so the memory waits for newer feedback, and
213
+ reflect still plans it. Feedback records the hash of the body it judged
214
+ (`contentHash`), so a write that leaves the body alone, such as an inference
215
+ stamp or an accepted frontmatter repair, does not lift the flag; changing the
216
+ body does. Feedback recorded without a hash keeps the earlier test: it flags
217
+ the memory while it is newer than the file's last write (its modification
218
+ time, as in the retrieval scope's new-material test), so any later write ends
219
+ it. An explicit `akm improve <ref>` still distills it.
220
+ - **A distill proposal that passes the quality judge goes to review, not to the
221
+ drain.** The gate used to stamp a passing lesson (or knowledge promotion)
222
+ `staged`, and the triage drain accepted it on the next run with no one
223
+ looking. It is now minted `deferred` for a person: gate decision
224
+ `deferred`/`quality-gate` with the reason `distill-review`, carrying the
225
+ judge's per-criterion `scores` and `judgeReason`, so neither the drain nor its
226
+ judgment tier accepts it, and the improve ledger records `review_needed`. The
227
+ `distill_invoked` outcome is still `queued`. On 2026-10-05 the gate had
228
+ staged 12 lessons and 10 were bad (they restated the memory, claimed what it
229
+ does not say, or filed a dated status as a lesson); no judge score separated
230
+ them from the two good ones. A failed judgment behaves as before, and with
231
+ `processes.distill.qualityGate` off nothing is judged, so the proposal is
232
+ minted unstamped for the drain to decide.
233
+ - **Distill skips a memory whose only recent feedback is positive and says
234
+ nothing.** A bare `akm feedback --positive` records that a note helped, which
235
+ gives the writer nothing to distil, so it restated the memory: 10 of the 11
236
+ lessons made from a memory with only that kind of feedback were rejected (the
237
+ 11th was good). When every feedback event in the last 30 days that counts as a
238
+ signal is positive with no reason and no note, the improve loop skips distill
239
+ for the memory: a `distill-skipped` action with the reason "only positive
240
+ feedback, without a reason" and an `improve_skipped` event
241
+ (`distill_positive_without_reason`). The attempt goes in the improve ledger as
242
+ `unchanged`, so the memory waits for newer feedback. A reason, a note or a
243
+ negative signal anywhere in the window lets it through, and an explicit
244
+ `akm improve <ref>` still distills it. Record `--reason` with a positive
245
+ signal to say what helped.
246
+ - **Distill no longer regenerates a lesson that already exists.** A lesson's ref
247
+ comes from its memory's name (`memories/deploy` gives
248
+ `lessons/memory-deploy-lesson`), so a second distill of the same memory
249
+ proposed the same ref, and accepting it replaced the lesson. All 5 such
250
+ overwrites recorded by the 2026-10-05 review were rejected. When the stash
251
+ the proposal is filed in already holds a file at the lesson ref, distill now
252
+ returns `skipped` with the reason `lesson_exists` (in the result and the
253
+ `distill_invoked` event) before any model call, mints no proposal and leaves
254
+ the memory untouched, and the improve loop records it in the ledger as
255
+ `unchanged`. A lesson of that name in another bundle does not count, since
256
+ the proposal would not replace it. To change a lesson, edit it.
257
+
258
+ ### Removed
259
+
260
+ - **`akm feedback --failure-mode` and the `feedback.allowedFailureModes` config
261
+ key.** The flag labelled negative feedback `incorrect`, `outdated`,
262
+ `dangerous`, `incomplete` or `redundant`. None of the 195 negative feedback
263
+ events of the last 30 days set it, and nothing read it back. It now fails as an
264
+ unknown flag, and `akm feedback`'s output and the `improve_review_needed`
265
+ event no longer carry `failureMode`. A config that still sets
266
+ `feedback.allowedFailureModes` loads, names the key once as unknown, and
267
+ `akm migrate apply` drops it. Events recorded earlier keep their `failureMode`.
268
+
269
+ ### Fixed
270
+
271
+ - **`akm feedback --replace` no longer queues a fix that accepting would turn
272
+ into a duplicate file.** A proposal writes the path computed from the ref's
273
+ type and name under the bundle's root, which is not where an asset indexed
274
+ outside that layout lives (a git bundle's `tasks/README.md` is
275
+ `knowledge/tasks/README`; a skill's `references/symptom-map.md` is
276
+ `knowledge/skills/<name>/references/symptom-map`). Accepting such a proposal
277
+ created a second file and left the real one unfixed. akm now refuses before
278
+ recording anything, naming the file and the path the proposal would write, and
279
+ says to edit the file directly. Plain negative feedback on these assets is
280
+ unaffected.
281
+ - **A proposal no longer rewraps, reorders or strips a note's frontmatter to
282
+ add or correct its `type`.** When a proposal's content had no `type:` or a
283
+ different one, akm re-serialized the whole frontmatter block, so the reviewer
284
+ of a one-line correction also saw long values rewrapped, keys reordered and
285
+ YAML comments dropped. In practice 40 of 70 one-line correction proposals did
286
+ this. akm now adds a missing `type:` (and `updated:`) as a line before the
287
+ closing `---`, or replaces the existing `type:` line where it stands, and
288
+ leaves every other byte as written, line endings and body included. It
289
+ re-serializes only when it cannot do that safely, such as a `type` value that
290
+ spans several lines. The same write path serves `akm remember`, `akm import`
291
+ and `akm workflow create`, so a note akm writes without a `type` now carries
292
+ it, and `updated`, as its last frontmatter lines instead of its first.
293
+ Accepting a proposal also stamps its provenance (`generated`, `verified`,
294
+ `provenance`) as lines of its own, the last of the frontmatter, instead of
295
+ writing the whole frontmatter out again; a staging run found the old stamp
296
+ rewrapping 3 of 16 accepted edits. Accept still turns CRLF into LF, and still
297
+ writes the frontmatter out again when it carries bookkeeping keys such as
298
+ `inferenceProcessed` from the live note into a proposal that lacks them.
299
+ - **`akm lint --fix` keeps a CRLF note's line endings** when it adds a missing
300
+ `updated:`. It used to rewrite the whole file to LF, so one added line showed
301
+ as every line changed.
302
+
9
303
  ## [0.9.26-alpha.2] - 2026-10-05
10
304
 
11
305
  ### Added
@@ -95,23 +95,29 @@ akm workflow create ship-release # Create a workflow asset in the
95
95
  akm lint --type workflows # Parse and compile every .md/.yml workflow source; list every error
96
96
  akm workflow run workflows/ship-release # Start or resume and execute the workflow
97
97
  akm feedback skills/code-review --positive # Record that an asset helped (ranks it higher; no rewrite)
98
- akm feedback agents/reviewer --negative --reason "wrong framework" # Flag it: lowers its ranking; improve may repair its frontmatter
98
+ akm feedback agents/reviewer --negative --reason "says to run jest; the suite runs on vitest" # Content wrong or stale: lowers its ranking; improve may repair its frontmatter
99
99
  akm feedback knowledge/opencode-server --negative --reason "the default port is 4096, not 8000" --replace "port 8000" --with "port 4096" --source "https://opencode.ai/docs/server/" # Queue an exact fix
100
100
  akm feedback memories/deployment-notes --positive # Works for memories too
101
101
  akm feedback env/prod --positive # Records env feedback without surfacing values
102
102
  ```
103
103
 
104
- Use `akm feedback` whenever an asset's content materially helps, or proves wrong,
105
- stale or unhelpful, so future search ranking can learn from actual usage.
104
+ Use `akm feedback --positive` when an asset's content materially helps, so
105
+ future search ranking can learn from actual usage. Record negative feedback only
106
+ when the asset's content is wrong or stale, and say what is wrong and what it
107
+ should say.
106
108
  `akm feedback <ref> --negative --reason "<what is wrong and what should change>"`
107
109
  flags the asset: it ranks lower right away, and the next improve run may repair
108
- its description, title or `when_to_use` from your reason. Improve does not
109
- rewrite an asset's text: to correct a wrong fact there, attach the exact fix
110
- with `--replace "<exact current text>" --with "<corrected text>" --source "<URL,
111
- command or file>"`, which akm checks and queues as a proposal. `--positive` records that an asset helped (it raises its
112
- ranking) and does not trigger a rewrite; improve no longer rewrites assets from
113
- positive signals or on a proactive cadence. An akm command that fails says
114
- nothing about the asset; don't record it as feedback.
110
+ its description, title or `when_to_use` from your reason. A note that simply did
111
+ not fit your task is not negative feedback: record nothing for it. Improve does
112
+ not rewrite an asset's text: once you have verified the correct fact, attach the
113
+ exact fix with `--replace "<exact current text>" --with "<corrected text>"
114
+ --source "<URL, command or file>"`, which akm checks and queues as a proposal.
115
+ A note that is outdated can be marked with `--outdated`, or
116
+ `--superseded-by <ref>` when another note replaces it.
117
+ `--positive` records that an asset helped (it raises its ranking) and does not
118
+ trigger a rewrite; improve no longer rewrites assets from positive signals or on
119
+ a proactive cadence. An akm command that fails says nothing about the asset;
120
+ don't record it as feedback.
115
121
 
116
122
  ## LLM Wiki bundles
117
123
 
@@ -8,7 +8,7 @@ For any task, follow this loop:
8
8
  1. `akm curate "<task>"` — find the best matching asset
9
9
  2. `akm show <ref>` — read the schema (field names and structure)
10
10
  3. Edit the workspace file using schema field names + task-specific values from your README
11
- 4. `akm feedback <ref> --positive` — record that the asset helped (it raises its ranking and does not trigger a rewrite); when its content was wrong, stale or unhelpful, `akm feedback <ref> --negative --reason "<what is wrong and what should change>"` flags it: the next improve run may repair its description, title or `when_to_use` from your reason, but not its text. To correct a wrong fact in the text, add the exact fix: `--replace "<exact current text>" --with "<corrected text>" --source "<URL, command or file>"`. A failed akm command (e.g. `akm show` erroring) is not feedback on the asset — don't record it.
11
+ 4. `akm feedback <ref> --positive` — record that the asset helped (it raises its ranking and does not trigger a rewrite). Record negative feedback only when the asset's content is wrong or stale, and say what is wrong and what it should say. `akm feedback <ref> --negative --reason "<what is wrong and what should change>"` flags it: the next improve run may repair its description, title or `when_to_use` from your reason, but not its text. A note that simply did not fit your task is not negative feedback: record nothing for it. Once you have verified the correct fact, add the exact fix: `--replace "<exact current text>" --with "<corrected text>" --source "<URL, command or file>"`. A note that is outdated can be marked with `--outdated`, or `--superseded-by <ref>` when another note replaces it. A failed akm command (e.g. `akm show` erroring) is not feedback on the asset — don't record it.
12
12
 
13
13
  For workflow tasks:
14
14
  1. `akm show workflows/<name>` — inspect the procedure before executing it
@@ -40,7 +40,7 @@ akm proposal diff skills/akm-dream # Diff proposal by ref, UUID, or 8
40
40
  akm proposal accept 7c115132 # Accept by UUID prefix
41
41
  akm proposal reject skills/my-skill --reason "..." # Reject by ref
42
42
  akm feedback <ref> --positive # Record that an asset helped (ranks it higher; no rewrite)
43
- akm feedback <ref> --negative --reason "..." # Flag it: lowers its ranking; improve may repair its frontmatter
43
+ akm feedback <ref> --negative --reason "..." # Content wrong or stale: lowers its ranking; improve may repair its frontmatter
44
44
  akm feedback <ref> --negative --reason "..." --replace "<exact text>" --with "<fix>" --source "<url|cmd|file>" # Queue an exact fix of its text
45
45
  akm bundle add <ref> # Add a source (npm, GitHub, git, local dir)
46
46
  akm clone <ref> # Copy an asset to the working bundle (optional --dest arg to clone to specific location)
@@ -65,9 +65,9 @@ akm search "<query>" --from registry # Search all registries (registry
65
65
  | secret | A single sensitive value for AUTHENTICATION (token, key, cert); name only. Inject with `akm secret run <ref> <VAR> -- <cmd>`. |
66
66
  | lesson | A distilled feedback lesson: `content` plus `action` (rendered from the `when_to_use` frontmatter). Read both before applying a related skill. Generated by the improve pipeline and promoted through the proposal queue. |
67
67
 
68
- When an asset's content meaningfully helps, or proves wrong, stale or unhelpful,
69
- record that with `akm feedback` so future search ranking can learn from real
70
- usage. Only negative feedback with a specific reason gets the asset reviewed and
68
+ When an asset's content meaningfully helps, or proves wrong or stale, record
69
+ that with `akm feedback` so future search ranking can learn from real usage.
70
+ Only negative feedback with a specific reason gets the asset reviewed and
71
71
  fixed: improve no longer rewrites assets from positive signals or on a
72
72
  proactive cadence. An akm command that fails says nothing about the asset;
73
73
  don't record it as feedback.
@@ -7,10 +7,10 @@ Rules:
7
7
  Return ONLY JSON (no prose, no code fences):
8
8
  {
9
9
  "operations": [
10
- { "op": "promote", "ref": "memories/<name>", "knowledgeRef": "knowledge/<suggested-slug>", "reason": "<brief reason>", "description": "<one sentence describing the new knowledge asset>", "confidence": 0.92 }
10
+ { "op": "promote", "ref": "memories/<name>", "knowledgeRef": "knowledge/<suggested-slug>", "reason": "<brief reason>", "description": "<one sentence describing the new knowledge asset, or an empty string to keep the memory's own>", "confidence": 0.92 }
11
11
  ]
12
12
  }
13
13
 
14
- For every operation, emit a `confidence` field in [0, 1] expressing your certainty that the operation is correct and safe. Use 0.95+ only when evidence is unambiguous. Omit the field rather than guessing if you are uncertain.
14
+ For every operation, emit a `confidence` field in [0, 1] expressing your certainty that the operation is correct and safe. Use 0.95+ only when evidence is unambiguous. Use `null` rather than guessing if you are uncertain.
15
15
 
16
16
  When the merged content includes an `updated` frontmatter field, the value MUST be a real ISO date string (e.g. `updated: 2026-05-20`). NEVER emit `updated: today`, `updated: {today}`, `updated: {today: null}`, `updated: now`, or any other literal placeholder/template-variable. If you do not have a real source-of-truth date, OMIT the `updated` field entirely — the post-processor will not invent one for you.
@@ -48,13 +48,13 @@ Respond with EXACTLY one JSON object matching this shape:
48
48
  "type": "memory" | "lesson" | "knowledge",
49
49
  "name": "<kebab-case name, e.g. jwt-token; optionally under one kebab-case scope, e.g. auth/jwt-token>",
50
50
  "description": "<one sentence 20-400 chars>",
51
- "when_to_use": "<one sentence 15-400 chars; REQUIRED only when type=lesson>",
51
+ "when_to_use": "<one sentence 15-400 chars for a lesson; an empty string for a memory or knowledge candidate>",
52
52
  "body": "<markdown body, 200-3000 chars typical>",
53
53
  "confidence": <number 0.0-1.0>,
54
54
  "evidence": "<one-line pointer to the moment in the session>"
55
55
  }
56
56
  ],
57
- "rationale_if_empty": "<one sentence; REQUIRED when candidates is empty>"
57
+ "rationale_if_empty": "<one sentence when candidates is empty; an empty string otherwise>"
58
58
  }
59
59
  ```
60
60
 
@@ -80,11 +80,12 @@ akm search "<query>" --type skill
80
80
  # Mark an asset as helpful (raises its ranking; does not trigger a rewrite)
81
81
  akm feedback <ref> --positive
82
82
 
83
- # Flag an asset: it ranks lower, and the next improve run may repair its
84
- # description, title or when_to_use from your reason
83
+ # Flag an asset whose content is wrong or stale: it ranks lower, and the next
84
+ # improve run may repair its description, title or when_to_use from your reason.
85
+ # A note that simply did not fit your task gets no negative feedback.
85
86
  akm feedback <ref> --negative --reason "<what is wrong and what should change>"
86
87
 
87
- # Correct a wrong fact in an asset's text: the exact fix is checked and queued for review
88
+ # Once you have verified the correct fact, attach the exact fix: it is checked and queued for review
88
89
  akm feedback <ref> --negative --reason "<what is wrong>" --replace "<exact current text>" --with "<corrected text>" --source "<URL, command or file>"
89
90
 
90
91
  # Capture a durable lesson or memory from the current session