akm-cli 0.9.17-alpha.8 → 0.9.17-alpha.9
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 +334 -0
- package/STABILITY.md +9 -8
- package/dist/assets/hints/cli-hints-full.md +6 -7
- package/dist/assets/improve-strategies/catchup.json +0 -3
- package/dist/assets/improve-strategies/consolidate.json +0 -1
- package/dist/assets/improve-strategies/default.json +1 -2
- package/dist/assets/improve-strategies/proactive-maintenance.json +1 -2
- package/dist/assets/improve-strategies/quick.json +1 -2
- package/dist/assets/improve-strategies/reflect-distill.json +1 -2
- package/dist/assets/improve-strategies/thorough.json +0 -3
- package/dist/assets/prompts/consolidate-pair.md +20 -0
- package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +17 -19
- package/dist/assets/stash-skeleton/facts/conventions/domains.md +2 -2
- package/dist/assets/templates/html/health.html +3 -5
- package/dist/cli/retired-commands.js +1 -1
- package/dist/commands/health/archive-usage.js +98 -0
- package/dist/commands/health/data-dir-usage.js +25 -13
- package/dist/commands/health/html-report.js +1 -4
- package/dist/commands/health/improve-metrics.js +0 -25
- package/dist/commands/health/md-report.js +1 -6
- package/dist/commands/health/report-view-model.js +4 -14
- package/dist/commands/health/windows.js +0 -1
- package/dist/commands/health.js +13 -0
- package/dist/commands/improve/consolidate/continuity-check.js +137 -0
- package/dist/commands/improve/consolidate/pair-pass.js +791 -0
- package/dist/commands/improve/consolidate.js +38 -63
- package/dist/commands/improve/extract-prompt.js +1 -2
- package/dist/commands/improve/improve-cli.js +1 -1
- package/dist/commands/improve/improve-strategies.js +23 -5
- package/dist/commands/improve/improve.js +19 -30
- package/dist/commands/improve/ledger.js +3 -2
- package/dist/commands/improve/loop-stages.js +5 -85
- package/dist/commands/improve/memory/memory-belief.js +3 -1
- package/dist/commands/improve/memory/memory-improve.js +269 -11
- package/dist/commands/improve/planner.js +0 -5
- package/dist/commands/improve/preparation.js +20 -135
- package/dist/commands/improve/retrieval-scope.js +19 -4
- package/dist/commands/improve/salience.js +1 -14
- package/dist/commands/improve/stage.js +0 -1
- package/dist/commands/lint/base-linter.js +19 -11
- package/dist/commands/proposal/drain.js +8 -1
- package/dist/commands/proposal/proposal-cli.js +16 -2
- package/dist/commands/proposal/proposal-types.js +7 -0
- package/dist/commands/proposal/proposal.js +37 -6
- package/dist/commands/proposal/repository.js +613 -4
- package/dist/commands/proposal/validators/proposals.js +9 -0
- package/dist/commands/read/knowledge.js +3 -2
- package/dist/commands/read/show.js +0 -14
- package/dist/commands/sources/stash-cli.js +2 -2
- package/dist/core/bundle-rename.js +1 -7
- package/dist/core/config/config-schema.js +8 -1
- package/dist/core/config/config.js +23 -48
- package/dist/core/config/engine-semantics.js +0 -2
- package/dist/core/config/schema/improve-processes.js +17 -42
- package/dist/core/config/schema/index-config.js +5 -25
- package/dist/core/file-change.js +13 -5
- package/dist/core/improve-result.js +16 -5
- package/dist/core/improve-types.js +0 -1
- package/dist/core/loopback.js +7 -12
- package/dist/core/parse.js +13 -16
- package/dist/core/state/migrations.js +15 -0
- package/dist/core/time.js +0 -20
- package/dist/indexer/db/llm-cache.js +2 -2
- package/dist/indexer/ensure-index.js +2 -2
- package/dist/indexer/index-written-assets.js +2 -3
- package/dist/indexer/indexer.js +18 -418
- package/dist/indexer/passes/metadata.js +0 -19
- package/dist/indexer/walk/walker.js +3 -4
- package/dist/llm/client.js +8 -10
- package/dist/llm/embedders/remote.js +1 -2
- package/dist/llm/feature-gate.js +0 -5
- package/dist/output/shapes/helpers.js +20 -4
- package/dist/output/text/command-format.js +0 -8
- package/dist/output/text/proposal-format.js +47 -1
- package/dist/output/text/show-format.js +0 -20
- package/dist/scripts/akm-migrate-node.js +917 -950
- package/dist/scripts/akm-migrate.js +917 -950
- package/dist/setup/steps/connection.js +5 -6
- package/dist/setup/steps/platforms.js +2 -2
- package/dist/sources/providers/git-stash.js +55 -4
- package/dist/storage/repositories/improve-ledger-repository.js +48 -7
- package/dist/storage/repositories/index-entries-repository.js +4 -7
- package/dist/storage/repositories/index-entry-schema.js +4 -2
- package/dist/storage/repositories/index-llm-cache-repository.js +7 -26
- package/dist/storage/repositories/index-schema.js +55 -104
- package/dist/storage/repositories/proposals-repository.js +61 -0
- package/dist/storage/repositories/salience-repository.js +1 -19
- package/docs/reference/cli.md +16 -19
- package/docs/reference/configuration.md +21 -12
- package/docs/reference/data-and-telemetry.md +0 -1
- package/package.json +1 -1
- package/schemas/akm-config.json +0 -342
- package/dist/assets/improve-strategies/graph-refresh.json +0 -15
- package/dist/assets/prompts/contradiction-judge.md +0 -33
- package/dist/assets/prompts/graph-extract-system.md +0 -1
- package/dist/assets/prompts/graph-extract-user-prompt.md +0 -35
- package/dist/assets/prompts/metadata-enhance-system.md +0 -1
- package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +0 -4
- package/dist/indexer/db/graph-db.js +0 -399
- package/dist/indexer/graph/graph-extraction.js +0 -809
- package/dist/indexer/graph/graph-related.js +0 -131
- package/dist/indexer/graph/graph-types.js +0 -4
- package/dist/llm/graph-extract.js +0 -892
- package/dist/llm/metadata-enhance.js +0 -95
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,340 @@ 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.17-alpha.9] - 2026-09-29
|
|
10
|
+
|
|
11
|
+
`akm improve` now forgets, reversibly and under review. A consolidation pair
|
|
12
|
+
pass compares each new or changed memory, flat knowledge file or lesson with
|
|
13
|
+
its nearest neighbours; where an LLM judge calls a pair duplicate, subsumed or
|
|
14
|
+
superseding, it mints a retire proposal that a person reviews (`akm proposal
|
|
15
|
+
list --generator consolidate-pair`). Accepting one archives the older or
|
|
16
|
+
contained copy, and `akm proposal revert` restores it exactly; an accepted
|
|
17
|
+
promotion now retires its source memory, so promotion no longer leaves a
|
|
18
|
+
duplicate. A continuity check flags a retirement whose survivor does not rank
|
|
19
|
+
where the retired asset did for its own past searches, and a flagged proposal
|
|
20
|
+
is never bulk-accepted. Archived files are purged 30 days after retirement,
|
|
21
|
+
only when git holds them unmodified. The per-run forgetting-safety lane, LLM
|
|
22
|
+
metadata enrichment and LLM entity-graph extraction are removed: each measured
|
|
23
|
+
no benefit. Decide pending retire proposals before downgrading to
|
|
24
|
+
0.9.17-alpha.8.
|
|
25
|
+
|
|
26
|
+
### Added
|
|
27
|
+
|
|
28
|
+
- **Consolidate pair pass: duplicate, subsumed and superseding memories are
|
|
29
|
+
now retired, review-gated.** A second pass inside `akmConsolidate`,
|
|
30
|
+
alongside the existing promote pass. It walks memory-tier assets (a
|
|
31
|
+
memory, base or `.derived`; a flat `knowledge/` asset; or a lesson) in the
|
|
32
|
+
retrieval scope that are new to the pass or whose body has changed since
|
|
33
|
+
their last full attempt — tracked by content hash, not a time window, so
|
|
34
|
+
an initiator the nightly cap or a pending-proposal collision leaves out
|
|
35
|
+
stays eligible rather than being marked settled, and the pass's own
|
|
36
|
+
ledger rows are never retrieval-scope evidence for the other improve
|
|
37
|
+
lanes — takes each one's nearest neighbours by stored vector (fetching 20,
|
|
38
|
+
keeping the first 5 that clear every filter; same bundle, memory tier
|
|
39
|
+
only — structured knowledge in subfolders is excluded), and judges every
|
|
40
|
+
pair at cosine >= `T_pair` (0.93) with one LLM call using the calibrated
|
|
41
|
+
relation prompt (`src/assets/prompts/consolidate-pair.md`, six labels:
|
|
42
|
+
`duplicate`, `subsumed`, `supersedes`, `contradicts`, `overlap`,
|
|
43
|
+
`unrelated`). An initiator with no prior attempt is held to a higher
|
|
44
|
+
`T_pair` >= 0.95, unless it is new material (git first-added within the
|
|
45
|
+
last 7 days), which judges at the ordinary 0.93. "Older"/"newer" for the
|
|
46
|
+
judge's own A/B labelling comes from one `git log` per run over the
|
|
47
|
+
bundle (first-add time, following renames so a moved or renamed file
|
|
48
|
+
keeps its original date), not frontmatter or file mtime — mtime is only
|
|
49
|
+
the fallback for a file git does not know, or a bundle with no `.git` at
|
|
50
|
+
all. At most 300 pairs are judged a night, admitted a whole initiator at
|
|
51
|
+
a time rather than by flat cosine rank: new-or-changed initiators first,
|
|
52
|
+
then the existing backlog by its own best cosine, each admitted only if
|
|
53
|
+
every one of its candidate pairs fits in what remains of the 300 — so an
|
|
54
|
+
initiator blocked on another pending decision never spends a slot doing
|
|
55
|
+
nothing, and a smaller initiator further down still fits when a larger
|
|
56
|
+
one ahead of it does not. `duplicate`, `subsumed` and `supersedes` mint a
|
|
57
|
+
reviewed `retire` proposal for the losing side (owner-calibrated
|
|
58
|
+
precision 20/22 = 0.91 [0.72, 0.97] against a second-rater baseline of
|
|
59
|
+
0.17 for `supersedes` alone); `contradicts` is counted but stays a human
|
|
60
|
+
decision, and `overlap`/`unrelated` get no proposal. Guards: never a
|
|
61
|
+
`captureMode: hot` memory, never a `.derived` memory whose parent still
|
|
62
|
+
exists, never a pair where either side already has a pending retire
|
|
63
|
+
proposal (as the retired ref or its successor), and never retiring or
|
|
64
|
+
reusing as a successor an asset already spent earlier in the same run.
|
|
65
|
+
(`src/commands/improve/consolidate/pair-pass.ts`,
|
|
66
|
+
`src/commands/improve/retrieval-scope.ts`,
|
|
67
|
+
`src/storage/repositories/improve-ledger-repository.ts`,
|
|
68
|
+
`src/assets/prompts/consolidate-pair.md`)
|
|
69
|
+
- **Retire proposals.** A pair-pass retire proposal mints under its own
|
|
70
|
+
source, `consolidate-pair` — kept apart from the promote pass's
|
|
71
|
+
`consolidate` proposals, so a bulk `accept`/`reject --generator
|
|
72
|
+
consolidate` never sweeps a retirement, and the reverse; a bare `akm
|
|
73
|
+
proposal accept <ref>` never resolves to one either (it matches the
|
|
74
|
+
newest non-retire proposal for the ref, if any — a retire is reached by
|
|
75
|
+
its own proposal id, or the bulk `--generator consolidate-pair` form),
|
|
76
|
+
and retention expiry never drops a pending one for age alone. A pair the owner
|
|
77
|
+
rejected or reverted is not proposed again while both sides are unchanged. Its primary
|
|
78
|
+
change deletes its target instead of writing content. Accepting one first
|
|
79
|
+
confirms the decision is still fresh — the successor still exists, and
|
|
80
|
+
both sides' recorded body hashes still match their current files, not
|
|
81
|
+
just the retired side's, so a decision a later accept elsewhere made
|
|
82
|
+
stale (an A->B/B->C chain, or A->B/B->A both minted) is refused cleanly
|
|
83
|
+
rather than partially applied — then archives the asset (and its
|
|
84
|
+
`.derived` twin, if one exists) through a generalized
|
|
85
|
+
`archiveCleanupCandidate` (now usable on any memory, knowledge or lesson
|
|
86
|
+
file, not only `.derived` memories): the same
|
|
87
|
+
`.akm/memory-cleanup/archive/` encoding memory cleanup already used,
|
|
88
|
+
never the dead `.akm/archive/`. A `supersedes` judgement first writes the
|
|
89
|
+
`supersededBy` edge on the older asset, then archives it. Triage never
|
|
90
|
+
auto-accepts a retire proposal, whatever `applyMode` says — it waits for
|
|
91
|
+
a direct `akm proposal accept`, reviewed the same way as any other
|
|
92
|
+
proposal (`akm proposal list`, `show`, `diff`, bulk `accept --generator
|
|
93
|
+
consolidate-pair`; `--max-diff-lines` counts a retire by its target's own
|
|
94
|
+
line count). `accept` is crash-safe: it records its full intent —
|
|
95
|
+
`backupContent` and which file is about to move — durably before moving
|
|
96
|
+
anything, so a crash partway through, including between a primary and its
|
|
97
|
+
`.derived` twin, resumes and finishes from what was recorded rather than
|
|
98
|
+
leaving an asset stranded or the decision unrecorded. `revert` needs no
|
|
99
|
+
intent of its own — it resumes from what `accept` already recorded, and
|
|
100
|
+
refuses instead of overwriting a path that was reused by an unrelated file
|
|
101
|
+
since (its current content no longer matching what was retired). `revert`
|
|
102
|
+
restores the archived file(s) byte-for-byte from the bytes recorded at
|
|
103
|
+
accept, even a file that had no trailing newline — YAML comments, key
|
|
104
|
+
order and any human-written edge all survive the round trip. A ref to a retired asset keeps resolving to its tombstone
|
|
105
|
+
(`isArchivedRelPath`) — fixed along the way: that resolver assumed only
|
|
106
|
+
memories are ever archived, so an xref to a retired knowledge or lesson
|
|
107
|
+
asset was wrongly reported `missing-ref` by `akm lint` until now. Pending
|
|
108
|
+
retire proposals must be accepted or rejected before downgrading to
|
|
109
|
+
0.9.17-alpha.8 or earlier — that release predates the retire shape
|
|
110
|
+
entirely and exits 70 on one in `show`/`diff`/`drain`, and drain's own
|
|
111
|
+
nightly pre-pass failing on the first one it meets stops that run's
|
|
112
|
+
auto-promotion for the whole stash. Downgrading also revives the
|
|
113
|
+
new-material starvation this same branch fixed forward-only: 0.9.17-alpha.8
|
|
114
|
+
counts a pair-pass ledger row as retrieval-scope evidence again, so its own
|
|
115
|
+
nightly attempts crowd new material back out of every other improve lane —
|
|
116
|
+
measured, two nights left only 341 of 2,183 new-only assets still in scope
|
|
117
|
+
once read under alpha.8
|
|
118
|
+
(`docs/architecture/persisted-data-compat.md`).
|
|
119
|
+
(`src/commands/proposal/repository.ts`,
|
|
120
|
+
`src/commands/improve/memory/memory-improve.ts`,
|
|
121
|
+
`src/commands/lint/base-linter.ts`)
|
|
122
|
+
- **A promotion retires its source memory (O1).** When `akm proposal accept`
|
|
123
|
+
promotes a consolidate `promote` proposal — by a person or by triage
|
|
124
|
+
auto-promotion — it now archives the source memory (and its `.derived`
|
|
125
|
+
twin) through the same retire-archive path, tombstoned `reason: promoted`,
|
|
126
|
+
provided the source's body still matches the hash recorded when the
|
|
127
|
+
promotion was minted; an edit since then leaves the source alone (a
|
|
128
|
+
proposal minted before this hash existed is never archived, for the same
|
|
129
|
+
reason). A promotion no longer leaves a memory/knowledge duplicate behind.
|
|
130
|
+
Best-effort: a failure to archive the source only warns; the promotion
|
|
131
|
+
itself is not undone. (`src/commands/improve/consolidate.ts`,
|
|
132
|
+
`src/commands/proposal/repository.ts`)
|
|
133
|
+
- **Retirement continuity check (rule R3).** Before the pair pass mints a
|
|
134
|
+
`retire` proposal, it replays up to five of the retired asset's own past
|
|
135
|
+
`search`/`curate` queries through akm's own search, in-process — the
|
|
136
|
+
ranking a user actually gets, no LLM. For every query where the retired
|
|
137
|
+
asset ranked in the top 10, the successor must too; compared directly,
|
|
138
|
+
since search itself returns at most the top 10 hits. A failing
|
|
139
|
+
query never blocks the mint — the
|
|
140
|
+
proposal's `retirement.continuityRisk` records the failing query count
|
|
141
|
+
and, per failing query, the retired asset's rank and the successor's
|
|
142
|
+
(`null` when the successor did not rank in the top 10 at all). A proposal
|
|
143
|
+
carrying `continuityRisk` is excluded from every bulk accept path (`accept
|
|
144
|
+
--generator …`, with or without `--yes`) but not from bulk reject —
|
|
145
|
+
declining a flagged proposal is always the safe direction; a person can
|
|
146
|
+
always accept one by id. An asset with no recorded queries is not checked
|
|
147
|
+
at all. A query that never ran (the search call threw) or that fell back
|
|
148
|
+
to keyword-only ranking (an unreachable embedding endpoint, most often)
|
|
149
|
+
is never silently trusted or silently dropped either: it counts as
|
|
150
|
+
"unverified" and, on its own, is enough to flag `continuityRisk` — an
|
|
151
|
+
endpoint outage reads as "risk unknown," never as "no risk found," for
|
|
152
|
+
every proposal checked while it stays down, not just the first. The
|
|
153
|
+
first fallback in a pair-pass run forces every later query in that same
|
|
154
|
+
run to skip the semantic attempt entirely, so a dead endpoint costs one
|
|
155
|
+
failed attempt total, not one per remaining query. Two fixes against false
|
|
156
|
+
flags, measured on a real night-1 admission (300 pairs, 6 flags, 3
|
|
157
|
+
spurious): replayed queries are the same cleaned set the retrieval
|
|
158
|
+
regression gate uses (`loadRetrievalQueries`) — stash-README boilerplate,
|
|
159
|
+
harness/tool envelopes, pastes over 2,000 characters, and near-duplicate
|
|
160
|
+
queries (equal once whitespace is collapsed) are dropped before replay,
|
|
161
|
+
not just capped at five raw entries; and the check does not run at all
|
|
162
|
+
when the retired and successor bodies are content-identical once
|
|
163
|
+
whitespace is collapsed — search's own content-dedupe already hides the
|
|
164
|
+
successor behind the retired asset for every such query, so a "successor
|
|
165
|
+
missing" finding would not be a real risk.
|
|
166
|
+
(`src/commands/improve/consolidate/continuity-check.ts`,
|
|
167
|
+
`src/commands/proposal/proposal-types.ts`,
|
|
168
|
+
`src/commands/proposal/proposal.ts`)
|
|
169
|
+
- **Continuity-risk visibility, and a `--generator` filter for `proposal
|
|
170
|
+
list`.** A retire proposal carrying `retirement.continuityRisk` now
|
|
171
|
+
shows `⚠ continuity-risk` inline in the default `akm proposal list`
|
|
172
|
+
output (and `--format text`), not just in `proposal show`. `proposal
|
|
173
|
+
show`'s text output now lists the actual failing query text and rank per
|
|
174
|
+
query, not just a count, and separately reports `unverifiedQueries` when
|
|
175
|
+
the risk is (also, or only) an unverified query rather than a rank
|
|
176
|
+
failure. `akm proposal accept --generator … --dry-run` (and a real bulk
|
|
177
|
+
run) now reports `skippedForContinuityRisk`, the count of otherwise
|
|
178
|
+
matching proposals excluded specifically for this reason, apart from an
|
|
179
|
+
ordinary `--max-diff-lines`/`--older-than` miss. `akm proposal list` gains
|
|
180
|
+
a `--generator <name>` filter, the same value `accept`/`reject
|
|
181
|
+
--generator` already take, so the (potentially large) backlog of one
|
|
182
|
+
generator's retire proposals can be reviewed as its own list.
|
|
183
|
+
(`src/commands/proposal/proposal.ts`, `src/commands/proposal/proposal-cli.ts`,
|
|
184
|
+
`src/output/text/proposal-format.ts`, `src/output/shapes/helpers.ts`)
|
|
185
|
+
- **Archive purge sweep.** Deterministic, no LLM, run once at the very start
|
|
186
|
+
of every `akm improve` invocation, ahead of index bootstrap and triage.
|
|
187
|
+
For a git-backed bundle, deletes the archived asset file(s) of a
|
|
188
|
+
retirement — never its `cleanup.md` tombstone — once `retiredAt` is more
|
|
189
|
+
than 30 days old (`RETIRE_GRACE_DAYS`) AND every file under that
|
|
190
|
+
retirement's archive directory is git-tracked, clean (`git ls-files` plus
|
|
191
|
+
`git status --porcelain -uall`), and verifiable (`git ls-files -v`: a
|
|
192
|
+
file marked `assume-unchanged` or `skip-worktree` hides its own edits
|
|
193
|
+
from `git status`, so it is never trusted as clean either) — each checked
|
|
194
|
+
once per sweep; git history keeps the bytes. `.git` presence alone is not
|
|
195
|
+
enough: `proposal accept` only commits for a `kind: "git"` write target,
|
|
196
|
+
and improve's own auto-sync stages only the paths its own run wrote, so a
|
|
197
|
+
filesystem-kind bundle can carry archived retirements that were never
|
|
198
|
+
committed — the tracked/clean/verifiable check is what keeps the sweep
|
|
199
|
+
from deleting the only surviving copy of those. A directory with even one
|
|
200
|
+
untracked, modified, or unverifiable file (tombstone included) is left
|
|
201
|
+
whole for a later sweep — and so is the ENTIRE archive for that sweep if
|
|
202
|
+
the underlying `git status` or `git ls-files` call itself fails (a broken
|
|
203
|
+
submodule, for instance, can fail `git status` while `git ls-files`
|
|
204
|
+
still succeeds): an empty result from a failed check is never treated as
|
|
205
|
+
"nothing to protect", and the sweep warns once rather than silently
|
|
206
|
+
purging nothing. A memory-cleanup family-prune archive carries no
|
|
207
|
+
`retiredAt`, so this sweep never touches that older archive class. Every
|
|
208
|
+
deleted file is journaled individually, so the end-of-run auto-sync
|
|
209
|
+
commits the removal the same way it commits the archive move itself.
|
|
210
|
+
(`src/commands/improve/memory/memory-improve.ts`,
|
|
211
|
+
`src/sources/providers/git-stash.ts`, `src/commands/improve/improve.ts`)
|
|
212
|
+
- **`akm health`'s `memory-cleanup-archive` advisory now covers every
|
|
213
|
+
bundle**, not just one with no `.git` at all. A bundle with no `.git` of
|
|
214
|
+
its own keeps every retirement's archived bytes forever (there is no
|
|
215
|
+
history to fall back on, so the purge sweep never runs there), and its
|
|
216
|
+
size and file count are reported as before. A git-backed bundle can ALSO
|
|
217
|
+
carry archived bytes the purge sweep will never remove — `.git` presence
|
|
218
|
+
alone never proved a retirement was committed — so this now runs the same
|
|
219
|
+
tracked/clean/verifiable check the purge sweep itself uses and reports
|
|
220
|
+
how many files and bytes of the archive cannot currently be purged
|
|
221
|
+
(untracked, modified, or unverifiable), alongside the total. Silent
|
|
222
|
+
whenever there is nothing to say: the archive is empty or absent, or (for
|
|
223
|
+
a git-backed bundle) every byte in it is purgeable once it ages out.
|
|
224
|
+
(`src/commands/health/archive-usage.ts`, `src/commands/health/data-dir-usage.ts`)
|
|
225
|
+
|
|
226
|
+
### Removed
|
|
227
|
+
|
|
228
|
+
- **LLM metadata enrichment (`index.metadataEnhance`) is retired.** On 49
|
|
229
|
+
stratified queries, with every eligible candidate enriched (1,968
|
|
230
|
+
entries): search nDCG@10 moved −0.0092 [−0.0324, +0.0165], curate P@5
|
|
231
|
+
+0.000 [−0.037, +0.045], and long prompts lost −0.054 [−0.093, −0.012]. A
|
|
232
|
+
Doc2Query-- filter made it worse (P@5 −0.020 [−0.045, −0.004]). The pass
|
|
233
|
+
replaced authored descriptions on 89% of the entries it rewrote, and a
|
|
234
|
+
full pass costs about 27 B70-hours (RS-D, owner ruling 2026-09-28). It was
|
|
235
|
+
already off by default and off in the maintainer's config. The LLM call
|
|
236
|
+
(`src/llm/metadata-enhance.ts`), its `akm index` dispatch, and the
|
|
237
|
+
`metadata_enhance` feature-gate key are gone; the deterministic metadata
|
|
238
|
+
pass, `quality: "generated"`, and memory inference are unaffected. A
|
|
239
|
+
config that still sets `index.metadataEnhance` loads, named once by the
|
|
240
|
+
same unknown-config-key path every other retired key uses: kept in
|
|
241
|
+
memory, round-trips through ordinary writes, and is dropped only by
|
|
242
|
+
`akm migrate apply`. The pass's `llm_enrichment_cache` rows (the default
|
|
243
|
+
`cache_variant`; graph and memory inference use their own named variants)
|
|
244
|
+
are deleted on the next writable open of `index.db`. An index built while
|
|
245
|
+
enrichment was on keeps its entries' LLM-written descriptions on
|
|
246
|
+
incremental runs — nothing rewrites an unchanged row; run
|
|
247
|
+
`akm index --full` once to replace them with the deterministic ones.
|
|
248
|
+
(`src/indexer/indexer.ts`, `src/llm/feature-gate.ts`,
|
|
249
|
+
`src/core/config/config.ts`, `src/core/config/schema/index-config.ts`,
|
|
250
|
+
`src/storage/repositories/index-schema.ts`)
|
|
251
|
+
- **The LLM entity-graph extraction pass.** `akm improve`'s per-file
|
|
252
|
+
entity/relation extraction, its persisted tables (`graph_meta`,
|
|
253
|
+
`graph_files`, `graph_file_entities`, `graph_file_relations`), and `akm
|
|
254
|
+
show`'s `related` list are gone. On the navigation eval, vector kNN beat
|
|
255
|
+
the LLM `related` list by 0.157 P@5 [0.051, 0.260]; the ranking boost it
|
|
256
|
+
once fed was already removed in 0.9.17-alpha.4. Declared links (#935,
|
|
257
|
+
alpha.8) are the only navigation surface `akm show` has now, and curate's
|
|
258
|
+
support refs already came from them, not the graph. index.db is a
|
|
259
|
+
regenerable cache, so the graph tables are dropped unconditionally on the
|
|
260
|
+
next writable open — nothing migrates or backs them up.
|
|
261
|
+
- **The `graph-refresh` improve strategy** and the `akm-graph-refresh-weekly`
|
|
262
|
+
task template are deleted. Naming `graph-refresh` via `--strategy` or a task
|
|
263
|
+
now fails with a message naming the retirement, unconditionally — even when
|
|
264
|
+
`improve.strategies["graph-refresh"]` still has a leftover override block
|
|
265
|
+
from customizing the built-in (the message names it; `akm migrate apply`
|
|
266
|
+
drops it). `defaults.improveStrategy: "graph-refresh"` still loads config
|
|
267
|
+
successfully — the refusal happens lazily, when the strategy is actually
|
|
268
|
+
resolved, not at every command's config load.
|
|
269
|
+
- **Retired config keys:** `index.graph.*` and every strategy's
|
|
270
|
+
`processes.graphExtraction.*`. An old config that still sets them keeps
|
|
271
|
+
loading and the keys are unread, but `index.graph` is now also named once
|
|
272
|
+
by the unknown-config-key warning (it previously validated silently
|
|
273
|
+
against the generic per-pass catchall) and, like any other retired key,
|
|
274
|
+
is dropped only by `akm migrate apply` — not by an ordinary config write.
|
|
275
|
+
- **`akm health` drops every graph metric** — the KPI card, summary-table
|
|
276
|
+
rows, per-run duration/entity/relation columns, and the
|
|
277
|
+
`improve.graphExtraction.failures` window-compare delta. `--window-compare`
|
|
278
|
+
and `--group-by run` still count every run, including a pre-alpha.9 one:
|
|
279
|
+
its stored `graphExtraction`/`graphExtractionDurationMs` result fields and
|
|
280
|
+
its `graph-extraction` `plan.stages` / `graphExtraction` `plan.processes`
|
|
281
|
+
entries still decode, read-only, same as any other retired field (AGENTS.md
|
|
282
|
+
"Reading persisted data") — they are just no longer rendered. The
|
|
283
|
+
`improve_completed` event's `graphExtractionExtractedFiles`,
|
|
284
|
+
`graphExtractionDurationMs`, `graphCoverage`, `graphDensity`, and
|
|
285
|
+
`graphEntities` metadata fields are no longer emitted.
|
|
286
|
+
- **The per-run forgetting-safety lane.** `scoreSalience`'s stash-wide
|
|
287
|
+
salience-rank comparison, `applyForgettingSafety`, and the
|
|
288
|
+
`improve_salience_rank_change` event are gone. It was a one-time WS-1
|
|
289
|
+
cutover guard from the June 2026 ranking-formula change that had kept
|
|
290
|
+
running on every improve run since; the last 30 days of events
|
|
291
|
+
(2026-08-30 to 2026-09-29: 47 `improve_salience_rank_change` events, 5
|
|
292
|
+
refs flagged across 4 runs — 09-05, 09-08 x2, 09-19, 09-28) showed no
|
|
293
|
+
marginal pick over the signal-delta lane and the retrieval scope: 4 of
|
|
294
|
+
the 5 flagged refs were also picked that same run by signal-delta
|
|
295
|
+
(adjacent event ids/timestamps, 2–26 minutes after the rank-change
|
|
296
|
+
event), and the 5th (`workflows/create-github-issues-from-spec`, flagged
|
|
297
|
+
09-05) has no `reflect_invoked` or `distill_invoked` event in the
|
|
298
|
+
retained history, but that run's `improve_runs.plannedRefs` shows it,
|
|
299
|
+
too, was planned under `signal-delta` — just not reflected (a
|
|
300
|
+
dispatch/budget limit that run, not a lane-exclusive pick). All 5
|
|
301
|
+
flagged refs were signal-delta picks; zero were forgetting-safety-only.
|
|
302
|
+
It also protected
|
|
303
|
+
`asset_salience.rank_score`, which only improve itself ever read — a rank
|
|
304
|
+
drop could not hide anything from search. `buildRankChangeReport` (its
|
|
305
|
+
comparator) is also gone: the new retirement continuity check (see
|
|
306
|
+
Added) compares ranks directly instead, and nothing else called it.
|
|
307
|
+
`forgetting-safety` stays a valid `eligibilitySource`/event-type
|
|
308
|
+
value so old proposals and events still decode, but nothing assigns or
|
|
309
|
+
emits it any more. (`src/commands/improve/preparation.ts`,
|
|
310
|
+
`src/commands/improve/salience.ts`, `src/core/events.ts`,
|
|
311
|
+
`src/storage/repositories/salience-repository.ts`)
|
|
312
|
+
- **`improve.strategies.<name>.processes.consolidate.incrementalSince` and
|
|
313
|
+
`.neighborsPerChanged`.** The consolidate pair pass is now the candidate
|
|
314
|
+
generator, narrowing per initiator through the improve ledger rather than
|
|
315
|
+
a global time window; neither key was set anywhere in the owner's config.
|
|
316
|
+
`narrowToIncrementalCandidates` goes with them, along with its
|
|
317
|
+
now-orphaned `parseSinceToIsoLenient` helper. A config that still sets
|
|
318
|
+
either key keeps loading under the retired-key contract: named once as
|
|
319
|
+
unknown, it survives an ordinary config write, and only `akm migrate
|
|
320
|
+
apply` drops it. (`src/core/config/schema/improve-processes.ts`,
|
|
321
|
+
`src/commands/improve/consolidate.ts`, `src/core/time.ts`,
|
|
322
|
+
`docs/reference/configuration.md`)
|
|
323
|
+
|
|
324
|
+
### Fixed
|
|
325
|
+
|
|
326
|
+
- **Stale "advisory merge/delete/contradict" documentation.** Consolidation
|
|
327
|
+
stopped executing its merge/delete/contradict operations at `e82eec811`
|
|
328
|
+
(2026-07, #732; they had run in production until then, not "never
|
|
329
|
+
executed" as a couple of doc comments and `improve-workflow.md` claimed),
|
|
330
|
+
and 0.9.17-alpha.1 (`f4ebd763a`) dropped them from the prompt and schema,
|
|
331
|
+
which have offered `promote` only since. But `docs/architecture/
|
|
332
|
+
improvement.md`, `STABILITY.md` and `docs/architecture/internals/
|
|
333
|
+
improve-workflow.md` still described them as advisory planned output.
|
|
334
|
+
Corrected, and `improve-workflow.md` gains a section documenting the pair
|
|
335
|
+
pass, retire proposals and O1. Also corrected: the `default` strategy's
|
|
336
|
+
"advisory consolidation" description, two comments that still credited a
|
|
337
|
+
`beliefState` ranking boost alpha.4 removed (`memory-belief.ts`,
|
|
338
|
+
`knowledge.ts`), and D27's stale `archiveMemory` naming in the
|
|
339
|
+
architecture decision history. Deleted the unused
|
|
340
|
+
`src/assets/prompts/contradiction-judge.md` (no reader since
|
|
341
|
+
`e82eec811`).
|
|
342
|
+
|
|
9
343
|
## [0.9.17-alpha.8] - 2026-09-28
|
|
10
344
|
|
|
11
345
|
`akm index` now records the links a bundle already declares (`xrefs`,
|
package/STABILITY.md
CHANGED
|
@@ -366,8 +366,8 @@ for scripted use.
|
|
|
366
366
|
### `akm improve` autonomy — opt-in in 0.9.0
|
|
367
367
|
|
|
368
368
|
**`akm improve` is review-first by default in 0.9.0.** The command itself is ON
|
|
369
|
-
— its schedules
|
|
370
|
-
|
|
369
|
+
— its schedules and reflect/distill proposals all run — but the lanes that
|
|
370
|
+
mutate assets *without* review require an explicit opt-in:
|
|
371
371
|
|
|
372
372
|
```sh
|
|
373
373
|
akm config set experimental.improveAutonomy true
|
|
@@ -388,9 +388,10 @@ review-first config correctly shows `queue`.
|
|
|
388
388
|
| memory cleanup | Belief-state frontmatter rewrites, archive moves | analyzed but not applied |
|
|
389
389
|
| `triage` `applyMode: "promote"` | Auto-accepts queued proposals into the bundle | downgraded to `queue` — triage still runs, it just does not auto-accept |
|
|
390
390
|
|
|
391
|
-
Consolidation remains enabled with autonomy off
|
|
392
|
-
|
|
393
|
-
proposal
|
|
391
|
+
Consolidation remains enabled with autonomy off: both its passes (promotion,
|
|
392
|
+
and the pair pass's duplicate/subsumed/supersedes judging) only ever emit a
|
|
393
|
+
reviewable proposal, and a pair-pass `retire` proposal is never auto-accepted
|
|
394
|
+
by `triage` `applyMode: "promote"` regardless of this gate.
|
|
394
395
|
|
|
395
396
|
Because the gate is applied before the LLM preflight, a review-first workspace
|
|
396
397
|
also needs fewer engines configured: a strategy whose only model-backed process
|
|
@@ -409,9 +410,9 @@ Autonomy is never inferred: an absent `experimental` section, an absent key, and
|
|
|
409
410
|
an explicit `false` all read as off, so a partially-written or older config is
|
|
410
411
|
review-first rather than accidentally permissive.
|
|
411
412
|
|
|
412
|
-
Reflect, distill, extract candidates, validation, proactive-maintenance
|
|
413
|
-
selection
|
|
414
|
-
|
|
413
|
+
Reflect, distill, extract candidates, validation, and proactive-maintenance
|
|
414
|
+
selection are proposal-only and never write assets directly. Two further
|
|
415
|
+
direct writes are ungated by design: `extract`'s session
|
|
415
416
|
indexing (additive `sessions/**` writes,
|
|
416
417
|
`processes.extract.indexSessions`, default on) and distill's
|
|
417
418
|
encoding-salience frontmatter stamp (metadata only).
|
|
@@ -245,10 +245,9 @@ akm improve --no-push # commit but skip push for this ru
|
|
|
245
245
|
akm improve --sync # force sync even on strategies that disable it
|
|
246
246
|
```
|
|
247
247
|
|
|
248
|
-
Strategy sync defaults: `catchup`, `consolidate`, `default`,
|
|
249
|
-
`
|
|
250
|
-
|
|
251
|
-
with `--sync` / `--no-sync` flags.
|
|
248
|
+
Strategy sync defaults: `catchup`, `consolidate`, `default`, `quick`, and
|
|
249
|
+
`thorough` auto-commit + push; `proactive-maintenance` and `reflect-distill`
|
|
250
|
+
skip sync entirely. Override with `--sync` / `--no-sync` flags.
|
|
252
251
|
|
|
253
252
|
The `--writable` flag on `akm bundle add` opts a remote git bundle into push-on-sync:
|
|
254
253
|
|
|
@@ -308,8 +307,8 @@ akm bundle create # Initialize working bund
|
|
|
308
307
|
akm setup # Interactive wizard: bundle + LLM/embedding + agent + registry config
|
|
309
308
|
akm setup --dir ~/custom-bundle # Run the wizard against a custom bundle path
|
|
310
309
|
akm setup --yes # Non-interactive, accepts all defaults
|
|
311
|
-
akm index # Rebuild search index
|
|
312
|
-
akm index --full # Full reindex
|
|
310
|
+
akm index # Rebuild search index
|
|
311
|
+
akm index --full # Full reindex
|
|
313
312
|
akm bundle list # List all sources
|
|
314
313
|
akm lint # Structural lint over the bundle; exits 0 regardless of findings
|
|
315
314
|
akm lint --fix # Auto-fix Tier 1 issues
|
|
@@ -399,7 +398,7 @@ akm agent --model sonnet --prompt "..." # Model override (aliases or exa
|
|
|
399
398
|
```sh
|
|
400
399
|
akm info # Capabilities, bundle dir, index stats, semantic-search status
|
|
401
400
|
akm health # Runtime diagnostics; exit 0 ok / 4 warn / 1 fail
|
|
402
|
-
akm health --report # Adds accept-rate
|
|
401
|
+
akm health --report # Adds accept-rate metrics
|
|
403
402
|
akm log # Append-only event stream (mutations, feedback, indexing)
|
|
404
403
|
akm log --ref <ref> # One asset's event trail
|
|
405
404
|
akm log --since @offset:<id> # Durable row-id cursor — poll this to follow the stream
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
"distill": { "enabled": false },
|
|
6
6
|
"consolidate": { "enabled": true, "allowedTypes": ["memory"], "maxChunkSize": 25 },
|
|
7
7
|
"memoryInference": { "enabled": false },
|
|
8
|
-
"graphExtraction": { "enabled": false },
|
|
9
8
|
"extract": { "enabled": false },
|
|
10
9
|
"triage": { "enabled": false },
|
|
11
10
|
"validation": { "enabled": false },
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"description": "Standard improve pass — reflect, distill,
|
|
2
|
+
"description": "Standard improve pass — reflect, distill, consolidation (promotion plus the reviewed pair-pass retire/supersede proposals), and validation. Memory inference is listed below but only runs when experimental.improveAutonomy is set; improve-stage extract and proactive maintenance off.",
|
|
3
3
|
"processes": {
|
|
4
4
|
"reflect": {
|
|
5
5
|
"enabled": true,
|
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
"distill": { "enabled": true, "allowedTypes": ["memory"], "requirePlannedRefs": true },
|
|
10
10
|
"consolidate": { "enabled": true, "allowedTypes": ["memory"] },
|
|
11
11
|
"memoryInference": { "enabled": true },
|
|
12
|
-
"graphExtraction": { "enabled": true },
|
|
13
12
|
"extract": { "enabled": false, "triage": { "enabled": true, "minScore": 2 } },
|
|
14
13
|
"validation": { "enabled": true },
|
|
15
14
|
"proactiveMaintenance": { "enabled": false, "dueDays": 30, "maxPerRun": 15 },
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"description": "Opt-in proactive-maintenance pass — reflect, distill, proposal triage (promote, high budget), and the proactive-maintenance lane (maxPerRun 100); consolidate/memoryInference/
|
|
2
|
+
"description": "Opt-in proactive-maintenance pass — reflect, distill, proposal triage (promote, high budget), and the proactive-maintenance lane (maxPerRun 100); consolidate/memoryInference/extract off. Sync disabled: an interrupted run would otherwise leave an uncommitted backlog.",
|
|
3
3
|
"processes": {
|
|
4
4
|
"reflect": {
|
|
5
5
|
"enabled": true,
|
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
"distill": { "enabled": true, "allowedTypes": ["memory"] },
|
|
9
9
|
"consolidate": { "enabled": false },
|
|
10
10
|
"memoryInference": { "enabled": false },
|
|
11
|
-
"graphExtraction": { "enabled": false },
|
|
12
11
|
"extract": { "enabled": false },
|
|
13
12
|
"validation": { "enabled": false },
|
|
14
13
|
"triage": {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"description": "Reflect-only pass — no extract, distill, consolidate,
|
|
2
|
+
"description": "Reflect-only pass — no extract, distill, consolidate, or memoryInference.",
|
|
3
3
|
"processes": {
|
|
4
4
|
"reflect": {
|
|
5
5
|
"enabled": true,
|
|
@@ -9,7 +9,6 @@
|
|
|
9
9
|
"distill": { "enabled": false },
|
|
10
10
|
"consolidate": { "enabled": false },
|
|
11
11
|
"memoryInference": { "enabled": false },
|
|
12
|
-
"graphExtraction": { "enabled": false },
|
|
13
12
|
"triage": { "enabled": false },
|
|
14
13
|
"validation": { "enabled": false },
|
|
15
14
|
"proactiveMaintenance": { "enabled": false }
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"description": "Reflect + distill pass — reflect, distill, memoryInference, and proposal triage (promote); proactiveMaintenance/consolidate/
|
|
2
|
+
"description": "Reflect + distill pass — reflect, distill, memoryInference, and proposal triage (promote); proactiveMaintenance/consolidate/extract off. Sync disabled: an interrupted run would otherwise leave an uncommitted backlog.",
|
|
3
3
|
"processes": {
|
|
4
4
|
"reflect": {
|
|
5
5
|
"enabled": true,
|
|
@@ -8,7 +8,6 @@
|
|
|
8
8
|
"distill": { "enabled": true, "allowedTypes": ["memory"], "requirePlannedRefs": false },
|
|
9
9
|
"consolidate": { "enabled": false },
|
|
10
10
|
"memoryInference": { "enabled": true },
|
|
11
|
-
"graphExtraction": { "enabled": false },
|
|
12
11
|
"extract": {
|
|
13
12
|
"enabled": false,
|
|
14
13
|
"timeoutMs": 300000,
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
You compare two assets from one person's agent-memory library (memories and knowledge notes an AI coding agent reads). Asset A is the OLDER one and asset B the NEWER one, by the dates shown.
|
|
2
|
+
|
|
3
|
+
Classify the relation between them as exactly one of:
|
|
4
|
+
|
|
5
|
+
- "duplicate": they state the same durable facts. Wording, title or formatting may differ, but neither adds a claim a reader would need that the other lacks.
|
|
6
|
+
- "subsumed": one of them contains every durable claim of the other, plus more. The smaller one is redundant.
|
|
7
|
+
- "supersedes": B updates, corrects, reverses or replaces a claim in A (a newer version, a changed decision, a fixed bug, a new value). A is now stale or wrong on that point.
|
|
8
|
+
- "contradicts": they make logically exclusive claims about the same thing and nothing shows which one is current.
|
|
9
|
+
- "overlap": same subject, but each has durable claims the other lacks. Keeping both loses nothing; merging them would keep both sets of claims.
|
|
10
|
+
- "unrelated": different subjects or different facts that happen to share words.
|
|
11
|
+
|
|
12
|
+
Rules:
|
|
13
|
+
- A durable claim is a fact, decision, value, command, path, number or rule someone would act on. Ignore dates, headings, tags and phrasing.
|
|
14
|
+
- Prefer "overlap" over "duplicate" when either asset has a specific detail (a number, command, file, version or condition) that the other lacks.
|
|
15
|
+
- "supersedes" needs a specific claim in A that B changes. Being newer or longer is not enough.
|
|
16
|
+
- "contradicts" needs two claims that cannot both be true. Different scope, project or time is not a contradiction.
|
|
17
|
+
|
|
18
|
+
Set "redundant" to "A" or "B" when that asset could be removed with no loss (only for "duplicate" or "subsumed"; for "duplicate" name the less complete or older one), else null. Set "stale" to "A" when the relation is "supersedes", else null.
|
|
19
|
+
|
|
20
|
+
Answer ONLY with JSON: {"relation": "...", "redundant": "A"|"B"|null, "stale": "A"|null, "confidence": 0.0-1.0, "reason": "<at most 25 words>"}
|
|
@@ -8,11 +8,11 @@ updated: 2026-09-28
|
|
|
8
8
|
|
|
9
9
|
<!--
|
|
10
10
|
SOFT guidance only — advice, not a contract. Back-linking here is a RETRIEVAL
|
|
11
|
-
mechanism, not decoration: `xrefs:` frontmatter folds into the search index
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
11
|
+
mechanism, not decoration: `xrefs:` frontmatter folds into the search index
|
|
12
|
+
and is stored as a declared link `akm show` lists on both assets.
|
|
13
|
+
Over-linking degrades ranking, so these rules are deliberately conservative.
|
|
14
|
+
(LLM-wiki bundles carry their own xref system in their pages' frontmatter —
|
|
15
|
+
this convention is for in-stash assets.)
|
|
16
16
|
-->
|
|
17
17
|
|
|
18
18
|
# Back-linking conventions
|
|
@@ -21,9 +21,8 @@ Cross-references are how knowledge compounds instead of being re-derived every
|
|
|
21
21
|
session. In AKM they are also **indexed**: the strings in an asset's `xrefs:`
|
|
22
22
|
frontmatter fold into its search-hint text and are stored as links that
|
|
23
23
|
`akm show` lists on both assets (with `supersededBy:`, `contradictedBy:` and a
|
|
24
|
-
`.derived` memory's parent)
|
|
25
|
-
|
|
26
|
-
lever — which means both too few and too many hurt.
|
|
24
|
+
`.derived` memory's parent). So links are a retrieval lever — which means both
|
|
25
|
+
too few and too many hurt.
|
|
27
26
|
|
|
28
27
|
```yaml
|
|
29
28
|
---
|
|
@@ -48,10 +47,8 @@ xrefs:
|
|
|
48
47
|
- **Associative xrefs are discretionary — real relationships only.** Add one when
|
|
49
48
|
you already know a genuine load-bearing connection. Do **not** hit a link
|
|
50
49
|
quota by pointing at the topically-nearest sibling — a plausible-but-wrong
|
|
51
|
-
xref makes this asset a false search match for the other topic
|
|
52
|
-
|
|
53
|
-
want the graph to learn must be named in the body (e.g. open with "Corrects
|
|
54
|
-
knowledge/auth/oauth-refresh-races").
|
|
50
|
+
xref makes this asset a false search match for the other topic and a false
|
|
51
|
+
declared link on both assets' `akm show` output.
|
|
55
52
|
- **Cap total xrefs at ~5 (a heuristic, not a measured threshold).** Each xref
|
|
56
53
|
folds its ref tokens into THIS asset's search hints — past a handful, the
|
|
57
54
|
asset matches queries about several other topics and its own ranking signal
|
|
@@ -80,19 +77,20 @@ prose is indexed in the lowest-weight `content` field, so
|
|
|
80
77
|
`description:`/`when_to_use:` remain the primary orientation channel. Then
|
|
81
78
|
open the body with a plain title plus a one-line
|
|
82
79
|
orientation naming what it is, its scope/domain, and its key entities in
|
|
83
|
-
canonical spelling (`Postgres`, `OAuth`, `TLS`, `Acme`) —
|
|
84
|
-
|
|
85
|
-
Keep the canonical-spelling list in `facts/conventions/domains`
|
|
86
|
-
fragment `postgres` / `postgresql` / `pg`.
|
|
80
|
+
canonical spelling (`Postgres`, `OAuth`, `TLS`, `Acme`) — consistent spelling
|
|
81
|
+
keeps search matches from fragmenting across variants, and readers land here
|
|
82
|
+
from `akm show`. Keep the canonical-spelling list in `facts/conventions/domains`
|
|
83
|
+
so agents don't fragment `postgres` / `postgresql` / `pg`.
|
|
87
84
|
|
|
88
85
|
## Hubs are optional, not per-namespace obligations
|
|
89
86
|
|
|
90
87
|
A hub (a `knowledge/` overview page that xrefs the key assets in a domain) is
|
|
91
88
|
worth authoring for a **few genuinely high-traffic domains**. Do **not**
|
|
92
89
|
mandate a hub per namespace and do not edit a hub on every write: that is O(n)
|
|
93
|
-
maintenance, a concurrent-write contention point, and it flattens
|
|
94
|
-
|
|
95
|
-
effort on per-asset self-situating headers
|
|
90
|
+
maintenance, a concurrent-write contention point, and it flattens every linked
|
|
91
|
+
asset's declared links into a namespace-wide star centered on the hub. Let the
|
|
92
|
+
FTS index be the catalog; spend the effort on per-asset self-situating headers
|
|
93
|
+
instead.
|
|
96
94
|
|
|
97
95
|
## Keep assets atomic
|
|
98
96
|
|
|
@@ -48,8 +48,8 @@ volume justifies it.
|
|
|
48
48
|
## Canonical entity spellings
|
|
49
49
|
|
|
50
50
|
Pick ONE name per entity and use it everywhere in asset **bodies** — retrieval
|
|
51
|
-
is case-insensitive but treats aliases as different
|
|
52
|
-
fragment
|
|
51
|
+
is case-insensitive but treats aliases as different terms, so alias variants
|
|
52
|
+
fragment search matches. Extend as your stash grows.
|
|
53
53
|
|
|
54
54
|
- Postgres (not postgresql / pg)
|
|
55
55
|
- Kubernetes (not k8s)
|