akm-cli 0.9.16 → 0.9.17-alpha.10
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 +2101 -0
- package/STABILITY.md +11 -10
- package/dist/akm +124 -193
- package/dist/akm-migrate +38 -19
- 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/prompts/consolidate-system.md +4 -11
- package/dist/assets/prompts/retrieval-relevance-judge.md +6 -0
- package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +20 -20
- 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/cli/shared.js +6 -2
- package/dist/cli/unknown-flags.js +24 -1
- package/dist/cli.js +68 -10
- package/dist/commands/agent/agent-dispatch.js +1 -1
- package/dist/commands/command/command-execution.js +24 -62
- package/dist/commands/feedback-cli.js +0 -1
- package/dist/commands/health/accept-rate.js +6 -0
- package/dist/commands/health/archive-usage.js +92 -0
- package/dist/commands/health/checks.js +83 -74
- package/dist/commands/health/config-skew.js +38 -0
- package/dist/commands/health/data-dir-usage.js +25 -13
- package/dist/commands/health/egress.js +54 -0
- package/dist/commands/health/html-report.js +1 -42
- package/dist/commands/health/improve-metrics.js +136 -591
- package/dist/commands/health/md-report.js +1 -6
- package/dist/commands/health/plugin-staleness.js +53 -3
- package/dist/commands/health/renderers.js +12 -4
- package/dist/commands/health/report-view-model.js +14 -120
- package/dist/commands/health/types-improve.js +4 -19
- package/dist/commands/health/windows.js +64 -74
- package/dist/commands/health.js +145 -143
- package/dist/commands/improve/consolidate/chunking.js +26 -117
- 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/sanitize.js +54 -149
- package/dist/commands/improve/consolidate.js +589 -1127
- package/dist/commands/improve/content-hash.js +16 -24
- package/dist/commands/improve/distill/content-repair.js +18 -100
- package/dist/commands/improve/distill-guards.js +20 -81
- package/dist/commands/improve/distill-promotion-policy.js +23 -243
- package/dist/commands/improve/distill.js +608 -1041
- package/dist/commands/improve/eligibility.js +126 -390
- package/dist/commands/improve/execution.js +8 -10
- package/dist/commands/improve/extract-prompt.js +1 -2
- package/dist/commands/improve/extract.js +487 -1046
- package/dist/commands/improve/feedback-valence.js +0 -25
- package/dist/commands/improve/improve-cli.js +75 -169
- package/dist/commands/improve/improve-result-file.js +10 -66
- package/dist/commands/improve/improve-strategies.js +52 -4
- package/dist/commands/improve/improve-usage-report.js +18 -64
- package/dist/commands/improve/improve.js +480 -1074
- package/dist/commands/improve/ledger.js +119 -0
- package/dist/commands/improve/locks.js +2 -8
- package/dist/commands/improve/loop-stages.js +415 -1073
- package/dist/commands/improve/memory/derived-ref.js +12 -77
- package/dist/commands/improve/memory/memory-belief.js +16 -118
- package/dist/commands/improve/memory/memory-improve.js +266 -14
- package/dist/commands/improve/outcome-loop.js +28 -156
- package/dist/commands/improve/planner.js +5 -15
- package/dist/commands/improve/preparation.js +779 -2319
- package/dist/commands/improve/proactive-maintenance.js +34 -101
- package/dist/commands/improve/reflect-noise.js +104 -280
- package/dist/commands/improve/reflect.js +642 -1353
- package/dist/commands/improve/retrieval-gate.js +127 -0
- package/dist/commands/improve/retrieval-scope.js +92 -0
- package/dist/commands/improve/salience.js +41 -240
- package/dist/commands/improve/session-asset.js +19 -100
- package/dist/commands/improve/stage.js +322 -0
- package/dist/commands/lint/base-linter.js +37 -15
- package/dist/commands/proposal/drain.js +261 -578
- package/dist/commands/proposal/proposal-cli.js +19 -20
- package/dist/commands/proposal/proposal-types.js +31 -24
- package/dist/commands/proposal/proposal.js +38 -8
- package/dist/commands/proposal/propose.js +134 -160
- package/dist/commands/proposal/repository.js +1097 -1394
- package/dist/commands/proposal/validators/proposal-quality-validators.js +71 -174
- package/dist/commands/proposal/validators/proposal-validators.js +1 -1
- package/dist/commands/proposal/validators/proposals.js +22 -89
- package/dist/commands/read/curate.js +105 -462
- package/dist/commands/read/knowledge.js +3 -2
- package/dist/commands/read/search-cli.js +16 -33
- package/dist/commands/read/search.js +17 -23
- package/dist/commands/read/show.js +57 -108
- package/dist/commands/sources/bundle-cli.js +25 -2
- package/dist/commands/sources/bundle-config-ops.js +4 -0
- package/dist/commands/sources/dangerous-env-audit.js +1 -2
- package/dist/commands/sources/info.js +127 -29
- package/dist/commands/sources/installed-stashes.js +197 -746
- package/dist/commands/sources/schema-repair.js +98 -129
- package/dist/commands/sources/source-add.js +62 -12
- package/dist/commands/sources/source-manage.js +9 -2
- package/dist/commands/sources/stash-cli.js +24 -4
- package/dist/commands/tasks/explain.js +10 -13
- package/dist/commands/tasks/tasks-cli.js +12 -13
- package/dist/commands/tasks/tasks.js +350 -936
- package/dist/commands/tasks/validate.js +26 -24
- package/dist/commands/workflow/plan.js +22 -29
- package/dist/commands/workflow-cli.js +4 -4
- package/dist/core/adapter/adapters/akm-adapter.js +2 -1
- package/dist/core/adapter/adapters/akm-lint.js +2 -3
- package/dist/core/adapter/adapters/akm-metadata.js +42 -12
- package/dist/core/adapter/adapters/akm-task-adapter.js +29 -8
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +1 -1
- package/dist/core/adapter/execution-source.js +17 -29
- package/dist/core/asset/asset-placement.js +4 -13
- package/dist/core/asset/frontmatter.js +106 -1
- package/dist/core/asset/resolve-ref.js +1 -1
- package/dist/core/bundle-id.js +42 -5
- package/dist/core/bundle-rename.js +285 -0
- package/dist/core/config/config-io.js +1 -2
- package/dist/core/config/config-schema.js +9 -34
- package/dist/core/config/config-walker.js +1 -1
- package/dist/core/config/config.js +184 -111
- package/dist/core/config/engine-semantics.js +0 -2
- package/dist/core/config/legacy-source-shape-shim.js +38 -9
- package/dist/core/config/schema/embedding.js +20 -5
- package/dist/core/config/schema/engines.js +5 -0
- package/dist/core/config/schema/execution.js +1 -1
- package/dist/core/config/schema/experimental.js +1 -1
- package/dist/core/config/schema/improve-processes.js +54 -125
- package/dist/core/config/schema/improve.js +4 -42
- package/dist/core/config/schema/index-config.js +9 -48
- package/dist/core/config/schema/scheduler.js +12 -12
- package/dist/core/config/schema/search.js +6 -22
- package/dist/core/env-secret-ref.js +0 -1
- package/dist/core/errors.js +8 -9
- package/dist/core/file-change.js +13 -5
- package/dist/core/file-lock.js +76 -173
- package/dist/core/improve-result.js +35 -7
- package/dist/core/improve-types.js +0 -1
- package/dist/core/logs-db.js +2 -2
- package/dist/core/loopback.js +7 -12
- package/dist/core/non-task-input.js +20 -0
- package/dist/core/parse.js +13 -16
- package/dist/core/paths.js +0 -24
- package/dist/core/redaction.js +109 -2
- package/dist/core/run-lock.js +2 -5
- package/dist/core/spawn-env.js +1 -1
- package/dist/core/state/migrations.js +123 -61
- package/dist/core/state-db-scope.js +2 -4
- package/dist/core/state-db.js +126 -692
- package/dist/core/time.js +0 -20
- package/dist/core/type-presentation.js +1 -9
- package/dist/core/write-source.js +294 -1005
- package/dist/execution/input-contract.js +1 -1
- package/dist/execution/resolved-request.js +135 -689
- package/dist/execution/source.js +63 -257
- package/dist/execution/target-ref.js +1 -1
- package/dist/indexer/bundle-identity-guard.js +2 -2
- package/dist/indexer/db/llm-cache.js +2 -2
- package/dist/indexer/ensure-index.js +77 -73
- package/dist/indexer/index-rebuild-lock.js +3 -11
- package/dist/indexer/index-writer-lock.js +8 -17
- package/dist/indexer/index-written-assets.js +141 -154
- package/dist/indexer/indexer.js +400 -1124
- package/dist/indexer/links/declared-links.js +90 -0
- package/dist/indexer/materialize-embeddings.js +60 -397
- package/dist/indexer/passes/memory-inference.js +96 -90
- package/dist/indexer/passes/metadata.js +132 -219
- package/dist/indexer/read-preflight.js +0 -7
- package/dist/indexer/scan/doc-to-entry.js +2 -3
- package/dist/indexer/scan/drain-dir.js +1 -1
- package/dist/indexer/search/db-search.js +190 -590
- package/dist/indexer/search/fts-query.js +30 -41
- package/dist/indexer/search/ranking.js +28 -154
- package/dist/indexer/search/search-attribution.js +12 -32
- package/dist/indexer/search/search-fields.js +11 -15
- package/dist/indexer/search/search-hit-enrichers.js +54 -85
- package/dist/indexer/search/search-source.js +1 -4
- package/dist/indexer/usage/usage-events.js +36 -7
- package/dist/indexer/walk/walker.js +3 -4
- package/dist/integrations/agent/engine-fallback.js +23 -40
- package/dist/integrations/agent/engine-resolution.js +93 -183
- package/dist/integrations/agent/execution.js +507 -0
- package/dist/integrations/agent/model-map.js +28 -156
- package/dist/integrations/agent/request-lowering.js +66 -141
- package/dist/integrations/agent/runner-dispatch.js +143 -321
- package/dist/integrations/agent/runner.js +54 -14
- package/dist/integrations/lockfile.js +53 -101
- package/dist/llm/client.js +18 -6
- package/dist/llm/embedders/deterministic.js +2 -3
- package/dist/llm/embedders/profile.js +71 -0
- package/dist/llm/embedders/remote.js +11 -17
- package/dist/llm/feature-gate.js +0 -8
- package/dist/llm/index-passes.js +3 -5
- package/dist/llm/memory-infer.js +1 -2
- package/dist/llm/structured-call.js +5 -24
- package/dist/output/generic-render.js +23 -11
- package/dist/output/html-render.js +13 -10
- package/dist/output/render-registry.js +3 -32
- package/dist/output/shapes/helpers.js +25 -38
- package/dist/output/shapes/passthrough.js +1 -9
- package/dist/{indexer/graph/graph-types.js → output/text/bundle-rename.js} +4 -1
- package/dist/output/text/command-format.js +69 -31
- package/dist/output/text/helpers.js +1 -1
- package/dist/output/text/migrate.js +5 -14
- package/dist/output/text/proposal-format.js +48 -3
- package/dist/output/text/show-format.js +13 -17
- package/dist/output/text/workflow-format.js +0 -32
- package/dist/output/text.js +2 -0
- package/dist/registry/factory.js +4 -19
- package/dist/registry/network.js +66 -220
- package/dist/registry/providers/index.js +0 -2
- package/dist/registry/providers/skills-sh.js +3 -14
- package/dist/registry/providers/static-index.js +24 -26
- package/dist/registry/resolve.js +55 -131
- package/dist/scripts/akm-migrate-node.js +42948 -92369
- package/dist/scripts/akm-migrate.js +42935 -92354
- package/dist/setup/registry-stash-loader.js +4 -13
- package/dist/setup/semantic-assets.js +3 -44
- package/dist/setup/setup.js +1 -1
- package/dist/setup/steps/connection.js +5 -6
- package/dist/setup/steps/platforms.js +2 -2
- package/dist/setup/steps/tasks.js +25 -15
- package/dist/sources/provider-factory.js +17 -18
- package/dist/sources/providers/filesystem.js +2 -3
- package/dist/sources/providers/git-install.js +7 -1
- package/dist/sources/providers/git-provider.js +0 -3
- package/dist/sources/providers/git-stash.js +83 -21
- package/dist/sources/providers/npm.js +2 -4
- package/dist/sources/providers/provider-utils.js +5 -10
- package/dist/sources/providers/website.js +0 -2
- package/dist/sources/snapshot-fetchers/website-ingest.js +1 -1
- package/dist/sources/website-url.js +2 -2
- package/dist/storage/database.js +9 -35
- package/dist/storage/repositories/improve-ledger-repository.js +209 -0
- package/dist/storage/repositories/index-connection.js +39 -72
- package/dist/storage/repositories/index-entries-repository.js +131 -129
- package/dist/storage/repositories/index-entry-mapper.js +1 -2
- package/dist/storage/repositories/index-entry-schema.js +101 -268
- package/dist/storage/repositories/index-fts-repository.js +86 -256
- package/dist/storage/repositories/index-links-repository.js +143 -0
- package/dist/storage/repositories/index-llm-cache-repository.js +7 -9
- package/dist/storage/repositories/index-meta-repository.js +6 -4
- package/dist/storage/repositories/index-schema.js +257 -325
- package/dist/storage/repositories/index-utility-repository.js +8 -29
- package/dist/storage/repositories/index-vec-repository.js +133 -414
- package/dist/storage/repositories/outcome-repository.js +2 -1
- package/dist/storage/repositories/proposals-repository.js +104 -1
- package/dist/storage/repositories/registry-index-cache-repository.js +100 -0
- package/dist/storage/repositories/salience-repository.js +1 -19
- package/dist/storage/repositories/task-history-repository.js +26 -4
- package/dist/storage/repositories/workflow-runs-repository.js +53 -244
- package/dist/storage/sqlite-migrations.js +136 -0
- package/dist/storage/sqlite-pragmas.js +11 -9
- package/dist/storage/sqlite-transaction.js +170 -0
- package/dist/storage/state-db-integrity.js +130 -0
- package/dist/tasks/activation-config.js +134 -62
- package/dist/tasks/backends/cron.js +191 -302
- package/dist/tasks/backends/exec-utils.js +2 -5
- package/dist/tasks/backends/launchd.js +141 -748
- package/dist/tasks/backends/schtasks.js +119 -623
- package/dist/tasks/prepare/prepare-support.js +5 -15
- package/dist/tasks/prepare/prepare.js +0 -2
- package/dist/tasks/resolve-akm-bin.js +20 -79
- package/dist/tasks/run/attempt-lifecycle.js +0 -1
- package/dist/tasks/run/load-task.js +1 -1
- package/dist/tasks/scheduler-binding.js +20 -238
- package/dist/tasks/scheduler-invocation.js +136 -244
- package/dist/tasks/scheduler-lock.js +53 -0
- package/dist/tasks/scheduler-sync.js +368 -679
- package/dist/tasks/source/parse-task-source.js +55 -9
- package/dist/tasks/source/task-source-v3-frozen.js +3 -4
- package/dist/tasks/source/task-to-v4.js +464 -88
- package/dist/workflows/authoring/authoring.js +3 -12
- package/dist/workflows/compile.js +211 -0
- package/dist/workflows/concurrency-policy.js +13 -74
- package/dist/workflows/exec/child-invocation.js +3 -17
- package/dist/workflows/exec/child-workflow.js +32 -141
- package/dist/workflows/exec/dispatch-redaction.js +13 -53
- package/dist/workflows/exec/environment.js +98 -0
- package/dist/workflows/exec/exec-unit.js +33 -140
- package/dist/workflows/exec/frozen-judge.js +7 -59
- package/dist/workflows/exec/native-executor.js +82 -341
- package/dist/workflows/exec/param-secrets.js +29 -47
- package/dist/workflows/exec/run-workflow.js +154 -387
- package/dist/workflows/exec/scheduler.js +9 -36
- package/dist/workflows/exec/step-work.js +127 -430
- package/dist/workflows/exec/unit-dispatch.js +11 -63
- package/dist/workflows/exec/unit-writer.js +8 -52
- package/dist/workflows/exec/worktree.js +39 -273
- package/dist/workflows/freeze/child-output-references.js +4 -15
- package/dist/workflows/freeze/environment.js +99 -92
- package/dist/workflows/freeze/freeze.js +172 -0
- package/dist/workflows/freeze/step-values.js +19 -21
- package/dist/workflows/freeze/targets/child-workflow.js +23 -92
- package/dist/workflows/freeze/targets/command.js +10 -33
- package/dist/workflows/freeze/targets/script.js +5 -12
- package/dist/workflows/freeze/targets/shell.js +3 -6
- package/dist/workflows/freeze/targets/task.js +25 -80
- package/dist/workflows/freeze/task-bindings.js +20 -67
- package/dist/workflows/{source-ir/github-yaml.js → github-yaml.js} +88 -206
- package/dist/workflows/ir/params.js +6 -51
- package/dist/workflows/ir/plan-hash.js +2 -34
- package/dist/workflows/parser.js +140 -43
- package/dist/{commands/improve/consolidate/types.js → workflows/plan.js} +2 -1
- package/dist/workflows/renderer.js +36 -69
- package/dist/workflows/resource-limits.js +12 -120
- package/dist/workflows/runtime/agent-identity.js +8 -40
- package/dist/workflows/runtime/run-outputs.js +3 -6
- package/dist/workflows/runtime/run-plan.js +316 -0
- package/dist/workflows/runtime/runs.js +48 -200
- package/dist/workflows/runtime/workflow-asset-loader.js +24 -57
- package/dist/workflows/{source-ir/semantics.js → source-semantics.js} +16 -20
- package/dist/workflows/validate-summary.js +2 -7
- package/docs/integration/bundling-akm.md +49 -42
- package/docs/migration/README.md +1 -0
- package/docs/migration/release-notes/0.9.17.md +43 -0
- package/docs/migration/v0.9.1-to-v0.9.2.md +23 -7
- package/docs/reference/cli.md +232 -135
- package/docs/reference/configuration.md +71 -57
- package/docs/reference/data-and-telemetry.md +20 -21
- package/docs/reference/tasks.md +105 -39
- package/docs/reference/workflow-schema.md +14 -18
- package/docs/reference/workflows.md +6 -9
- package/package.json +1 -1
- package/schemas/akm-config.json +115 -738
- package/schemas/akm-workflow.json +1 -0
- 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/commands/health/advisories.js +0 -150
- package/dist/commands/health/metrics.js +0 -329
- package/dist/commands/health/surfaces.js +0 -102
- package/dist/commands/improve/anti-collapse.js +0 -83
- package/dist/commands/improve/collapse-detector.js +0 -432
- package/dist/commands/improve/consolidate/eligibility.js +0 -48
- package/dist/commands/improve/consolidate/merge.js +0 -149
- package/dist/commands/improve/distill/promote-memory.js +0 -291
- package/dist/commands/improve/distill/quality-gate.js +0 -337
- package/dist/commands/improve/eval-cases.js +0 -52
- package/dist/commands/improve/memory/memory-contradiction-detect.js +0 -291
- package/dist/commands/improve/proposal-envelope.js +0 -31
- package/dist/commands/improve/run-context.js +0 -123
- package/dist/commands/improve/shared.js +0 -31
- package/dist/commands/improve/source-identity.js +0 -28
- package/dist/commands/improve/triage.js +0 -96
- package/dist/commands/proposal/drain-policies.js +0 -151
- package/dist/commands/sources/update-transaction.js +0 -220
- package/dist/core/action-contributors.js +0 -28
- package/dist/core/config/config-version-shim.js +0 -101
- package/dist/core/fs-txn.js +0 -405
- package/dist/core/lexical-score.js +0 -25
- package/dist/core/maintenance-barrier.js +0 -167
- package/dist/execution/executable-identity.js +0 -105
- package/dist/execution/guarded-source.js +0 -427
- package/dist/indexer/db/graph-db.js +0 -444
- package/dist/indexer/graph/graph-boost.js +0 -427
- package/dist/indexer/graph/graph-dedup.js +0 -95
- package/dist/indexer/graph/graph-extraction.js +0 -1108
- package/dist/indexer/search/name-match.js +0 -35
- package/dist/indexer/search/ranking-contributors.js +0 -515
- package/dist/indexer/search/ranking-types.js +0 -4
- package/dist/indexer/walk/project-context.js +0 -192
- package/dist/integrations/agent/execution-cascade.js +0 -566
- package/dist/integrations/agent/execution-definitions.js +0 -202
- package/dist/integrations/agent/execution-lowering.js +0 -841
- package/dist/integrations/agent/execution-preparation.js +0 -98
- package/dist/integrations/agent/inline-execution.js +0 -74
- package/dist/llm/graph-extract.js +0 -728
- package/dist/llm/metadata-enhance.js +0 -96
- package/dist/registry/create-provider-registry.js +0 -29
- package/dist/registry/pinned-request-helper.js +0 -247
- package/dist/registry/pinned-transport.js +0 -717
- package/dist/sources/providers/index.js +0 -14
- package/dist/storage/engines/sqlite-migrations.js +0 -271
- package/dist/storage/repositories/canaries-repository.js +0 -107
- package/dist/storage/repositories/embedding-salvage-repository.js +0 -184
- package/dist/storage/repositories/registry-cache.js +0 -113
- package/dist/tasks/scheduler-sync-preview.js +0 -52
- package/dist/tasks/source/task-to-v3.js +0 -507
- package/dist/workflows/freeze/resolve-steps.js +0 -86
- package/dist/workflows/freeze/source-freeze.js +0 -64
- package/dist/workflows/ir/compile.js +0 -321
- package/dist/workflows/ir/environment-v4.js +0 -330
- package/dist/workflows/ir/freeze-v4.js +0 -153
- package/dist/workflows/ir/schema-v4.js +0 -745
- package/dist/workflows/ir/schema.js +0 -354
- package/dist/workflows/program/schema.js +0 -77
- package/dist/workflows/runtime/checkin.js +0 -57
- package/dist/workflows/runtime/plan-classifier.js +0 -196
- package/dist/workflows/runtime/unit-checkin.js +0 -45
- package/dist/workflows/runtime/unit-phases.js +0 -20
- package/dist/workflows/schema.js +0 -4
- package/dist/workflows/source-ir/compile.js +0 -200
- package/dist/workflows/source-ir/program.js +0 -50
- package/dist/workflows/source-ir/result.js +0 -26
- package/dist/workflows/source-ir/schema.js +0 -786
- package/dist/workflows/source-ir/triggers.js +0 -79
- package/dist/workflows/source-ir/uses.js +0 -40
- package/dist/workflows/validator.js +0 -60
|
@@ -1,35 +0,0 @@
|
|
|
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
|
-
import { buildLexicalQueryPlan } from "./fts-query.js";
|
|
5
|
-
/**
|
|
6
|
-
* Tokenize a display name through the same Unicode-aware lexical planner as a
|
|
7
|
-
* query. Ranking must not invent a second, punctuation-dependent name grammar.
|
|
8
|
-
*/
|
|
9
|
-
export function lexicalNameTokens(name) {
|
|
10
|
-
return buildLexicalQueryPlan(name).tokens.map((token) => token.toLowerCase());
|
|
11
|
-
}
|
|
12
|
-
/**
|
|
13
|
-
* Structural name-token evidence. Exact tokens are always meaningful; fuzzy
|
|
14
|
-
* prefix evidence requires three code points on both sides so a question's
|
|
15
|
-
* short words or digits cannot match an opaque generated storage name.
|
|
16
|
-
*/
|
|
17
|
-
export function structuralNameTokenMatch(left, right) {
|
|
18
|
-
return (left === right ||
|
|
19
|
-
(Math.min([...left].length, [...right].length) >= 3 && (left.startsWith(right) || right.startsWith(left))));
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Match a query phrase only across complete, contiguous name tokens. This is
|
|
23
|
-
* deliberately not raw substring matching: `000` must not become name
|
|
24
|
-
* evidence merely because an opaque token happens to be `z9xq000`.
|
|
25
|
-
*/
|
|
26
|
-
export function structuralNamePhraseMatch(nameTokens, queryTokens) {
|
|
27
|
-
if (queryTokens.length === 0 || queryTokens.length > nameTokens.length)
|
|
28
|
-
return false;
|
|
29
|
-
for (let start = 0; start <= nameTokens.length - queryTokens.length; start += 1) {
|
|
30
|
-
if (queryTokens.every((queryToken, index) => structuralNameTokenMatch(nameTokens[start + index], queryToken))) {
|
|
31
|
-
return true;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
return false;
|
|
35
|
-
}
|
|
@@ -1,515 +0,0 @@
|
|
|
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
|
-
import { isKnownType } from "../../core/recognition-util.js";
|
|
5
|
-
import { computeGraphBoost } from "../graph/graph-boost.js";
|
|
6
|
-
import { lexicalNameTokens, structuralNamePhraseMatch, structuralNameTokenMatch } from "./name-match.js";
|
|
7
|
-
import { attachSearchHitAttribution } from "./search-attribution.js";
|
|
8
|
-
/**
|
|
9
|
-
* Chunk 1.5 (D1.5-5) — retyped from `Record<string, number>` to a FULL
|
|
10
|
-
* `Record<KnownType, number>`. Only 8/14 types carried an entry before this
|
|
11
|
-
* chunk (`env`, `secret`, `wiki`, `lesson`, `task`, `session` silently fell
|
|
12
|
-
* through to the `?? 0` fallback at the sole consumer,
|
|
13
|
-
* {@link typeRankingContributor}). The 6 additions below are explicit `0`
|
|
14
|
-
* entries — behavior-preserving (they already defaulted to `0`), but now
|
|
15
|
-
* compile-time-exhaustive: adding a new `KNOWN_TYPE` forces an explicit
|
|
16
|
-
* boost decision instead of silently defaulting.
|
|
17
|
-
*/
|
|
18
|
-
export const TYPE_BOOST = {
|
|
19
|
-
skill: 0.4,
|
|
20
|
-
command: 0.35,
|
|
21
|
-
workflow: 0.35,
|
|
22
|
-
agent: 0.3,
|
|
23
|
-
script: 0.2,
|
|
24
|
-
knowledge: 0.22,
|
|
25
|
-
// Facts are authoritative, durable declarations about the stash — rank them
|
|
26
|
-
// alongside knowledge so they surface reliably when relevant.
|
|
27
|
-
fact: 0.22,
|
|
28
|
-
// Instruction files (CLAUDE.md / AGENTS.md) are project instructions read
|
|
29
|
-
// like knowledge (maintainer resolution 2026-07) — rank them alongside
|
|
30
|
-
// knowledge so they surface reliably when relevant.
|
|
31
|
-
instruction: 0.22,
|
|
32
|
-
memory: -0.02,
|
|
33
|
-
// Chunk 1.5: previously-absent entries, all defaulted to 0 pre-chunk —
|
|
34
|
-
// explicit now, unchanged in effect.
|
|
35
|
-
env: 0,
|
|
36
|
-
secret: 0,
|
|
37
|
-
lesson: 0,
|
|
38
|
-
task: 0,
|
|
39
|
-
session: 0,
|
|
40
|
-
};
|
|
41
|
-
/**
|
|
42
|
-
* Open-string accessor over {@link TYPE_BOOST} (plan §2.3 "ranking
|
|
43
|
-
* accessor"). Foreign/unknown types (outside `KNOWN_TYPES`) fall back to `0`
|
|
44
|
-
* — identical to the old `TYPE_BOOST[item.entry.type] ?? 0` behavior on a
|
|
45
|
-
* loosely-typed `Record<string, number>`, now expressed safely over the
|
|
46
|
-
* exhaustive `Record<KnownType, number>`.
|
|
47
|
-
*/
|
|
48
|
-
export function typeBoostFor(type) {
|
|
49
|
-
return isKnownType(type) ? TYPE_BOOST[type] : 0;
|
|
50
|
-
}
|
|
51
|
-
const MAX_BOOST_SUM = 3.0;
|
|
52
|
-
const UTILITY_WEIGHT = 0.5;
|
|
53
|
-
const UTILITY_MAX_BOOST = 1.5;
|
|
54
|
-
/**
|
|
55
|
-
* R2 / #692 — weight of the improve loop's `asset_salience.rank_score`.
|
|
56
|
-
* rank_score ∈ [0,1] → boost ∈ [1, 1.2]. Bounded well below the utility boost
|
|
57
|
-
* so the composed signal would refine, never dominate, lexical/semantic
|
|
58
|
-
* relevance.
|
|
59
|
-
*
|
|
60
|
-
* As of #692 this is NOT wired into default user-facing ranking — see
|
|
61
|
-
* {@link salienceRankingContributor}'s doc comment. Kept exported (with the
|
|
62
|
-
* contributor) for a future gated experiment; do not reintroduce it into
|
|
63
|
-
* {@link defaultUtilityRankingContributors} without a measured
|
|
64
|
-
* curate-golden-bench delta and an explicit config gate.
|
|
65
|
-
*/
|
|
66
|
-
export const SALIENCE_WEIGHT = 0.2;
|
|
67
|
-
export const SALIENCE_MAX_BOOST = 1.2;
|
|
68
|
-
/**
|
|
69
|
-
* Phase 2A / Rec 5: default recency half-life (days) used when no
|
|
70
|
-
* `utilityDecayConfig` is supplied to the ranking pipeline. Matches the
|
|
71
|
-
* pre-2A hardcoded `RECENCY_DECAY_DAYS = 30` constant — the formula is
|
|
72
|
-
* default-safe and collapses to `exp(-days / 30)` when no overrides apply.
|
|
73
|
-
*/
|
|
74
|
-
const DEFAULT_RECENCY_HALF_LIFE_DAYS = 30;
|
|
75
|
-
/**
|
|
76
|
-
* Cap on the effective half-life after applying the feedback stability
|
|
77
|
-
* boost — prevents indefinite half-life inflation for memories with many
|
|
78
|
-
* positive feedback events. `effectiveHalfLife = min(halfLife * boost^count, halfLife * 4)`.
|
|
79
|
-
*/
|
|
80
|
-
const FEEDBACK_HALF_LIFE_CAP_MULTIPLIER = 4;
|
|
81
|
-
function beliefStateBoost(item) {
|
|
82
|
-
const entry = item.entry;
|
|
83
|
-
// 03: belief-state penalties/boosts apply to ANY flagged entry (memory OR
|
|
84
|
-
// knowledge), so contradicted/superseded KNOWLEDGE is demoted from results
|
|
85
|
-
// just like flagged memories. Entries without a belief state fall through to
|
|
86
|
-
// the `return 0` below (default-safe — no effect on unflagged assets).
|
|
87
|
-
// Phase 1A: `asserted` and `deprecated` are first-class states.
|
|
88
|
-
// `asserted` carries stronger user-explicit authority than `active`.
|
|
89
|
-
// `deprecated` is a frozen historical state — penalized but milder than `superseded`.
|
|
90
|
-
if (entry.beliefState === "contradicted")
|
|
91
|
-
return -0.45;
|
|
92
|
-
if (entry.beliefState === "superseded")
|
|
93
|
-
return -0.25;
|
|
94
|
-
if (entry.beliefState === "archived")
|
|
95
|
-
return -0.6;
|
|
96
|
-
if (entry.beliefState === "deprecated")
|
|
97
|
-
return -0.15;
|
|
98
|
-
if (entry.beliefState === "asserted")
|
|
99
|
-
return 0.08;
|
|
100
|
-
if (entry.beliefState === "active")
|
|
101
|
-
return 0.06;
|
|
102
|
-
return 0;
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* Post-boost score ceilings for the demoting belief states (SPEC-5,
|
|
106
|
-
* stash-conventions-code-spec.md — corrections demotion).
|
|
107
|
-
*
|
|
108
|
-
* Why the additive {@link beliefStateBoost} penalties alone are not enough:
|
|
109
|
-
* keyword base scores have a bounded lexical floor (`normalizeFtsScores`),
|
|
110
|
-
* while the boost sum then MULTIPLIES the base (`score *= 1 + boostSum`,
|
|
111
|
-
* {@link applyScoreContributors}). A superseded incumbent can still earn
|
|
112
|
-
* enough independent boosts to outrank its own correction, so additive
|
|
113
|
-
* penalties alone cannot guarantee the corrections pattern's point ("so the
|
|
114
|
-
* ranker demotes the stale version instead of letting it outrank your fix").
|
|
115
|
-
*
|
|
116
|
-
* The ceilings guarantee the demotion while keeping flagged entries VISIBLE:
|
|
117
|
-
* un-demoted keyword hits floor at a 0.3 base, so any un-demoted hit outranks
|
|
118
|
-
* a ceilinged one; demoted entries still list (belief FILTERING stays a
|
|
119
|
-
* separate opt-in axis, `--belief`), and scores already below a ceiling keep
|
|
120
|
-
* their relative ordering. Ceiling order mirrors the additive-penalty
|
|
121
|
-
* severity order pinned in tests/integration/belief-state-phase1a.test.ts:
|
|
122
|
-
* deprecated (mildest) > superseded > contradicted > archived.
|
|
123
|
-
*/
|
|
124
|
-
const BELIEF_STATE_SCORE_CEILINGS = {
|
|
125
|
-
deprecated: 0.28,
|
|
126
|
-
superseded: 0.25,
|
|
127
|
-
contradicted: 0.2,
|
|
128
|
-
archived: 0.15,
|
|
129
|
-
};
|
|
130
|
-
/**
|
|
131
|
-
* Clamp a ranked entry's FINAL score (after every additive and utility boost)
|
|
132
|
-
* to its demoting belief state's ceiling. No-op for `asserted`/`active`/unset
|
|
133
|
-
* entries. Applied once per item at the end of `applyRankingRules` so sort
|
|
134
|
-
* order and displayed scores stay consistent (single scoring pipeline).
|
|
135
|
-
*
|
|
136
|
-
* When the ceiling clamps, the pre-clamp score is recorded as
|
|
137
|
-
* `preCeilingScore` so db-search's semantic-only `minScore` floor can judge
|
|
138
|
-
* the hit by what it would have scored WITHOUT the demotion — a ceiling below
|
|
139
|
-
* the floor (archived 0.15 < default minScore 0.2) must demote a hit to last
|
|
140
|
-
* place, never silently drop it from the results.
|
|
141
|
-
*/
|
|
142
|
-
export function applyBeliefStateScoreCeiling(item) {
|
|
143
|
-
const state = item.entry.beliefState;
|
|
144
|
-
const ceiling = state !== undefined ? BELIEF_STATE_SCORE_CEILINGS[state] : undefined;
|
|
145
|
-
if (ceiling !== undefined && item.score > ceiling) {
|
|
146
|
-
item.preCeilingScore = item.score;
|
|
147
|
-
item.score = ceiling;
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
const exactNameRankingContributor = {
|
|
151
|
-
name: "exact-name-ranking",
|
|
152
|
-
appliesTo: () => true,
|
|
153
|
-
adjust(item, ctx) {
|
|
154
|
-
const entry = item.entry;
|
|
155
|
-
const nameLower = entry.name.toLowerCase();
|
|
156
|
-
const rawNameBase = nameLower.split("/").pop() ?? nameLower;
|
|
157
|
-
const nameBase = entry.type === "memory" && rawNameBase.endsWith(".derived")
|
|
158
|
-
? rawNameBase.slice(0, -".derived".length)
|
|
159
|
-
: rawNameBase;
|
|
160
|
-
if (nameBase === ctx.queryLower || nameLower === ctx.queryLower) {
|
|
161
|
-
return 2.0;
|
|
162
|
-
}
|
|
163
|
-
const nameTokens = lexicalNameTokens(nameBase);
|
|
164
|
-
if (structuralNamePhraseMatch(nameTokens, ctx.queryTokens))
|
|
165
|
-
return 1.0;
|
|
166
|
-
const matchCount = ctx.queryTokens.filter((qt) => nameTokens.some((nt) => structuralNameTokenMatch(nt, qt))).length;
|
|
167
|
-
return matchCount > 0 ? Math.min(0.9, matchCount * 0.3) : 0;
|
|
168
|
-
},
|
|
169
|
-
};
|
|
170
|
-
const typeRankingContributor = {
|
|
171
|
-
name: "type-ranking",
|
|
172
|
-
appliesTo: () => true,
|
|
173
|
-
adjust(item) {
|
|
174
|
-
return typeBoostFor(item.entry.type);
|
|
175
|
-
},
|
|
176
|
-
};
|
|
177
|
-
const beliefStateRankingContributor = {
|
|
178
|
-
name: "belief-state-ranking",
|
|
179
|
-
appliesTo(item) {
|
|
180
|
-
// Fire for any entry that carries a belief state, regardless of type — so
|
|
181
|
-
// contradicted/superseded knowledge is demoted, not just memories. The
|
|
182
|
-
// `.derived`-twin `derivedBoost` (±0.12/−0.08) is deleted (03-R3): it made
|
|
183
|
-
// stale flag-free twins outrank their corrected base memory; belief-state
|
|
184
|
-
// demotion is the principled signal, not the twin-name heuristic.
|
|
185
|
-
return item.entry.beliefState !== undefined;
|
|
186
|
-
},
|
|
187
|
-
adjust(item) {
|
|
188
|
-
return beliefStateBoost(item);
|
|
189
|
-
},
|
|
190
|
-
};
|
|
191
|
-
const tagRankingContributor = {
|
|
192
|
-
name: "tag-ranking",
|
|
193
|
-
appliesTo(item) {
|
|
194
|
-
return Array.isArray(item.entry.tags) && item.entry.tags.length > 0;
|
|
195
|
-
},
|
|
196
|
-
adjust(item, ctx) {
|
|
197
|
-
let tagBoost = 0;
|
|
198
|
-
for (const tag of item.entry.tags ?? []) {
|
|
199
|
-
if (ctx.queryTokens.some((token) => tag.toLowerCase() === token))
|
|
200
|
-
tagBoost += 0.15;
|
|
201
|
-
}
|
|
202
|
-
return Math.min(0.3, tagBoost);
|
|
203
|
-
},
|
|
204
|
-
};
|
|
205
|
-
const searchHintRankingContributor = {
|
|
206
|
-
name: "search-hint-ranking",
|
|
207
|
-
appliesTo(item) {
|
|
208
|
-
return Array.isArray(item.entry.searchHints) && item.entry.searchHints.length > 0;
|
|
209
|
-
},
|
|
210
|
-
adjust(item, ctx) {
|
|
211
|
-
let hintBoost = 0;
|
|
212
|
-
for (const hint of item.entry.searchHints ?? []) {
|
|
213
|
-
const hintLower = hint.toLowerCase();
|
|
214
|
-
for (const token of ctx.queryTokens) {
|
|
215
|
-
if (hintLower.includes(token)) {
|
|
216
|
-
hintBoost += 0.12;
|
|
217
|
-
break;
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
return Math.min(0.24, hintBoost);
|
|
222
|
-
},
|
|
223
|
-
};
|
|
224
|
-
const aliasRankingContributor = {
|
|
225
|
-
name: "alias-ranking",
|
|
226
|
-
appliesTo(item) {
|
|
227
|
-
return Array.isArray(item.entry.aliases) && item.entry.aliases.length > 0;
|
|
228
|
-
},
|
|
229
|
-
adjust(item, ctx) {
|
|
230
|
-
let boost = 0;
|
|
231
|
-
for (const alias of item.entry.aliases ?? []) {
|
|
232
|
-
const aliasLower = alias.toLowerCase();
|
|
233
|
-
if (aliasLower === ctx.queryLower) {
|
|
234
|
-
boost += 1.5;
|
|
235
|
-
break;
|
|
236
|
-
}
|
|
237
|
-
if (ctx.queryTokens.some((token) => aliasLower.includes(token)))
|
|
238
|
-
boost += 0.3;
|
|
239
|
-
}
|
|
240
|
-
return boost;
|
|
241
|
-
},
|
|
242
|
-
};
|
|
243
|
-
const descriptionRankingContributor = {
|
|
244
|
-
name: "description-ranking",
|
|
245
|
-
appliesTo(item) {
|
|
246
|
-
// A relaxed FTS query admits an OR pool. Awarding a flat +0.1 merely
|
|
247
|
-
// because of a partial description coincidence double-counts a weak
|
|
248
|
-
// signal and can outrank materially stronger BM25 body evidence. The FTS
|
|
249
|
-
// score already accounts for descriptions; retain this secondary boost
|
|
250
|
-
// only for conjunctive candidates.
|
|
251
|
-
return (item.lexicalMatch !== "relaxed" && typeof item.entry.description === "string" && item.entry.description.length > 0);
|
|
252
|
-
},
|
|
253
|
-
adjust(item, ctx) {
|
|
254
|
-
const descLower = item.entry.description?.toLowerCase() ?? "";
|
|
255
|
-
const descMatchCount = ctx.queryTokens.filter((token) => descLower.includes(token)).length;
|
|
256
|
-
if (descMatchCount === ctx.queryTokens.length && ctx.queryTokens.length > 1)
|
|
257
|
-
return 0.25;
|
|
258
|
-
if (descMatchCount > 0)
|
|
259
|
-
return 0.1;
|
|
260
|
-
return 0;
|
|
261
|
-
},
|
|
262
|
-
};
|
|
263
|
-
const metadataRankingContributor = {
|
|
264
|
-
name: "metadata-ranking",
|
|
265
|
-
appliesTo: () => true,
|
|
266
|
-
adjust(item) {
|
|
267
|
-
let boost = item.entry.quality === "curated" ? 0.05 : 0;
|
|
268
|
-
if (typeof item.entry.confidence === "number") {
|
|
269
|
-
boost += Math.min(0.05, Math.max(0, item.entry.confidence) * 0.05);
|
|
270
|
-
}
|
|
271
|
-
return boost;
|
|
272
|
-
},
|
|
273
|
-
};
|
|
274
|
-
const graphRankingContributor = {
|
|
275
|
-
name: "graph-ranking",
|
|
276
|
-
appliesTo(_item, ctx) {
|
|
277
|
-
return ctx.graphContext !== null;
|
|
278
|
-
},
|
|
279
|
-
adjust(item, ctx) {
|
|
280
|
-
return ctx.graphContext ? computeGraphBoost(ctx.graphContext, item.filePath) : 0;
|
|
281
|
-
},
|
|
282
|
-
applied(item, ctx, contribution) {
|
|
283
|
-
if (!ctx.graphContext || contribution <= 0)
|
|
284
|
-
return;
|
|
285
|
-
const graphNode = ctx.graphContext.nodesByPath.get(item.filePath);
|
|
286
|
-
attachSearchHitAttribution(item, {
|
|
287
|
-
graphExtraction: {
|
|
288
|
-
boost: contribution,
|
|
289
|
-
...(graphNode?.bodyHash ? { bodyHash: graphNode.bodyHash } : {}),
|
|
290
|
-
...((graphNode?.extractionRunId ?? ctx.graphContext.graph.telemetry?.extractionRunId)
|
|
291
|
-
? { extractionRunId: graphNode?.extractionRunId ?? ctx.graphContext.graph.telemetry?.extractionRunId }
|
|
292
|
-
: {}),
|
|
293
|
-
},
|
|
294
|
-
});
|
|
295
|
-
},
|
|
296
|
-
};
|
|
297
|
-
/**
|
|
298
|
-
* Capture-mode boost — Phase 1B / Rec 7.
|
|
299
|
-
*
|
|
300
|
-
* Memories captured via the hot path (`akm remember`) get a modest additive
|
|
301
|
-
* boost so they outrank otherwise-equal background-derived memories. Memories
|
|
302
|
-
* without `captureMode` return 0.
|
|
303
|
-
*/
|
|
304
|
-
const captureModeRankingContributor = {
|
|
305
|
-
name: "capture-mode-ranking",
|
|
306
|
-
appliesTo(item) {
|
|
307
|
-
return item.entry.type === "memory" && item.entry.captureMode === "hot";
|
|
308
|
-
},
|
|
309
|
-
adjust() {
|
|
310
|
-
return 0.2;
|
|
311
|
-
},
|
|
312
|
-
};
|
|
313
|
-
/**
|
|
314
|
-
* Lesson strength boost — Phase 7A / Advantage D4b.
|
|
315
|
-
*
|
|
316
|
-
* Each ref that has credited a lesson via `akm feedback --applied-to` adds
|
|
317
|
-
* 0.06 to the boost (capped at 0.3 ≈ five credits). Lessons without a
|
|
318
|
-
* `lessonStrength` array (or a number) return 0.
|
|
319
|
-
*/
|
|
320
|
-
const lessonStrengthContributor = {
|
|
321
|
-
name: "lesson-strength-ranking",
|
|
322
|
-
appliesTo(item) {
|
|
323
|
-
return (item.entry.type === "lesson" && typeof item.entry.lessonStrength === "number" && item.entry.lessonStrength > 0);
|
|
324
|
-
},
|
|
325
|
-
adjust(item) {
|
|
326
|
-
const strength = item.entry.lessonStrength ?? 0;
|
|
327
|
-
return Math.min(0.3, 0.06 * strength);
|
|
328
|
-
},
|
|
329
|
-
};
|
|
330
|
-
/**
|
|
331
|
-
* Pinned-fact boost.
|
|
332
|
-
*
|
|
333
|
-
* Facts marked `pinned: true` form the small always-injected "core context"
|
|
334
|
-
* (see docs/architecture/specs/fact-asset-type.md). The fact metadata contributor records
|
|
335
|
-
* a `pinned` search hint; here we give those facts a modest additive boost so
|
|
336
|
-
* the core outranks ordinary facts on otherwise-equal queries. Capped small so
|
|
337
|
-
* it cannot overpower an exact-name match.
|
|
338
|
-
*/
|
|
339
|
-
const pinnedFactRankingContributor = {
|
|
340
|
-
name: "pinned-fact-ranking",
|
|
341
|
-
appliesTo(item) {
|
|
342
|
-
return item.entry.type === "fact" && (item.entry.searchHints?.includes("pinned") ?? false);
|
|
343
|
-
},
|
|
344
|
-
adjust() {
|
|
345
|
-
return 0.15;
|
|
346
|
-
},
|
|
347
|
-
};
|
|
348
|
-
/**
|
|
349
|
-
* Blend ratio for scoped vs. global utility signals.
|
|
350
|
-
*
|
|
351
|
-
* When a scoped row exists: `effectiveUtility = scoped * 0.7 + global * 0.3`
|
|
352
|
-
* This ensures the in-project signal strongly dominates while the global
|
|
353
|
-
* cold-start signal still helps when scoped history is sparse.
|
|
354
|
-
*/
|
|
355
|
-
const SCOPED_UTILITY_BLEND_SCOPED = 0.7;
|
|
356
|
-
const SCOPED_UTILITY_BLEND_GLOBAL = 1 - SCOPED_UTILITY_BLEND_SCOPED;
|
|
357
|
-
const utilityRankingContributor = {
|
|
358
|
-
name: "utility-ranking",
|
|
359
|
-
appliesTo(item, ctx) {
|
|
360
|
-
const utilScore = ctx.utilityScores.get(item.id);
|
|
361
|
-
const scopedScore = ctx.scopedUtilityScores?.get(item.id);
|
|
362
|
-
return Boolean((utilScore && utilScore.utility > 0) || (scopedScore && scopedScore.utility > 0));
|
|
363
|
-
},
|
|
364
|
-
apply(item, ctx) {
|
|
365
|
-
const utilScore = ctx.utilityScores.get(item.id);
|
|
366
|
-
const scopedScore = ctx.scopedUtilityScores?.get(item.id);
|
|
367
|
-
// Determine effective utility: prefer scoped when present, blend with global.
|
|
368
|
-
const globalUtility = utilScore?.utility ?? 0;
|
|
369
|
-
const scopedUtility = scopedScore?.utility ?? 0;
|
|
370
|
-
const effectiveUtility = scopedUtility > 0
|
|
371
|
-
? scopedUtility * SCOPED_UTILITY_BLEND_SCOPED + globalUtility * SCOPED_UTILITY_BLEND_GLOBAL
|
|
372
|
-
: globalUtility;
|
|
373
|
-
if (effectiveUtility <= 0)
|
|
374
|
-
return;
|
|
375
|
-
// Recency decay: use the global lastUsedAt for the decay factor (it's an
|
|
376
|
-
// ISO string with full resolution), falling back to scoped lastUsedAt (ms).
|
|
377
|
-
let recencyFactor = 1;
|
|
378
|
-
const lastUsedRaw = utilScore?.lastUsedAt ?? (scopedScore ? new Date(scopedScore.lastUsedAt).toISOString() : undefined);
|
|
379
|
-
if (lastUsedRaw) {
|
|
380
|
-
const lastUsedMs = new Date(lastUsedRaw).getTime();
|
|
381
|
-
const daysSinceLastUse = Number.isNaN(lastUsedMs)
|
|
382
|
-
? Infinity
|
|
383
|
-
: Math.max(0, (Date.now() - lastUsedMs) / (1000 * 60 * 60 * 24));
|
|
384
|
-
// Phase 2A / Rec 5: configurable forgetting curve with optional
|
|
385
|
-
// feedback-stability boost. Absent config + absent positive feedback
|
|
386
|
-
// collapses to `exp(-days / 30)` — pre-2A default-safe.
|
|
387
|
-
const halfLifeDays = ctx.utilityDecayConfig?.halfLifeDays ?? DEFAULT_RECENCY_HALF_LIFE_DAYS;
|
|
388
|
-
const stabilityBoost = ctx.utilityDecayConfig?.feedbackStabilityBoost ?? 1.5;
|
|
389
|
-
const positiveCount = ctx.positiveFeedbackCounts?.get(item.id) ?? 0;
|
|
390
|
-
// `boost^count` is 1 when count is 0 OR when boost is 1.0, so neither
|
|
391
|
-
// a missing feedback count nor a "no boost" config widens the half-life.
|
|
392
|
-
let stabilizedHalfLife = halfLifeDays * stabilityBoost ** positiveCount;
|
|
393
|
-
stabilizedHalfLife = Math.min(stabilizedHalfLife, halfLifeDays * FEEDBACK_HALF_LIFE_CAP_MULTIPLIER);
|
|
394
|
-
// Defensive: half-life must stay positive to avoid div-by-zero / Infinity.
|
|
395
|
-
const safeHalfLife = Math.max(0.0001, stabilizedHalfLife);
|
|
396
|
-
recencyFactor = Math.exp(-daysSinceLastUse / safeHalfLife);
|
|
397
|
-
}
|
|
398
|
-
const rawBoost = 1 + effectiveUtility * recencyFactor * UTILITY_WEIGHT;
|
|
399
|
-
item.score *= Math.min(rawBoost, UTILITY_MAX_BOOST);
|
|
400
|
-
item.utilityBoosted = true;
|
|
401
|
-
},
|
|
402
|
-
};
|
|
403
|
-
/**
|
|
404
|
-
* Project-context boost.
|
|
405
|
-
*
|
|
406
|
-
* Auto-boosts assets whose name, tags, aliases, or search hints contain tokens
|
|
407
|
-
* derived from the current working directory's project name. For example, when
|
|
408
|
-
* running `akm search` from the `akm` git repo, assets tagged `akm` or named
|
|
409
|
-
* `akm-*` receive an additive boost.
|
|
410
|
-
*
|
|
411
|
-
* The boost is capped at 0.5 so it can never overpower an exact-name match
|
|
412
|
-
* (which contributes 2.0). Each matching token adds 0.2 up to the cap.
|
|
413
|
-
*
|
|
414
|
-
* Skipped entirely when `projectContext` is absent or has no tokens (e.g.
|
|
415
|
-
* when running from home dir, /tmp, or when disabled via
|
|
416
|
-
* `--no-project-context`).
|
|
417
|
-
*/
|
|
418
|
-
const projectContextRankingContributor = {
|
|
419
|
-
name: "project-context-ranking",
|
|
420
|
-
appliesTo(_item, ctx) {
|
|
421
|
-
return ctx.projectContext != null && ctx.projectContext.tokens.size > 0;
|
|
422
|
-
},
|
|
423
|
-
adjust(item, ctx) {
|
|
424
|
-
if (!ctx.projectContext)
|
|
425
|
-
return 0;
|
|
426
|
-
const fields = [
|
|
427
|
-
item.entry.name ?? "",
|
|
428
|
-
...(item.entry.tags ?? []),
|
|
429
|
-
...(item.entry.aliases ?? []),
|
|
430
|
-
...(item.entry.searchHints ?? []),
|
|
431
|
-
].map((s) => s.toLowerCase());
|
|
432
|
-
let hits = 0;
|
|
433
|
-
for (const token of ctx.projectContext.tokens) {
|
|
434
|
-
if (fields.some((f) => f.includes(token)))
|
|
435
|
-
hits++;
|
|
436
|
-
}
|
|
437
|
-
return Math.min(0.5, hits * 0.2);
|
|
438
|
-
},
|
|
439
|
-
};
|
|
440
|
-
export const defaultRankingContributors = [
|
|
441
|
-
exactNameRankingContributor,
|
|
442
|
-
typeRankingContributor,
|
|
443
|
-
beliefStateRankingContributor,
|
|
444
|
-
tagRankingContributor,
|
|
445
|
-
searchHintRankingContributor,
|
|
446
|
-
aliasRankingContributor,
|
|
447
|
-
descriptionRankingContributor,
|
|
448
|
-
metadataRankingContributor,
|
|
449
|
-
graphRankingContributor,
|
|
450
|
-
captureModeRankingContributor,
|
|
451
|
-
lessonStrengthContributor,
|
|
452
|
-
pinnedFactRankingContributor,
|
|
453
|
-
projectContextRankingContributor,
|
|
454
|
-
];
|
|
455
|
-
/**
|
|
456
|
-
* R2 — the improve loop's salience core, as a bounded multiplicative ranking
|
|
457
|
-
* boost. `asset_salience.rank_score` (encoding + outcome + retrieval
|
|
458
|
-
* projection, maintained every improve run) otherwise drives only improve's
|
|
459
|
-
* INTERNAL maintenance selection.
|
|
460
|
-
*
|
|
461
|
-
* **#692 — NOT in {@link defaultUtilityRankingContributors}.** Removed from
|
|
462
|
-
* default user-facing ranking (search/curate): the boost was
|
|
463
|
-
* retrieval-dominated (`w_r = 0.60` in salience.ts, with no source filter, so
|
|
464
|
-
* it double-counted the same `usage_events` the utility EMA contributor
|
|
465
|
-
* already reinforces), warm-started non-zero with no outcome evidence, had
|
|
466
|
-
* zero pack coverage (favoring only self-generated personal assets), and
|
|
467
|
-
* measured as noise on live data (max observed multiplier ×1.071). Removing
|
|
468
|
-
* its default state.db load also deleted a confirmed hot-path defect — see
|
|
469
|
-
* the now-deleted `loadSalienceRankScores` in `ranking.ts` git history.
|
|
470
|
-
*
|
|
471
|
-
* `rank_score` itself is UNCHANGED as improve's internal selection signal.
|
|
472
|
-
* This contributor, and its weight/cap constants, stay exported so a FUTURE
|
|
473
|
-
* gated experiment (config-gated, outcome-gated) can wire it back in
|
|
474
|
-
* explicitly — see `RankEntriesOptions.salienceRankScores`'s doc comment in
|
|
475
|
-
* `ranking.ts`. Reachable today only via explicit contributor-list injection
|
|
476
|
-
* (tests / eval harnesses calling `applyUtilityContributors` directly with a
|
|
477
|
-
* list that includes it) — never through `applyRankingRules` / `akm search` /
|
|
478
|
-
* `akm curate`.
|
|
479
|
-
*/
|
|
480
|
-
export const salienceRankingContributor = {
|
|
481
|
-
name: "salience-ranking",
|
|
482
|
-
appliesTo(item, ctx) {
|
|
483
|
-
const rank = ctx.salienceRankScores?.get(item.id);
|
|
484
|
-
return rank !== undefined && rank > 0;
|
|
485
|
-
},
|
|
486
|
-
apply(item, ctx) {
|
|
487
|
-
const rank = ctx.salienceRankScores?.get(item.id) ?? 0;
|
|
488
|
-
const rawBoost = 1 + Math.min(1, Math.max(0, rank)) * SALIENCE_WEIGHT;
|
|
489
|
-
item.score *= Math.min(rawBoost, SALIENCE_MAX_BOOST);
|
|
490
|
-
},
|
|
491
|
-
};
|
|
492
|
-
// #692 — salienceRankingContributor deliberately excluded; see its doc
|
|
493
|
-
// comment. Do not add it back here without a config gate + a measured
|
|
494
|
-
// curate-golden-bench delta justifying it.
|
|
495
|
-
export const defaultUtilityRankingContributors = [utilityRankingContributor];
|
|
496
|
-
export function applyScoreContributors(item, ctx, contributors = defaultRankingContributors) {
|
|
497
|
-
let boostSum = 0;
|
|
498
|
-
for (const contributor of contributors) {
|
|
499
|
-
if (!contributor.appliesTo(item, ctx))
|
|
500
|
-
continue;
|
|
501
|
-
const cappedBefore = Math.min(boostSum, MAX_BOOST_SUM);
|
|
502
|
-
boostSum += contributor.adjust(item, ctx);
|
|
503
|
-
// Attribution receives only the share admitted by the common boost cap,
|
|
504
|
-
// never a raw contributor value that scoring discarded.
|
|
505
|
-
contributor.applied?.(item, ctx, Math.min(boostSum, MAX_BOOST_SUM) - cappedBefore);
|
|
506
|
-
}
|
|
507
|
-
item.score *= 1 + Math.min(boostSum, MAX_BOOST_SUM);
|
|
508
|
-
}
|
|
509
|
-
export function applyUtilityContributors(item, ctx, contributors = defaultUtilityRankingContributors) {
|
|
510
|
-
for (const contributor of contributors) {
|
|
511
|
-
if (!contributor.appliesTo(item, ctx))
|
|
512
|
-
continue;
|
|
513
|
-
contributor.apply(item, ctx);
|
|
514
|
-
}
|
|
515
|
-
}
|