akm-cli 0.9.0-rc.0 → 0.9.0-rc.13
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 +1283 -22
- package/README.md +62 -37
- package/SECURITY.md +46 -31
- package/dist/akm +162 -38
- package/dist/akm-migrate +44 -0
- package/dist/assets/backends/schtasks-template.xml +2 -1
- package/dist/assets/hints/cli-hints-full.md +268 -118
- package/dist/assets/hints/cli-hints-short.md +87 -24
- package/dist/assets/{profiles → improve-strategies}/catchup.json +3 -1
- package/dist/assets/{profiles → improve-strategies}/consolidate.json +3 -1
- package/dist/assets/{profiles → improve-strategies}/default.json +6 -7
- package/dist/assets/improve-strategies/frequent.json +15 -0
- package/dist/assets/{profiles → improve-strategies}/graph-refresh.json +4 -2
- package/dist/assets/{profiles → improve-strategies}/memory-focus.json +4 -1
- package/dist/assets/{profiles → improve-strategies}/proactive-maintenance.json +5 -5
- package/dist/assets/{profiles → improve-strategies}/quick.json +4 -2
- package/dist/assets/improve-strategies/reflect-distill.json +30 -0
- package/dist/assets/{profiles → improve-strategies}/thorough.json +1 -1
- package/dist/assets/prompts/consolidate-system.md +5 -5
- package/dist/assets/prompts/extract-session.md +2 -6
- package/dist/assets/prompts/memory-infer-user.md +2 -3
- package/dist/assets/prompts/reflect-llm-framed-contract.md +11 -0
- package/dist/assets/prompts/reflect-llm-schema-contract.md +3 -0
- package/dist/assets/prompts/reflect-output-repair.md +3 -0
- package/dist/assets/prompts/workflow-unit-preamble.md +26 -0
- package/dist/assets/stash-skeleton/README.md +38 -10
- package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +8 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +8 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +14 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +13 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +9 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +11 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +9 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +9 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +8 -0
- package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +100 -0
- package/dist/assets/stash-skeleton/facts/conventions/domains.md +64 -0
- package/dist/assets/stash-skeleton/facts/conventions/organization.md +136 -0
- package/dist/assets/tasks/core/extract.yml +3 -2
- package/dist/assets/tasks/core/improve.yml +2 -1
- package/dist/assets/tasks/core/index-refresh.yml +1 -0
- package/dist/assets/tasks/core/sync.yml +1 -0
- package/dist/assets/tasks/core/version-check.yml +2 -1
- package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +5 -0
- package/dist/assets/tasks/improve/akm-improve-catchup.yml +8 -0
- package/dist/assets/tasks/improve/akm-improve-consolidate.yml +5 -0
- package/dist/assets/tasks/improve/akm-improve-frequent.yml +5 -0
- package/dist/assets/tasks/improve/akm-improve-nightly.yml +5 -0
- package/dist/assets/templates/html/health.html +5 -4
- package/dist/assets/workflows/workflow-template.md +31 -15
- package/dist/cli/invocation.js +279 -0
- package/dist/cli/parse-args.js +5 -90
- package/dist/cli/retired-commands.js +78 -0
- package/dist/cli/shared.js +158 -48
- package/dist/cli-node.mjs +2 -1
- package/dist/cli.js +747 -293
- package/dist/commands/agent/agent-dispatch.js +19 -18
- package/dist/commands/agent/agent-support.js +0 -24
- package/dist/commands/agent/contribute-cli.js +43 -97
- package/dist/commands/completions.js +80 -23
- package/dist/commands/config-cli.js +44 -281
- package/dist/commands/env/env-binding.js +99 -0
- package/dist/commands/env/env-cli.js +84 -224
- package/dist/commands/env/env.js +12 -163
- package/dist/commands/env/marker-path.js +6 -0
- package/dist/commands/env/secret-cli.js +45 -61
- package/dist/commands/env/secret.js +32 -62
- package/dist/commands/feedback-cli.js +179 -85
- package/dist/commands/health/accept-rate.js +58 -0
- package/dist/commands/health/advisories.js +7 -8
- package/dist/commands/health/checks.js +279 -94
- package/dist/commands/health/html-report.js +197 -578
- package/dist/commands/health/improve-metrics.js +277 -246
- package/dist/commands/health/llm-usage.js +19 -19
- package/dist/commands/health/md-report.js +16 -7
- package/dist/commands/health/metrics.js +67 -32
- package/dist/commands/health/renderers.js +47 -0
- package/dist/commands/health/report-view-model.js +508 -0
- package/dist/commands/health/stash-exposure.js +1 -1
- package/dist/commands/health/surfaces.js +16 -56
- package/dist/commands/health/task-runs.js +3 -67
- package/dist/{migrate-storage-node.mjs → commands/health/types-checks.js} +1 -5
- package/dist/commands/health/types-improve.js +29 -0
- package/dist/{output/text/save.js → commands/health/types-metrics.js} +1 -2
- package/dist/commands/health/types-result.js +7 -0
- package/dist/commands/health/types-runs.js +4 -0
- package/dist/commands/health/types-session-log.js +4 -0
- package/dist/commands/health/types-windows.js +4 -0
- package/dist/commands/health/types.js +26 -21
- package/dist/commands/health/windows.js +2 -3
- package/dist/commands/health.js +296 -167
- package/dist/commands/improve/anti-collapse.js +5 -5
- package/dist/commands/improve/autonomy-gate.js +68 -0
- package/dist/commands/improve/collapse-detector.js +65 -52
- package/dist/commands/improve/consolidate/chunking.js +9 -7
- package/dist/commands/improve/consolidate/eligibility.js +1 -23
- package/dist/commands/improve/consolidate/merge.js +4 -0
- package/dist/commands/improve/consolidate.js +454 -1354
- package/dist/commands/improve/content-hash.js +39 -0
- package/dist/commands/improve/distill/content-repair.js +4 -10
- package/dist/commands/improve/distill/promote-memory.js +89 -64
- package/dist/commands/improve/distill/quality-gate.js +118 -42
- package/dist/commands/improve/distill-guards.js +1 -1
- package/dist/commands/improve/distill-promotion-policy.js +33 -888
- package/dist/commands/improve/distill.js +607 -363
- package/dist/commands/improve/eligibility.js +165 -79
- package/dist/commands/improve/extract-cli.js +35 -126
- package/dist/commands/improve/extract-prompt.js +6 -35
- package/dist/commands/improve/extract.js +640 -391
- package/dist/commands/improve/feedback-valence.js +2 -12
- package/dist/commands/improve/improve-cli.js +134 -135
- package/dist/commands/improve/improve-result-file.js +30 -50
- package/dist/commands/improve/improve-run-types.js +4 -0
- package/dist/commands/improve/improve-strategies.js +135 -0
- package/dist/commands/improve/improve.js +904 -701
- package/dist/commands/improve/locks.js +64 -111
- package/dist/commands/improve/loop-stages.js +1110 -923
- package/dist/commands/improve/memory/derived-ref.js +124 -0
- package/dist/commands/improve/memory/memory-belief.js +79 -7
- package/dist/commands/improve/memory/memory-contradiction-detect.js +49 -52
- package/dist/commands/improve/memory/memory-improve.js +25 -37
- package/dist/commands/improve/outcome-loop.js +25 -88
- package/dist/commands/improve/preparation.js +1034 -813
- package/dist/commands/improve/proactive-maintenance.js +34 -9
- package/dist/commands/improve/proposal-envelope.js +31 -0
- package/dist/commands/improve/reflect.js +983 -794
- package/dist/commands/improve/run-context.js +119 -0
- package/dist/commands/improve/salience.js +24 -127
- package/dist/commands/improve/session-asset.js +7 -3
- package/dist/commands/improve/shared.js +14 -34
- package/dist/commands/improve/source-identity.js +28 -0
- package/dist/commands/improve/triage.js +20 -17
- package/dist/commands/lint/base-linter.js +340 -313
- package/dist/commands/lint/env-key-rules.js +31 -47
- package/dist/commands/lint/index.js +185 -30
- package/dist/commands/{events.js → log.js} +28 -38
- package/dist/commands/migrate-cli.js +54 -0
- package/dist/commands/migration-tool.js +55 -0
- package/dist/commands/observability-cli.js +70 -208
- package/dist/commands/proposal/diff-format.js +50 -0
- package/dist/commands/proposal/drain-policies.js +0 -6
- package/dist/commands/proposal/drain.js +91 -40
- package/dist/commands/proposal/proposal-cli.js +134 -132
- package/dist/commands/proposal/proposal-types.js +56 -0
- package/dist/commands/proposal/proposal.js +83 -65
- package/dist/commands/proposal/propose-cli.js +88 -0
- package/dist/commands/proposal/propose.js +105 -88
- package/dist/commands/proposal/repository.js +1303 -278
- package/dist/commands/proposal/validators/proposal-quality-validators.js +16 -6
- package/dist/commands/proposal/validators/proposal-validators.js +61 -12
- package/dist/commands/proposal/validators/proposals.js +6 -8
- package/dist/commands/read/curate.js +78 -73
- package/dist/commands/read/knowledge.js +510 -13
- package/dist/commands/read/registry-search.js +2 -2
- package/dist/commands/read/remember-cli.js +84 -15
- package/dist/commands/read/search-cli.js +203 -96
- package/dist/commands/read/search.js +126 -94
- package/dist/commands/read/show.js +226 -250
- package/dist/commands/registry-cli.js +34 -60
- package/dist/commands/remember.js +18 -57
- package/dist/commands/sources/add-cli.js +104 -49
- package/dist/commands/sources/bundle-cli.js +166 -0
- package/dist/commands/sources/bundle-config-ops.js +63 -0
- package/dist/commands/sources/info.js +27 -15
- package/dist/commands/sources/init.js +30 -40
- package/dist/commands/sources/installed-stashes.js +469 -172
- package/dist/commands/sources/migration-help.js +7 -4
- package/dist/commands/sources/schema-repair.js +10 -9
- package/dist/commands/sources/self-update.js +182 -121
- package/dist/commands/sources/source-add.js +169 -178
- package/dist/commands/sources/source-clone.js +144 -41
- package/dist/commands/sources/source-manage.js +94 -59
- package/dist/commands/sources/sources-cli.js +64 -205
- package/dist/commands/sources/stash-cli.js +91 -54
- package/dist/commands/sources/stash-skeleton.js +1 -1
- package/dist/commands/tasks/tasks-cli.js +106 -104
- package/dist/commands/tasks/tasks.js +445 -262
- package/dist/commands/workflow-cli.js +232 -121
- package/dist/core/action-contributors.js +1 -1
- package/dist/core/activation-policy.js +49 -0
- package/dist/core/adapter/adapters/agent-skills-adapter.js +181 -0
- package/dist/core/adapter/adapters/akm-adapter.js +528 -0
- package/dist/core/adapter/adapters/akm-lint.js +392 -0
- package/dist/core/adapter/adapters/akm-metadata.js +387 -0
- package/dist/core/adapter/adapters/akm-task-adapter.js +149 -0
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +180 -0
- package/dist/core/adapter/adapters/claude-adapter.js +61 -0
- package/dist/core/adapter/adapters/dotenv-adapter.js +187 -0
- package/dist/core/adapter/adapters/generic-files-adapter.js +119 -0
- package/dist/core/adapter/adapters/index.js +80 -0
- package/dist/core/adapter/adapters/llm-wiki-adapter.js +419 -0
- package/dist/core/adapter/adapters/okf-adapter.js +391 -0
- package/dist/core/adapter/adapters/opencode-adapter.js +68 -0
- package/dist/core/adapter/adapters/shared.js +286 -0
- package/dist/core/adapter/adapters/tool-dir-shared.js +217 -0
- package/dist/core/adapter/adapters/website-snapshot-adapter.js +155 -0
- package/dist/core/adapter/bundle-adapter.js +4 -0
- package/dist/core/adapter/detect-adapter.js +17 -0
- package/dist/core/adapter/recognize-match.js +44 -0
- package/dist/core/adapter/registry.js +56 -0
- package/dist/core/adapter/types.js +4 -0
- package/dist/core/asset/akm-markdown.js +30 -0
- package/dist/core/asset/asset-placement.js +243 -0
- package/dist/core/asset/asset-ref.js +110 -79
- package/dist/core/asset/asset-serialize.js +20 -0
- package/dist/core/asset/frontmatter.js +28 -12
- package/dist/core/asset/markdown.js +40 -51
- package/dist/core/asset/resolve-ref.js +274 -0
- package/dist/core/asset/stash-meta.js +2 -2
- package/dist/core/bundle-id.js +51 -0
- package/dist/core/common.js +281 -86
- package/dist/core/config/config-io.js +42 -128
- package/dist/core/config/config-schema.js +233 -834
- package/dist/core/config/config-sources.js +162 -39
- package/dist/core/config/config-types.js +16 -11
- package/dist/core/config/config-version.js +29 -0
- package/dist/core/config/config-walker.js +126 -37
- package/dist/core/config/config.js +154 -331
- package/dist/core/config/deep-merge.js +41 -0
- package/dist/core/config/engine-semantics.js +28 -0
- package/dist/core/config/experimental.js +21 -0
- package/dist/core/config/schema/embedding.js +38 -0
- package/dist/core/config/schema/engines.js +116 -0
- package/dist/core/config/schema/experimental.js +47 -0
- package/dist/core/config/schema/feedback.js +31 -0
- package/dist/core/config/schema/improve-processes.js +389 -0
- package/dist/core/config/schema/improve.js +94 -0
- package/dist/core/config/schema/index-config.js +176 -0
- package/dist/core/config/schema/output.js +18 -0
- package/dist/core/config/schema/primitives.js +94 -0
- package/dist/core/config/schema/search.js +30 -0
- package/dist/core/config/schema/setup.js +18 -0
- package/dist/core/config/schema/sources-bundles.js +169 -0
- package/dist/core/config/schema/workflow.js +29 -0
- package/dist/core/env-secret-ref.js +155 -20
- package/dist/core/errors.js +17 -15
- package/dist/core/events-types.js +4 -0
- package/dist/core/events.js +46 -128
- package/dist/core/extra-params.js +62 -0
- package/dist/core/file-change.js +17 -0
- package/dist/core/file-lock.js +202 -57
- package/dist/core/fs-txn.js +392 -0
- package/dist/core/git-message.js +59 -0
- package/dist/core/improve-result.js +167 -0
- package/dist/core/json-schema.js +142 -0
- package/dist/core/lesson-lint.js +1 -17
- package/dist/core/logs-db.js +1 -1
- package/dist/core/maintenance-barrier.js +135 -0
- package/dist/core/migration-operation.js +44 -0
- package/dist/core/mutation-target.js +78 -0
- package/dist/core/paths.js +22 -25
- package/dist/core/platform.js +10 -0
- package/dist/core/recognition-util.js +128 -0
- package/dist/core/redaction.js +392 -0
- package/dist/core/standards/resolve-standards-context.js +36 -65
- package/dist/core/standards/resolve-stash-standards.js +2 -2
- package/dist/core/standards/resolve-type-conventions.js +5 -5
- package/dist/core/state/migrations.js +242 -11
- package/dist/core/state-db.js +98 -10
- package/dist/core/structured.js +1 -1
- package/dist/core/subprocess.js +303 -0
- package/dist/core/text-truncation.js +9 -5
- package/dist/core/time.js +20 -0
- package/dist/core/type-presentation.js +130 -0
- package/dist/core/warn.js +0 -3
- package/dist/core/write-source.js +834 -118
- package/dist/indexer/bundle-identity-guard.js +92 -0
- package/dist/indexer/db/graph-db.js +1 -25
- package/dist/indexer/db/llm-cache.js +1 -1
- package/dist/indexer/ensure-index.js +30 -9
- package/dist/indexer/graph/graph-boost.js +9 -30
- package/dist/indexer/graph/graph-extraction.js +41 -27
- package/dist/indexer/graph/graph-types.js +4 -0
- package/dist/indexer/index-writer-lock.js +93 -49
- package/dist/indexer/index-written-assets.js +100 -53
- package/dist/indexer/indexer.js +746 -329
- package/dist/indexer/init.js +18 -25
- package/dist/indexer/installations.js +142 -0
- package/dist/indexer/passes/dir-staleness.js +18 -10
- package/dist/indexer/passes/memory-inference.js +25 -15
- package/dist/indexer/passes/metadata.js +412 -243
- package/dist/indexer/scan/doc-to-entry.js +160 -0
- package/dist/indexer/scan/drain-dir.js +134 -0
- package/dist/indexer/search/db-search.js +292 -108
- package/dist/indexer/search/fts-query.js +64 -0
- package/dist/indexer/search/ranking-contributors.js +145 -25
- package/dist/indexer/search/ranking-types.js +4 -0
- package/dist/indexer/search/ranking.js +28 -71
- package/dist/indexer/search/search-attribution.js +67 -0
- package/dist/indexer/search/search-fields.js +18 -3
- package/dist/indexer/search/search-hit-enrichers.js +30 -40
- package/dist/indexer/search/search-source.js +157 -111
- package/dist/indexer/search/semantic-status.js +4 -1
- package/dist/indexer/usage/usage-events.js +10 -30
- package/dist/indexer/walk/file-context.js +3 -45
- package/dist/indexer/walk/matchers.js +42 -34
- package/dist/indexer/walk/path-resolver.js +11 -5
- package/dist/indexer/walk/walker.js +42 -14
- package/dist/integrations/agent/builder-shared.js +7 -0
- package/dist/integrations/agent/builders.js +5 -56
- package/dist/integrations/agent/config.js +3 -143
- package/dist/integrations/agent/detect.js +17 -2
- package/dist/integrations/agent/engine-resolution.js +231 -0
- package/dist/integrations/agent/index.js +1 -2
- package/dist/integrations/agent/model-aliases.js +16 -2
- package/dist/integrations/agent/profiles.js +36 -62
- package/dist/integrations/agent/prompts.js +46 -18
- package/dist/integrations/agent/runner-dispatch.js +93 -4
- package/dist/integrations/agent/runner.js +76 -208
- package/dist/integrations/agent/spawn.js +88 -196
- package/dist/integrations/harnesses/aider/agent-builder.js +114 -0
- package/dist/integrations/harnesses/aider/index.js +48 -0
- package/dist/integrations/harnesses/aider/result-extractor.js +53 -0
- package/dist/integrations/harnesses/amazonq/agent-builder.js +147 -0
- package/dist/integrations/harnesses/amazonq/index.js +45 -0
- package/dist/integrations/harnesses/amazonq/result-extractor.js +48 -0
- package/dist/integrations/harnesses/claude/agent-builder.js +46 -8
- package/dist/integrations/harnesses/claude/config-import.js +1 -3
- package/dist/integrations/harnesses/claude/index.js +24 -35
- package/dist/integrations/harnesses/claude/result-extractor.js +52 -0
- package/dist/integrations/harnesses/claude/session-log.js +27 -75
- package/dist/integrations/harnesses/codex/agent-builder.js +138 -0
- package/dist/integrations/harnesses/codex/index.js +52 -0
- package/dist/integrations/harnesses/codex/result-extractor.js +73 -0
- package/dist/integrations/harnesses/copilot/agent-builder.js +122 -0
- package/dist/integrations/harnesses/copilot/index.js +48 -0
- package/dist/integrations/harnesses/copilot/result-extractor.js +151 -0
- package/dist/integrations/harnesses/gemini/agent-builder.js +120 -0
- package/dist/integrations/harnesses/gemini/index.js +48 -0
- package/dist/integrations/harnesses/gemini/result-extractor.js +121 -0
- package/dist/integrations/harnesses/ids.js +24 -0
- package/dist/integrations/harnesses/index.js +54 -34
- package/dist/integrations/harnesses/opencode/agent-builder.js +23 -5
- package/dist/integrations/harnesses/opencode/config-import.js +1 -3
- package/dist/integrations/harnesses/opencode/index.js +14 -32
- package/dist/integrations/harnesses/opencode/session-log.js +67 -125
- package/dist/integrations/harnesses/opencode-sdk/harness.js +51 -0
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +681 -108
- package/dist/integrations/harnesses/openhands/agent-builder.js +128 -0
- package/dist/integrations/harnesses/openhands/index.js +48 -0
- package/dist/integrations/harnesses/openhands/result-extractor.js +103 -0
- package/dist/integrations/harnesses/pi/agent-builder.js +97 -0
- package/dist/integrations/harnesses/pi/index.js +45 -0
- package/dist/integrations/harnesses/pi/result-extractor.js +135 -0
- package/dist/integrations/harnesses/shared.js +17 -0
- package/dist/integrations/harnesses/types.js +43 -32
- package/dist/integrations/lockfile.js +211 -24
- package/dist/integrations/session-logs/index.js +36 -39
- package/dist/integrations/session-logs/provider-base.js +113 -0
- package/dist/llm/client.js +182 -110
- package/dist/llm/embedders/deterministic.js +2 -2
- package/dist/llm/embedders/remote.js +21 -9
- package/dist/llm/feature-gate.js +17 -57
- package/dist/llm/graph-extract.js +12 -13
- package/dist/llm/index-passes.js +8 -42
- package/dist/llm/memory-infer.js +144 -1
- package/dist/llm/metadata-enhance.js +45 -30
- package/dist/llm/structured-call.js +16 -8
- package/dist/llm/usage-persist.js +30 -5
- package/dist/llm/usage-telemetry.js +59 -6
- package/dist/output/cli-hints.js +1 -2
- package/dist/output/command-registry.js +27 -0
- package/dist/output/context.js +22 -7
- package/dist/output/format-exempt.js +80 -0
- package/dist/output/generic-render.js +251 -0
- package/dist/output/html-render.js +11 -16
- package/dist/output/render-registry.js +57 -0
- package/dist/output/renderers.js +14 -279
- package/dist/output/shapes/curate.js +10 -1
- package/dist/output/shapes/events.js +12 -7
- package/dist/output/shapes/helpers.js +58 -84
- package/dist/output/shapes/passthrough.js +11 -39
- package/dist/output/shapes/proposal/producer.js +15 -7
- package/dist/output/shapes/registry.js +12 -6
- package/dist/output/shapes.js +0 -9
- package/dist/output/text/{init.js → bundle-create.js} +3 -1
- package/dist/output/text/bundle-show.js +7 -0
- package/dist/output/text/command-format.js +562 -0
- package/dist/output/text/env.js +1 -3
- package/dist/output/text/events.js +8 -7
- package/dist/output/text/helpers.js +15 -1164
- package/dist/output/text/proposal/producer.js +4 -2
- package/dist/output/text/proposal-format.js +202 -0
- package/dist/output/text/registry-commands.js +1 -2
- package/dist/output/text/registry.js +12 -6
- package/dist/output/text/show-directives.js +117 -0
- package/dist/output/text/show-format.js +103 -0
- package/dist/output/text/sync.js +5 -0
- package/dist/output/text/workflow-format.js +332 -0
- package/dist/output/text/workflow.js +3 -2
- package/dist/output/text.js +10 -19
- package/dist/registry/factory.js +4 -6
- package/dist/registry/origin-resolve.js +16 -27
- package/dist/registry/providers/skills-sh.js +3 -3
- package/dist/registry/providers/static-index.js +15 -25
- package/dist/registry/resolve.js +43 -94
- package/dist/registry/semver.js +43 -0
- package/dist/runtime.js +81 -12
- package/dist/scripts/akm-migrate.js +35529 -0
- package/dist/setup/detect.js +5 -7
- package/dist/setup/detected-engines.js +136 -0
- package/dist/setup/engine-config.js +100 -0
- package/dist/setup/registry-stash-loader.js +3 -3
- package/dist/setup/semantic-assets.js +12 -9
- package/dist/setup/setup.js +444 -208
- package/dist/setup/steps/connection-shared.js +120 -0
- package/dist/setup/steps/connection.js +108 -305
- package/dist/setup/steps/platforms.js +13 -12
- package/dist/setup/steps/semantic.js +15 -3
- package/dist/setup/steps/sources.js +21 -15
- package/dist/setup/steps/stashdir.js +6 -4
- package/dist/setup/steps/tasks.js +236 -119
- package/dist/setup/steps.js +3 -2
- package/dist/sources/freshness.js +39 -0
- package/dist/sources/provider-factory.js +11 -17
- package/dist/sources/providers/filesystem.js +2 -3
- package/dist/sources/providers/git-install.js +278 -34
- package/dist/sources/providers/git-provider.js +54 -56
- package/dist/sources/providers/git-stash.js +420 -91
- package/dist/sources/providers/git.js +2 -2
- package/dist/sources/providers/npm.js +16 -19
- package/dist/sources/providers/provider-utils.js +47 -22
- package/dist/sources/providers/sync-from-ref.js +3 -9
- package/dist/sources/providers/website.js +2 -2
- package/dist/sources/resolve.js +11 -10
- package/dist/sources/snapshot-fetchers/types.js +4 -0
- package/dist/sources/{website-ingest.js → snapshot-fetchers/website-ingest.js} +110 -41
- package/dist/storage/database.js +60 -4
- package/dist/storage/engines/sqlite-migrations.js +156 -5
- package/dist/storage/locations.js +1 -2
- package/dist/storage/repositories/canaries-repository.js +1 -1
- package/dist/storage/repositories/events-repository.js +51 -11
- package/dist/storage/repositories/improve-runs-repository.js +6 -32
- package/dist/storage/repositories/index-connection.js +79 -0
- package/dist/storage/repositories/index-db.js +4 -3
- package/dist/storage/repositories/index-entries-repository.js +863 -0
- package/dist/{indexer/db/entry-mapper.js → storage/repositories/index-entry-mapper.js} +19 -2
- package/dist/storage/repositories/index-entry-types.js +4 -0
- package/dist/storage/repositories/index-fts-repository.js +167 -0
- package/dist/storage/repositories/index-llm-cache-repository.js +108 -0
- package/dist/storage/repositories/index-meta-repository.js +49 -0
- package/dist/{indexer/db/schema.js → storage/repositories/index-schema.js} +226 -100
- package/dist/storage/repositories/index-sql.js +12 -0
- package/dist/storage/repositories/index-utility-repository.js +356 -0
- package/dist/storage/repositories/index-vec-repository.js +250 -0
- package/dist/storage/repositories/outcome-repository.js +119 -0
- package/dist/storage/repositories/proposals-repository.js +317 -75
- package/dist/storage/repositories/registry-cache.js +1 -1
- package/dist/storage/repositories/salience-repository.js +172 -0
- package/dist/storage/repositories/task-history-repository.js +110 -3
- package/dist/storage/repositories/workflow-runs-repository.js +240 -19
- package/dist/tasks/backends/cron.js +169 -46
- package/dist/tasks/backends/exec-utils.js +76 -3
- package/dist/tasks/backends/index.js +6 -9
- package/dist/tasks/backends/launchd.js +292 -55
- package/dist/tasks/backends/schtasks.js +557 -70
- package/dist/tasks/backends/types.js +4 -0
- package/dist/tasks/command-executable.js +93 -0
- package/dist/tasks/embedded.js +56 -38
- package/dist/tasks/parser.js +156 -64
- package/dist/tasks/resolve-akm-bin.js +144 -51
- package/dist/tasks/runner.js +377 -209
- package/dist/tasks/schedule.js +108 -19
- package/dist/tasks/scheduler-invocation.js +296 -0
- package/dist/tasks/schema.js +1 -1
- package/dist/tasks/task-id.js +35 -0
- package/dist/tasks/validator.js +30 -16
- package/dist/text-import-hook.mjs +1 -1
- package/dist/workflows/authoring/authoring.js +104 -43
- package/dist/workflows/authoring/scope-key.js +1 -1
- package/dist/workflows/cli.js +0 -16
- package/dist/workflows/concurrency-policy.js +15 -0
- package/dist/workflows/exec/brief.js +450 -0
- package/dist/workflows/exec/frozen-judge.js +47 -0
- package/dist/workflows/exec/native-executor.js +1038 -0
- package/dist/workflows/exec/param-secrets.js +115 -0
- package/dist/workflows/exec/report.js +1460 -0
- package/dist/workflows/exec/run-workflow.js +602 -0
- package/dist/workflows/exec/scheduler.js +71 -0
- package/dist/workflows/exec/step-work.js +1190 -0
- package/dist/workflows/exec/unit-writer.js +23 -0
- package/dist/workflows/exec/workflow-engine-gate.js +67 -0
- package/dist/workflows/exec/worktree.js +171 -0
- package/dist/workflows/ir/compile.js +246 -0
- package/dist/workflows/ir/freeze.js +233 -0
- package/dist/workflows/ir/params.js +54 -0
- package/dist/workflows/ir/plan-hash.js +68 -0
- package/dist/workflows/ir/schema.js +540 -0
- package/dist/workflows/parser.js +878 -304
- package/dist/workflows/program/expressions.js +181 -0
- package/dist/workflows/program/schema.js +51 -0
- package/dist/workflows/renderer.js +100 -45
- package/dist/workflows/resource-limits.js +22 -0
- package/dist/workflows/runtime/agent-identity.js +59 -14
- package/dist/workflows/runtime/checkin.js +1 -1
- package/dist/workflows/runtime/plan-classifier.js +131 -0
- package/dist/workflows/runtime/runs.js +376 -119
- package/dist/workflows/runtime/unit-checkin.js +45 -0
- package/dist/workflows/runtime/unit-phases.js +20 -0
- package/dist/workflows/runtime/workflow-asset-loader.js +241 -40
- package/dist/workflows/schema.js +1 -11
- package/dist/workflows/validate-summary.js +2 -3
- package/dist/workflows/validator.js +52 -30
- package/docs/README.md +42 -78
- package/docs/migration/README.md +8 -0
- package/docs/migration/release-notes/0.6.0.md +1 -1
- package/docs/migration/release-notes/0.7.0.md +9 -8
- package/docs/migration/release-notes/0.9.0.md +158 -14
- package/docs/migration/v0.7-to-v0.8.md +46 -47
- package/docs/migration/v0.8-to-v0.9.md +844 -0
- package/docs/reference/README.md +12 -0
- package/docs/reference/data-and-telemetry.md +333 -0
- package/package.json +21 -17
- package/schemas/akm-asset-envelope.json +93 -0
- package/schemas/akm-config.json +4636 -0
- package/schemas/akm-task.json +87 -0
- package/schemas/akm-workflow.json +373 -0
- package/dist/akm-migrate-storage +0 -38
- package/dist/assets/help/help-accept.md +0 -12
- package/dist/assets/help/help-improve.md +0 -84
- package/dist/assets/help/help-proposals.md +0 -17
- package/dist/assets/help/help-propose.md +0 -17
- package/dist/assets/help/help-reject.md +0 -11
- package/dist/assets/profiles/frequent.json +0 -13
- package/dist/assets/profiles/recombine-only.json +0 -21
- package/dist/assets/profiles/reflect-distill.json +0 -30
- package/dist/assets/profiles/synthesize.json +0 -15
- package/dist/assets/prompts/procedural-system.md +0 -44
- package/dist/assets/prompts/recombine-system.md +0 -40
- package/dist/assets/prompts/staleness-detect-system.md +0 -6
- package/dist/assets/tasks/core/backup.yml +0 -4
- package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
- package/dist/assets/templates/html/default.html +0 -78
- package/dist/assets/templates/html/vendor/echarts.min.js +0 -45
- package/dist/assets/wiki/index-template.md +0 -12
- package/dist/assets/wiki/ingest-workflow-template.md +0 -83
- package/dist/assets/wiki/log-template.md +0 -8
- package/dist/assets/wiki/schema-template.md +0 -61
- package/dist/cli/config-migrate.js +0 -150
- package/dist/cli/config-validate.js +0 -39
- package/dist/commands/graph/graph-cli.js +0 -124
- package/dist/commands/graph/graph.js +0 -487
- package/dist/commands/improve/calibration.js +0 -161
- package/dist/commands/improve/dedup.js +0 -482
- package/dist/commands/improve/extract-watch.js +0 -140
- package/dist/commands/improve/hot-probation.js +0 -45
- package/dist/commands/improve/improve-auto-accept.js +0 -276
- package/dist/commands/improve/improve-profiles.js +0 -168
- package/dist/commands/improve/procedural.js +0 -398
- package/dist/commands/improve/recombine.js +0 -818
- package/dist/commands/improve/schema-similarity-gate.js +0 -168
- package/dist/commands/lint/agent-linter.js +0 -44
- package/dist/commands/lint/command-linter.js +0 -44
- package/dist/commands/lint/default-linter.js +0 -16
- package/dist/commands/lint/fact-linter.js +0 -39
- package/dist/commands/lint/knowledge-linter.js +0 -16
- package/dist/commands/lint/memory-linter.js +0 -61
- package/dist/commands/lint/registry.js +0 -41
- package/dist/commands/lint/skill-linter.js +0 -45
- package/dist/commands/lint/task-linter.js +0 -50
- package/dist/commands/lint/workflow-linter.js +0 -81
- package/dist/commands/proposal/legacy-import.js +0 -115
- package/dist/commands/sources/history.js +0 -196
- package/dist/commands/tasks/default-tasks.js +0 -186
- package/dist/commands/wiki-cli.js +0 -292
- package/dist/core/asset/asset-registry.js +0 -76
- package/dist/core/asset/asset-spec.js +0 -259
- package/dist/core/config/config-migration.js +0 -602
- package/dist/core/deep-merge.js +0 -38
- package/dist/core/eval/rank-metrics.js +0 -113
- package/dist/core/ripgrep/install.js +0 -163
- package/dist/core/ripgrep/resolve.js +0 -81
- package/dist/indexer/db/db.js +0 -1413
- package/dist/indexer/manifest.js +0 -170
- package/dist/indexer/passes/metadata-contributors.js +0 -31
- package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -94
- package/dist/integrations/harnesses/opencode-sdk/index.js +0 -49
- package/dist/llm/call-ai.js +0 -62
- package/dist/llm/memory-infer-impl.js +0 -138
- package/dist/output/shapes/distill.js +0 -14
- package/dist/output/shapes/history.js +0 -11
- package/dist/output/text/distill.js +0 -6
- package/dist/output/text/enable-disable.js +0 -8
- package/dist/output/text/history.js +0 -6
- package/dist/output/text/wiki.js +0 -16
- package/dist/registry/build-index.js +0 -386
- package/dist/scripts/migrate-storage.js +0 -19108
- package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +0 -9411
- package/dist/scripts/migrations/v16-to-v17.js +0 -141
- package/dist/setup/legacy-config.js +0 -106
- package/dist/storage/repositories/consolidation-repository.js +0 -38
- package/dist/storage/repositories/recombine-repository.js +0 -213
- package/dist/wiki/wiki-templates.js +0 -15
- package/dist/wiki/wiki.js +0 -1012
- package/dist/workflows/db.js +0 -215
- package/docs/data-and-telemetry.md +0 -226
- /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/registry.js +0 -0
- /package/dist/sources/{wiki-fetchers → snapshot-fetchers}/youtube.js +0 -0
|
@@ -1,8 +1,20 @@
|
|
|
1
1
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
+
import { isKnownType } from "../../core/recognition-util.js";
|
|
4
5
|
import { computeGraphBoost } from "../graph/graph-boost.js";
|
|
5
|
-
|
|
6
|
+
import { attachSearchHitAttribution } from "./search-attribution.js";
|
|
7
|
+
/**
|
|
8
|
+
* Chunk 1.5 (D1.5-5) — retyped from `Record<string, number>` to a FULL
|
|
9
|
+
* `Record<KnownType, number>`. Only 8/14 types carried an entry before this
|
|
10
|
+
* chunk (`env`, `secret`, `wiki`, `lesson`, `task`, `session` silently fell
|
|
11
|
+
* through to the `?? 0` fallback at the sole consumer,
|
|
12
|
+
* {@link typeRankingContributor}). The 6 additions below are explicit `0`
|
|
13
|
+
* entries — behavior-preserving (they already defaulted to `0`), but now
|
|
14
|
+
* compile-time-exhaustive: adding a new `KNOWN_TYPE` forces an explicit
|
|
15
|
+
* boost decision instead of silently defaulting.
|
|
16
|
+
*/
|
|
17
|
+
export const TYPE_BOOST = {
|
|
6
18
|
skill: 0.4,
|
|
7
19
|
command: 0.35,
|
|
8
20
|
workflow: 0.35,
|
|
@@ -12,19 +24,46 @@ const TYPE_BOOST = {
|
|
|
12
24
|
// Facts are authoritative, durable declarations about the stash — rank them
|
|
13
25
|
// alongside knowledge so they surface reliably when relevant.
|
|
14
26
|
fact: 0.22,
|
|
27
|
+
// Instruction files (CLAUDE.md / AGENTS.md) are project instructions read
|
|
28
|
+
// like knowledge (maintainer resolution 2026-07) — rank them alongside
|
|
29
|
+
// knowledge so they surface reliably when relevant.
|
|
30
|
+
instruction: 0.22,
|
|
15
31
|
memory: -0.02,
|
|
32
|
+
// Chunk 1.5: previously-absent entries, all defaulted to 0 pre-chunk —
|
|
33
|
+
// explicit now, unchanged in effect.
|
|
34
|
+
env: 0,
|
|
35
|
+
secret: 0,
|
|
36
|
+
lesson: 0,
|
|
37
|
+
task: 0,
|
|
38
|
+
session: 0,
|
|
16
39
|
};
|
|
40
|
+
/**
|
|
41
|
+
* Open-string accessor over {@link TYPE_BOOST} (plan §2.3 "ranking
|
|
42
|
+
* accessor"). Foreign/unknown types (outside `KNOWN_TYPES`) fall back to `0`
|
|
43
|
+
* — identical to the old `TYPE_BOOST[item.entry.type] ?? 0` behavior on a
|
|
44
|
+
* loosely-typed `Record<string, number>`, now expressed safely over the
|
|
45
|
+
* exhaustive `Record<KnownType, number>`.
|
|
46
|
+
*/
|
|
47
|
+
export function typeBoostFor(type) {
|
|
48
|
+
return isKnownType(type) ? TYPE_BOOST[type] : 0;
|
|
49
|
+
}
|
|
17
50
|
const MAX_BOOST_SUM = 3.0;
|
|
18
51
|
const UTILITY_WEIGHT = 0.5;
|
|
19
52
|
const UTILITY_MAX_BOOST = 1.5;
|
|
20
53
|
/**
|
|
21
|
-
* R2
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
54
|
+
* R2 / #692 — weight of the improve loop's `asset_salience.rank_score`.
|
|
55
|
+
* rank_score ∈ [0,1] → boost ∈ [1, 1.2]. Bounded well below the utility boost
|
|
56
|
+
* so the composed signal would refine, never dominate, lexical/semantic
|
|
57
|
+
* relevance.
|
|
58
|
+
*
|
|
59
|
+
* As of #692 this is NOT wired into default user-facing ranking — see
|
|
60
|
+
* {@link salienceRankingContributor}'s doc comment. Kept exported (with the
|
|
61
|
+
* contributor) for a future gated experiment; do not reintroduce it into
|
|
62
|
+
* {@link defaultUtilityRankingContributors} without a measured
|
|
63
|
+
* curate-golden-bench delta and an explicit config gate.
|
|
25
64
|
*/
|
|
26
|
-
const SALIENCE_WEIGHT = 0.2;
|
|
27
|
-
const SALIENCE_MAX_BOOST = 1.2;
|
|
65
|
+
export const SALIENCE_WEIGHT = 0.2;
|
|
66
|
+
export const SALIENCE_MAX_BOOST = 1.2;
|
|
28
67
|
/**
|
|
29
68
|
* Phase 2A / Rec 5: default recency half-life (days) used when no
|
|
30
69
|
* `utilityDecayConfig` is supplied to the ranking pipeline. Matches the
|
|
@@ -61,6 +100,54 @@ function beliefStateBoost(item) {
|
|
|
61
100
|
return 0.06;
|
|
62
101
|
return 0;
|
|
63
102
|
}
|
|
103
|
+
/**
|
|
104
|
+
* Post-boost score ceilings for the demoting belief states (SPEC-5,
|
|
105
|
+
* stash-conventions-code-spec.md — corrections demotion).
|
|
106
|
+
*
|
|
107
|
+
* Why the additive {@link beliefStateBoost} penalties alone are not enough:
|
|
108
|
+
* keyword base scores are min-max normalized into [0.3, 1.0]
|
|
109
|
+
* (`normalizeFtsScores`), so the spread between the best FTS hit and its
|
|
110
|
+
* runner-up can be as large as 0.7 — and the boost sum then MULTIPLIES the
|
|
111
|
+
* base (`score *= 1 + boostSum`, {@link applyScoreContributors}). A
|
|
112
|
+
* superseded incumbent that is the best keyword match for a query therefore
|
|
113
|
+
* stays clamp-pinned at 1.0 above its own correction no matter what additive
|
|
114
|
+
* penalty it receives — defeating the corrections pattern's point ("so the
|
|
115
|
+
* ranker demotes the stale version instead of letting it outrank your fix").
|
|
116
|
+
*
|
|
117
|
+
* The ceilings guarantee the demotion while keeping flagged entries VISIBLE:
|
|
118
|
+
* un-demoted keyword hits floor at a 0.3 base, so any un-demoted hit outranks
|
|
119
|
+
* a ceilinged one; demoted entries still list (belief FILTERING stays a
|
|
120
|
+
* separate opt-in axis, `--belief`), and scores already below a ceiling keep
|
|
121
|
+
* their relative ordering. Ceiling order mirrors the additive-penalty
|
|
122
|
+
* severity order pinned in tests/integration/belief-state-phase1a.test.ts:
|
|
123
|
+
* deprecated (mildest) > superseded > contradicted > archived.
|
|
124
|
+
*/
|
|
125
|
+
const BELIEF_STATE_SCORE_CEILINGS = {
|
|
126
|
+
deprecated: 0.28,
|
|
127
|
+
superseded: 0.25,
|
|
128
|
+
contradicted: 0.2,
|
|
129
|
+
archived: 0.15,
|
|
130
|
+
};
|
|
131
|
+
/**
|
|
132
|
+
* Clamp a ranked entry's FINAL score (after every additive and utility boost)
|
|
133
|
+
* to its demoting belief state's ceiling. No-op for `asserted`/`active`/unset
|
|
134
|
+
* entries. Applied once per item at the end of `applyRankingRules` so sort
|
|
135
|
+
* order and displayed scores stay consistent (single scoring pipeline).
|
|
136
|
+
*
|
|
137
|
+
* When the ceiling clamps, the pre-clamp score is recorded as
|
|
138
|
+
* `preCeilingScore` so db-search's semantic-only `minScore` floor can judge
|
|
139
|
+
* the hit by what it would have scored WITHOUT the demotion — a ceiling below
|
|
140
|
+
* the floor (archived 0.15 < default minScore 0.2) must demote a hit to last
|
|
141
|
+
* place, never silently drop it from the results.
|
|
142
|
+
*/
|
|
143
|
+
export function applyBeliefStateScoreCeiling(item) {
|
|
144
|
+
const state = item.entry.beliefState;
|
|
145
|
+
const ceiling = state !== undefined ? BELIEF_STATE_SCORE_CEILINGS[state] : undefined;
|
|
146
|
+
if (ceiling !== undefined && item.score > ceiling) {
|
|
147
|
+
item.preCeilingScore = item.score;
|
|
148
|
+
item.score = ceiling;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
64
151
|
const exactNameRankingContributor = {
|
|
65
152
|
name: "exact-name-ranking",
|
|
66
153
|
appliesTo: () => true,
|
|
@@ -86,7 +173,7 @@ const typeRankingContributor = {
|
|
|
86
173
|
name: "type-ranking",
|
|
87
174
|
appliesTo: () => true,
|
|
88
175
|
adjust(item) {
|
|
89
|
-
return
|
|
176
|
+
return typeBoostFor(item.entry.type);
|
|
90
177
|
},
|
|
91
178
|
};
|
|
92
179
|
const beliefStateRankingContributor = {
|
|
@@ -189,13 +276,27 @@ const graphRankingContributor = {
|
|
|
189
276
|
adjust(item, ctx) {
|
|
190
277
|
return ctx.graphContext ? computeGraphBoost(ctx.graphContext, item.filePath) : 0;
|
|
191
278
|
},
|
|
279
|
+
applied(item, ctx, contribution) {
|
|
280
|
+
if (!ctx.graphContext || contribution <= 0)
|
|
281
|
+
return;
|
|
282
|
+
const graphNode = ctx.graphContext.nodesByPath.get(item.filePath);
|
|
283
|
+
attachSearchHitAttribution(item, {
|
|
284
|
+
graphExtraction: {
|
|
285
|
+
boost: contribution,
|
|
286
|
+
...(graphNode?.bodyHash ? { bodyHash: graphNode.bodyHash } : {}),
|
|
287
|
+
...((graphNode?.extractionRunId ?? ctx.graphContext.graph.telemetry?.extractionRunId)
|
|
288
|
+
? { extractionRunId: graphNode?.extractionRunId ?? ctx.graphContext.graph.telemetry?.extractionRunId }
|
|
289
|
+
: {}),
|
|
290
|
+
},
|
|
291
|
+
});
|
|
292
|
+
},
|
|
192
293
|
};
|
|
193
294
|
/**
|
|
194
295
|
* Capture-mode boost — Phase 1B / Rec 7.
|
|
195
296
|
*
|
|
196
297
|
* Memories captured via the hot path (`akm remember`) get a modest additive
|
|
197
298
|
* boost so they outrank otherwise-equal background-derived memories. Memories
|
|
198
|
-
* without `captureMode`
|
|
299
|
+
* without `captureMode` return 0.
|
|
199
300
|
*/
|
|
200
301
|
const captureModeRankingContributor = {
|
|
201
302
|
name: "capture-mode-ranking",
|
|
@@ -227,7 +328,7 @@ const lessonStrengthContributor = {
|
|
|
227
328
|
* Pinned-fact boost.
|
|
228
329
|
*
|
|
229
330
|
* Facts marked `pinned: true` form the small always-injected "core context"
|
|
230
|
-
* (see docs/
|
|
331
|
+
* (see docs/architecture/specs/fact-asset-type.md). The fact metadata contributor records
|
|
231
332
|
* a `pinned` search hint; here we give those facts a modest additive boost so
|
|
232
333
|
* the core outranks ordinary facts on otherwise-equal queries. Capped small so
|
|
233
334
|
* it cannot overpower an exact-name match.
|
|
@@ -309,7 +410,7 @@ const utilityRankingContributor = {
|
|
|
309
410
|
*
|
|
310
411
|
* Skipped entirely when `projectContext` is absent or has no tokens (e.g.
|
|
311
412
|
* when running from home dir, /tmp, or when disabled via
|
|
312
|
-
* `--no-project-context`
|
|
413
|
+
* `--no-project-context`).
|
|
313
414
|
*/
|
|
314
415
|
const projectContextRankingContributor = {
|
|
315
416
|
name: "project-context-ranking",
|
|
@@ -349,15 +450,31 @@ export const defaultRankingContributors = [
|
|
|
349
450
|
projectContextRankingContributor,
|
|
350
451
|
];
|
|
351
452
|
/**
|
|
352
|
-
* R2 —
|
|
453
|
+
* R2 — the improve loop's salience core, as a bounded multiplicative ranking
|
|
454
|
+
* boost. `asset_salience.rank_score` (encoding + outcome + retrieval
|
|
455
|
+
* projection, maintained every improve run) otherwise drives only improve's
|
|
456
|
+
* INTERNAL maintenance selection.
|
|
353
457
|
*
|
|
354
|
-
*
|
|
355
|
-
*
|
|
356
|
-
*
|
|
357
|
-
*
|
|
358
|
-
*
|
|
458
|
+
* **#692 — NOT in {@link defaultUtilityRankingContributors}.** Removed from
|
|
459
|
+
* default user-facing ranking (search/curate): the boost was
|
|
460
|
+
* retrieval-dominated (`w_r = 0.60` in salience.ts, with no source filter, so
|
|
461
|
+
* it double-counted the same `usage_events` the utility EMA contributor
|
|
462
|
+
* already reinforces), warm-started non-zero with no outcome evidence, had
|
|
463
|
+
* zero pack coverage (favoring only self-generated personal assets), and
|
|
464
|
+
* measured as noise on live data (max observed multiplier ×1.071). Removing
|
|
465
|
+
* its default state.db load also deleted a confirmed hot-path defect — see
|
|
466
|
+
* the now-deleted `loadSalienceRankScores` in `ranking.ts` git history.
|
|
467
|
+
*
|
|
468
|
+
* `rank_score` itself is UNCHANGED as improve's internal selection signal.
|
|
469
|
+
* This contributor, and its weight/cap constants, stay exported so a FUTURE
|
|
470
|
+
* gated experiment (config-gated, outcome-gated) can wire it back in
|
|
471
|
+
* explicitly — see `RankEntriesOptions.salienceRankScores`'s doc comment in
|
|
472
|
+
* `ranking.ts`. Reachable today only via explicit contributor-list injection
|
|
473
|
+
* (tests / eval harnesses calling `applyUtilityContributors` directly with a
|
|
474
|
+
* list that includes it) — never through `applyRankingRules` / `akm search` /
|
|
475
|
+
* `akm curate`.
|
|
359
476
|
*/
|
|
360
|
-
const salienceRankingContributor = {
|
|
477
|
+
export const salienceRankingContributor = {
|
|
361
478
|
name: "salience-ranking",
|
|
362
479
|
appliesTo(item, ctx) {
|
|
363
480
|
const rank = ctx.salienceRankScores?.get(item.id);
|
|
@@ -369,10 +486,10 @@ const salienceRankingContributor = {
|
|
|
369
486
|
item.score *= Math.min(rawBoost, SALIENCE_MAX_BOOST);
|
|
370
487
|
},
|
|
371
488
|
};
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
];
|
|
489
|
+
// #692 — salienceRankingContributor deliberately excluded; see its doc
|
|
490
|
+
// comment. Do not add it back here without a config gate + a measured
|
|
491
|
+
// curate-golden-bench delta justifying it.
|
|
492
|
+
export const defaultUtilityRankingContributors = [utilityRankingContributor];
|
|
376
493
|
/**
|
|
377
494
|
* EVAL/DEBUG ONLY — remove named ranking contributors from a list.
|
|
378
495
|
*
|
|
@@ -380,11 +497,10 @@ export const defaultUtilityRankingContributors = [
|
|
|
380
497
|
* `name`s). A no-op — returns the input list unchanged (same reference) — when
|
|
381
498
|
* the env value is unset/empty, so production ranking is never affected unless
|
|
382
499
|
* the operator opts in. Its sole purpose is per-contributor ablation for the
|
|
383
|
-
* curate ablation harness (
|
|
384
|
-
* and `scripts/akm-eval/`): run the same fixture with and without a contributor
|
|
500
|
+
* curate ablation harness (`scripts/akm-eval/`): run the same fixture with and without a contributor
|
|
385
501
|
* and diff the ranked results to measure whether that contributor is load-bearing.
|
|
386
502
|
*
|
|
387
|
-
* NOTE (
|
|
503
|
+
* NOTE (from the 2026-06 ablation analysis): a contributor's ablation delta is only observable
|
|
388
504
|
* in the UNSATURATED score regime — once entries saturate at the `displayScore`
|
|
389
505
|
* ceiling their contributor deltas are absorbed and ablation reads Δ=0.
|
|
390
506
|
*/
|
|
@@ -404,7 +520,11 @@ export function applyScoreContributors(item, ctx, contributors = defaultRankingC
|
|
|
404
520
|
for (const contributor of contributors) {
|
|
405
521
|
if (!contributor.appliesTo(item, ctx))
|
|
406
522
|
continue;
|
|
523
|
+
const cappedBefore = Math.min(boostSum, MAX_BOOST_SUM);
|
|
407
524
|
boostSum += contributor.adjust(item, ctx);
|
|
525
|
+
// Attribution receives only the share admitted by the common boost cap,
|
|
526
|
+
// never a raw contributor value that scoring discarded.
|
|
527
|
+
contributor.applied?.(item, ctx, Math.min(boostSum, MAX_BOOST_SUM) - cappedBefore);
|
|
408
528
|
}
|
|
409
529
|
item.score *= 1 + Math.min(boostSum, MAX_BOOST_SUM);
|
|
410
530
|
}
|
|
@@ -1,68 +1,8 @@
|
|
|
1
1
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import { getStateDbPath } from "../../core/state-db.js";
|
|
7
|
-
import { openDatabase } from "../../storage/database.js";
|
|
8
|
-
import { getUtilityScoresByIds } from "../db/db.js";
|
|
9
|
-
import { applyContributorAblation, applyScoreContributors, applyUtilityContributors, defaultRankingContributors, defaultUtilityRankingContributors, } from "./ranking-contributors.js";
|
|
10
|
-
/**
|
|
11
|
-
* R2 — best-effort load of `asset_salience.rank_score` from state.db for the
|
|
12
|
-
* ranked items. Fail-open: any error (state.db locked by a concurrent improve
|
|
13
|
-
* run, missing table, unreadable path) returns an empty map, which makes the
|
|
14
|
-
* salience contributor a no-op — byte-identical to pre-R2 ranking.
|
|
15
|
-
*
|
|
16
|
-
* Deliberately NOT `openStateDatabase()`: that helper runs migrations and sets
|
|
17
|
-
* a 30 s busy timeout — too heavy for a search hot path. This opens read-only,
|
|
18
|
-
* never creates or migrates state.db (missing file / missing table = empty
|
|
19
|
-
* map), and caps lock waits at 250 ms so a concurrent improve run can only
|
|
20
|
-
* ever cost the search a quarter second, not a stall.
|
|
21
|
-
*/
|
|
22
|
-
export function loadSalienceRankScores(items) {
|
|
23
|
-
const result = new Map();
|
|
24
|
-
if (items.length === 0)
|
|
25
|
-
return result;
|
|
26
|
-
try {
|
|
27
|
-
const dbPath = getStateDbPath();
|
|
28
|
-
if (!fs.existsSync(dbPath))
|
|
29
|
-
return result; // improve loop has never run here
|
|
30
|
-
const idByRef = new Map();
|
|
31
|
-
for (const item of items) {
|
|
32
|
-
idByRef.set(makeAssetRef(item.entry.type, item.entry.name), item.id);
|
|
33
|
-
}
|
|
34
|
-
const stateDb = openDatabase(dbPath, { readonly: true });
|
|
35
|
-
try {
|
|
36
|
-
try {
|
|
37
|
-
stateDb.exec("PRAGMA busy_timeout = 250");
|
|
38
|
-
}
|
|
39
|
-
catch {
|
|
40
|
-
// pragma failure on a readonly handle is fine — default timeout applies
|
|
41
|
-
}
|
|
42
|
-
const refs = [...idByRef.keys()];
|
|
43
|
-
const CHUNK = 500;
|
|
44
|
-
for (let i = 0; i < refs.length; i += CHUNK) {
|
|
45
|
-
const chunk = refs.slice(i, i + CHUNK);
|
|
46
|
-
const placeholders = chunk.map(() => "?").join(",");
|
|
47
|
-
const rows = stateDb
|
|
48
|
-
.prepare(`SELECT asset_ref, rank_score FROM asset_salience WHERE asset_ref IN (${placeholders})`)
|
|
49
|
-
.all(...chunk);
|
|
50
|
-
for (const row of rows) {
|
|
51
|
-
const id = idByRef.get(row.asset_ref);
|
|
52
|
-
if (id !== undefined)
|
|
53
|
-
result.set(id, row.rank_score);
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
finally {
|
|
58
|
-
stateDb.close();
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
catch {
|
|
62
|
-
// Fail open — search must never break because state.db is unavailable.
|
|
63
|
-
}
|
|
64
|
-
return result;
|
|
65
|
-
}
|
|
4
|
+
import { getUtilityScoresByIds } from "../../storage/repositories/index-utility-repository.js";
|
|
5
|
+
import { applyBeliefStateScoreCeiling, applyContributorAblation, applyScoreContributors, applyUtilityContributors, defaultRankingContributors, defaultUtilityRankingContributors, } from "./ranking-contributors.js";
|
|
66
6
|
export function normalizeFtsScores(results) {
|
|
67
7
|
const ftsScoreMap = new Map();
|
|
68
8
|
if (results.length === 0)
|
|
@@ -93,6 +33,9 @@ export function combineSearchScores(options) {
|
|
|
93
33
|
filePath: result.filePath,
|
|
94
34
|
score: combinedScore,
|
|
95
35
|
rankingMode: embedScore !== undefined ? "hybrid" : "fts",
|
|
36
|
+
itemRef: result.itemRef,
|
|
37
|
+
bundleId: result.bundleId,
|
|
38
|
+
conceptId: result.conceptId,
|
|
96
39
|
});
|
|
97
40
|
}
|
|
98
41
|
for (const [id, cosine] of options.embedScoreMap) {
|
|
@@ -112,6 +55,9 @@ export function combineSearchScores(options) {
|
|
|
112
55
|
filePath: found.filePath,
|
|
113
56
|
score: cosine * VEC_WEIGHT,
|
|
114
57
|
rankingMode: "semantic",
|
|
58
|
+
itemRef: found.itemRef,
|
|
59
|
+
bundleId: found.bundleId,
|
|
60
|
+
conceptId: found.conceptId,
|
|
115
61
|
});
|
|
116
62
|
}
|
|
117
63
|
return scored;
|
|
@@ -127,21 +73,26 @@ export function applyRankingRules(options) {
|
|
|
127
73
|
graphContext: options.graphContext,
|
|
128
74
|
projectContext: options.projectContext,
|
|
129
75
|
};
|
|
130
|
-
// Eval/debug only:
|
|
131
|
-
//
|
|
132
|
-
//
|
|
133
|
-
|
|
76
|
+
// Eval/debug only: lets the ablation harness drop named contributors to
|
|
77
|
+
// measure their effect. Resolved once per query; a no-op (full lists) when
|
|
78
|
+
// unset — see applyContributorAblation. C9: DI via
|
|
79
|
+
// `options.ablateContributors` is now the primary path (see the field's
|
|
80
|
+
// doc comment on RankEntriesOptions); AKM_ABLATE_CONTRIBUTORS is a
|
|
81
|
+
// temporary fallback for the one caller that cannot yet thread the option
|
|
82
|
+
// through (see that doc comment for why).
|
|
83
|
+
const ablateEnv = options.ablateContributors ?? process.env.AKM_ABLATE_CONTRIBUTORS;
|
|
134
84
|
const activeScoreContributors = applyContributorAblation(defaultRankingContributors, ablateEnv);
|
|
135
85
|
const activeUtilityContributors = applyContributorAblation(defaultUtilityRankingContributors, ablateEnv);
|
|
136
86
|
for (const item of options.items) {
|
|
137
87
|
applyScoreContributors(item, rankingContext, activeScoreContributors);
|
|
138
88
|
}
|
|
139
89
|
const { global: utilScoresMap, scoped: scopedUtilScoresMap } = getUtilityScoresByIds(options.db, options.items.map((item) => item.id), options.scopeKey);
|
|
140
|
-
// R2
|
|
141
|
-
//
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
90
|
+
// R2 / #692 — salience-ranking is not in defaultUtilityRankingContributors
|
|
91
|
+
// (see ranking-contributors.ts), so this is never consumed by the default
|
|
92
|
+
// ranking path below; it exists only for a caller that explicitly builds a
|
|
93
|
+
// contributor list including salienceRankingContributor. undefined/null
|
|
94
|
+
// both normalize to "no data" — there is no state.db fallback load.
|
|
95
|
+
const salienceRankScores = options.salienceRankScores ?? new Map();
|
|
145
96
|
const utilityContext = {
|
|
146
97
|
...rankingContext,
|
|
147
98
|
utilityScores: utilScoresMap,
|
|
@@ -152,6 +103,12 @@ export function applyRankingRules(options) {
|
|
|
152
103
|
};
|
|
153
104
|
for (const item of options.items) {
|
|
154
105
|
applyUtilityContributors(item, utilityContext, activeUtilityContributors);
|
|
106
|
+
// SPEC-5: demoting belief states (superseded/contradicted/archived/
|
|
107
|
+
// deprecated) cap the FINAL score. The additive belief penalty inside the
|
|
108
|
+
// multiplicative boost sum cannot overcome the FTS min-max normalization
|
|
109
|
+
// spread, so without the ceiling a superseded incumbent that is the best
|
|
110
|
+
// keyword match outranks its own correction forever.
|
|
111
|
+
applyBeliefStateScoreCeiling(item);
|
|
155
112
|
}
|
|
156
113
|
return options.items;
|
|
157
114
|
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
+
const ATTRIBUTION = Symbol("search-hit-attribution");
|
|
5
|
+
export function attachSearchHitAttribution(target, attribution) {
|
|
6
|
+
const host = target;
|
|
7
|
+
host[ATTRIBUTION] = {
|
|
8
|
+
...host[ATTRIBUTION],
|
|
9
|
+
...attribution,
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
export function copySearchHitAttribution(from, to, outputDescription) {
|
|
13
|
+
const attribution = from[ATTRIBUTION];
|
|
14
|
+
if (!attribution)
|
|
15
|
+
return;
|
|
16
|
+
const memoryInference = attribution.memoryInference;
|
|
17
|
+
const memorySurvives = memoryInference?.exposure !== "surface" ||
|
|
18
|
+
(memoryInference.surfaceDescription !== undefined && memoryInference.surfaceDescription === outputDescription);
|
|
19
|
+
const applicable = {
|
|
20
|
+
...(memorySurvives && memoryInference ? { memoryInference } : {}),
|
|
21
|
+
...(attribution.graphExtraction ? { graphExtraction: attribution.graphExtraction } : {}),
|
|
22
|
+
};
|
|
23
|
+
if (applicable.memoryInference || applicable.graphExtraction)
|
|
24
|
+
attachSearchHitAttribution(to, applicable);
|
|
25
|
+
}
|
|
26
|
+
export function getSearchHitAttribution(target) {
|
|
27
|
+
return target[ATTRIBUTION];
|
|
28
|
+
}
|
|
29
|
+
export function buildUsageEventAttribution(attribution, entryRef, projection = "full") {
|
|
30
|
+
if (!attribution)
|
|
31
|
+
return undefined;
|
|
32
|
+
const memoryInference = attribution.memoryInference;
|
|
33
|
+
const childRef = memoryInference?.exposure === "direct" ? entryRef : memoryInference?.childRef;
|
|
34
|
+
const graphExtraction = attribution.graphExtraction;
|
|
35
|
+
const graphApplies = graphExtraction !== undefined && Number.isFinite(graphExtraction.boost) && graphExtraction.boost > 0;
|
|
36
|
+
const surfaceFields = memoryInference?.surfaceFields ?? [];
|
|
37
|
+
const surfaceVisible = memoryInference?.exposure !== "surface" ||
|
|
38
|
+
(projection === "full"
|
|
39
|
+
? surfaceFields.length > 0
|
|
40
|
+
: projection === "normal" || projection === "agent"
|
|
41
|
+
? surfaceFields.includes("description")
|
|
42
|
+
: false);
|
|
43
|
+
const memoryApplies = memoryInference !== undefined && childRef?.includes("//") === true && surfaceVisible;
|
|
44
|
+
if (!memoryApplies && !graphApplies)
|
|
45
|
+
return undefined;
|
|
46
|
+
return {
|
|
47
|
+
...(memoryApplies
|
|
48
|
+
? {
|
|
49
|
+
memoryInference: {
|
|
50
|
+
exposure: memoryInference.exposure,
|
|
51
|
+
childRef,
|
|
52
|
+
},
|
|
53
|
+
}
|
|
54
|
+
: {}),
|
|
55
|
+
...(graphApplies ? { graphExtraction } : {}),
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
export function usageEventAttributionMetadata(attribution, entryRef, projection = "full") {
|
|
59
|
+
const applicable = buildUsageEventAttribution(attribution, entryRef, projection);
|
|
60
|
+
return JSON.stringify({
|
|
61
|
+
downstreamAttribution: {
|
|
62
|
+
version: 1,
|
|
63
|
+
control: applicable === undefined,
|
|
64
|
+
...applicable,
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
}
|
|
@@ -9,14 +9,16 @@
|
|
|
9
9
|
* - description: entry description
|
|
10
10
|
* - tags: tags + aliases joined
|
|
11
11
|
* - hints: searchHints + examples + usage + intent fields
|
|
12
|
-
* - content: TOC headings
|
|
12
|
+
* - content: TOC headings + parameters + the config-gated body opening
|
|
13
|
+
* (lowest-weight catch-all)
|
|
13
14
|
*/
|
|
14
15
|
// NOTE (R5): the collapse detector's frozen canary queries are built from the
|
|
15
16
|
// same surface this function indexes (name tokens / tags / description) and
|
|
16
17
|
// scored via FTS against it. Changing what buildSearchFields includes shifts
|
|
17
18
|
// the detector's recall baseline for ALL existing canary sets — coordinate
|
|
18
19
|
// with src/commands/improve/collapse-detector.ts (buildCanaryQuery) and expect
|
|
19
|
-
// operators to re-mint via `
|
|
20
|
+
// operators to re-mint via `bun scripts/refresh-canary-set.ts --refresh` after
|
|
21
|
+
// such a change.
|
|
20
22
|
export function buildSearchFields(entry) {
|
|
21
23
|
const name = entry.name.replace(/[-_]/g, " ").toLowerCase();
|
|
22
24
|
const description = (entry.description ?? "").toLowerCase();
|
|
@@ -27,6 +29,8 @@ export function buildSearchFields(entry) {
|
|
|
27
29
|
tagParts.push(entry.aliases.join(" "));
|
|
28
30
|
const tags = tagParts.join(" ").toLowerCase();
|
|
29
31
|
const hintParts = [];
|
|
32
|
+
if (entry.hints)
|
|
33
|
+
hintParts.push(entry.hints.join(" "));
|
|
30
34
|
if (entry.searchHints)
|
|
31
35
|
hintParts.push(entry.searchHints.join(" "));
|
|
32
36
|
if (entry.examples)
|
|
@@ -49,6 +53,8 @@ export function buildSearchFields(entry) {
|
|
|
49
53
|
hintParts.push(entry.whenToUse);
|
|
50
54
|
const hints = hintParts.join(" ").toLowerCase();
|
|
51
55
|
const contentParts = [];
|
|
56
|
+
if (entry.content)
|
|
57
|
+
contentParts.push(entry.content);
|
|
52
58
|
if (entry.toc) {
|
|
53
59
|
contentParts.push(entry.toc.map((h) => h.text).join(" "));
|
|
54
60
|
}
|
|
@@ -59,12 +65,21 @@ export function buildSearchFields(entry) {
|
|
|
59
65
|
contentParts.push(param.description);
|
|
60
66
|
}
|
|
61
67
|
}
|
|
68
|
+
// Stash-organization conventions (SPEC-8): the self-situating body opening
|
|
69
|
+
// (captured by the metadata pass only when `index.indexBodyOpening` is on)
|
|
70
|
+
// folds into the lowest-weight catch-all column — never name/description/
|
|
71
|
+
// tags/hints — so orientation prose is retrievable without outranking
|
|
72
|
+
// structured-field matches. The fold is unconditional on the entry field:
|
|
73
|
+
// `rebuildFts` rebuilds FTS rows from stored entry_json and must reproduce
|
|
74
|
+
// the same fields without re-reading config.
|
|
75
|
+
if (entry.bodyOpening)
|
|
76
|
+
contentParts.push(entry.bodyOpening);
|
|
62
77
|
const content = contentParts.join(" ").toLowerCase();
|
|
63
78
|
return { name, description, tags, hints, content };
|
|
64
79
|
}
|
|
65
80
|
/**
|
|
66
81
|
* Build a single concatenated search text string for an entry.
|
|
67
|
-
* Used for the `search_text` column in the entries table
|
|
82
|
+
* Used for the `search_text` column in the entries table.
|
|
68
83
|
* and for generating embedding text.
|
|
69
84
|
*/
|
|
70
85
|
export function buildSearchText(entry) {
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
-
import {
|
|
5
|
-
import { getDerivedForParent } from "
|
|
4
|
+
import { displayRef } from "../../core/asset/resolve-ref.js";
|
|
5
|
+
import { getDerivedForParent, getItemRefById } from "../../storage/repositories/index-entries-repository.js";
|
|
6
6
|
import { getRenderer } from "../walk/file-context.js";
|
|
7
|
+
import { attachSearchHitAttribution } from "./search-attribution.js";
|
|
7
8
|
const rendererSearchHitEnricher = {
|
|
8
9
|
name: "renderer-search-hit-enricher",
|
|
9
10
|
appliesTo(ctx) {
|
|
@@ -46,16 +47,23 @@ export const derivedMemoryEnricher = {
|
|
|
46
47
|
// it untouched also avoids `<parent>.derived.derived` chains.
|
|
47
48
|
if (hit.name.toLowerCase().endsWith(".derived"))
|
|
48
49
|
return;
|
|
49
|
-
// Parent ref shape: `
|
|
50
|
-
// so we don't depend on whatever wiki/registry prefix `hit.ref`
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
// Parent ref shape: the 0.9.0 `memories/<name>` conceptId. Re-build from the
|
|
51
|
+
// entry's name so we don't depend on whatever wiki/registry prefix `hit.ref`
|
|
52
|
+
// carries. INTERNAL lookup key into `getDerivedForParent`: the `derived_from`
|
|
53
|
+
// column now stores this same conceptId grammar (Group-C item 2 flip — the
|
|
54
|
+
// metadata producer + this consumer move together).
|
|
55
|
+
const parentRef = `memories/${hit.name}`;
|
|
56
|
+
const derived = getDerivedForParent(ctx.db, parentRef, ctx.stashDir);
|
|
53
57
|
if (!derived)
|
|
54
58
|
return;
|
|
55
59
|
// Swap description / searchHints / tags from the derived child.
|
|
56
60
|
// The parent ref itself is preserved — only the surface text is swapped.
|
|
61
|
+
const surfaceFields = [];
|
|
62
|
+
let surfaceDescription;
|
|
57
63
|
if (typeof derived.entry.description === "string" && derived.entry.description.length > 0) {
|
|
58
64
|
hit.description = derived.entry.description;
|
|
65
|
+
surfaceDescription = derived.entry.description;
|
|
66
|
+
surfaceFields.push("description");
|
|
59
67
|
}
|
|
60
68
|
if (Array.isArray(derived.entry.searchHints) && derived.entry.searchHints.length > 0) {
|
|
61
69
|
// We don't have a `searchHints` field on SourceSearchHit today — it's
|
|
@@ -65,44 +73,26 @@ export const derivedMemoryEnricher = {
|
|
|
65
73
|
}
|
|
66
74
|
if (Array.isArray(derived.entry.tags) && derived.entry.tags.length > 0) {
|
|
67
75
|
hit.tags = derived.entry.tags;
|
|
76
|
+
surfaceFields.push("tags");
|
|
77
|
+
}
|
|
78
|
+
// F4b output-spelling flip: `expandTo` is a user-facing `akm show <ref>`
|
|
79
|
+
// target, so emit the 0.9.0 short conceptId grammar (`memories/<name>`).
|
|
80
|
+
hit.expandTo = displayRef({ type: "memory", name: derived.entry.name });
|
|
81
|
+
const childRef = getItemRefById(ctx.db, derived.id);
|
|
82
|
+
if (childRef && surfaceFields.length > 0) {
|
|
83
|
+
attachSearchHitAttribution(hit, {
|
|
84
|
+
memoryInference: {
|
|
85
|
+
exposure: "surface",
|
|
86
|
+
childRef,
|
|
87
|
+
surfaceFields,
|
|
88
|
+
...(surfaceDescription ? { surfaceDescription } : {}),
|
|
89
|
+
},
|
|
90
|
+
});
|
|
68
91
|
}
|
|
69
|
-
hit.expandTo = makeAssetRef("memory", derived.entry.name);
|
|
70
92
|
},
|
|
71
93
|
};
|
|
72
|
-
/**
|
|
73
|
-
* Registry of additional enrichers — populated by
|
|
74
|
-
* {@link registerSearchHitEnricher} and consumed in addition to
|
|
75
|
-
* {@link defaultSearchHitEnrichers} when `enrichSearchHit` is invoked
|
|
76
|
-
* without an explicit enricher list.
|
|
77
|
-
*
|
|
78
|
-
* Kept module-local so callers must use `registerSearchHitEnricher` rather
|
|
79
|
-
* than mutating the array directly.
|
|
80
|
-
*/
|
|
81
|
-
const additionalEnrichers = [];
|
|
82
94
|
export const defaultSearchHitEnrichers = [rendererSearchHitEnricher, derivedMemoryEnricher];
|
|
83
|
-
|
|
84
|
-
* Register an additional enricher to be applied alongside the defaults.
|
|
85
|
-
*
|
|
86
|
-
* Idempotent on `name`: subsequent calls with the same name replace the
|
|
87
|
-
* previously-registered enricher (so tests can re-register cleanly without
|
|
88
|
-
* stacking duplicates).
|
|
89
|
-
*/
|
|
90
|
-
export function registerSearchHitEnricher(enricher) {
|
|
91
|
-
const existingIndex = additionalEnrichers.findIndex((e) => e.name === enricher.name);
|
|
92
|
-
if (existingIndex >= 0) {
|
|
93
|
-
additionalEnrichers[existingIndex] = enricher;
|
|
94
|
-
}
|
|
95
|
-
else {
|
|
96
|
-
additionalEnrichers.push(enricher);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
/**
|
|
100
|
-
* Test-only: clear the registered-enrichers list. Not part of the public API.
|
|
101
|
-
*/
|
|
102
|
-
export function _resetRegisteredSearchHitEnrichers() {
|
|
103
|
-
additionalEnrichers.length = 0;
|
|
104
|
-
}
|
|
105
|
-
export async function enrichSearchHit(hit, ctx, enrichers = [...defaultSearchHitEnrichers, ...additionalEnrichers]) {
|
|
95
|
+
export async function enrichSearchHit(hit, ctx, enrichers = defaultSearchHitEnrichers) {
|
|
106
96
|
for (const enricher of enrichers) {
|
|
107
97
|
if (!enricher.appliesTo(ctx))
|
|
108
98
|
continue;
|