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
|
@@ -0,0 +1,124 @@
|
|
|
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
|
+
/**
|
|
5
|
+
* The single, keyed-on-ref implementation of "is this a derived memory?" and
|
|
6
|
+
* "which parent does it derive from?" (R12).
|
|
7
|
+
*
|
|
8
|
+
* Two divergent copies previously lived side by side — the CONSUMER
|
|
9
|
+
* (`memory-improve.ts`, keyed on the memory name) and the PRODUCER
|
|
10
|
+
* (`memory-contradiction-detect.ts`, keyed on the file path). The producer's
|
|
11
|
+
* copy was strictly narrower: it ignored `derivedFrom` entirely and matched
|
|
12
|
+
* `source:` through a separate parser. That let the producer and consumer
|
|
13
|
+
* disagree on a memory's parent — the exact defect plan §6 calls out
|
|
14
|
+
* ("producer/consumer cannot disagree").
|
|
15
|
+
*
|
|
16
|
+
* Both sides now share this one impl, keyed on the memory NAME (the stash-
|
|
17
|
+
* relative path without the `.md` extension, e.g. `nested/foo.derived`). The
|
|
18
|
+
* producer converts its file path to a name via `toMemoryRef` before calling
|
|
19
|
+
* in. Adopting it on the producer side is an INTENTIONAL widening, pinned by
|
|
20
|
+
* `tests/commands/improve/derived-ref.test.ts`:
|
|
21
|
+
* - `derivedFrom`-keyed families now resolve a parent (and so participate in
|
|
22
|
+
* contradiction detection); and
|
|
23
|
+
* - `source:` is parsed through `parseRefInput` so current bundle-qualified
|
|
24
|
+
* refs resolve consistently.
|
|
25
|
+
*
|
|
26
|
+
* Resolution order (source → derivedFrom → `.derived` suffix) matches the
|
|
27
|
+
* consumer's prior behaviour exactly, so the consumer side is a pure move.
|
|
28
|
+
*/
|
|
29
|
+
import { conceptIdFromTypeName, parseRefInput } from "../../../core/asset/resolve-ref.js";
|
|
30
|
+
import { asNonEmptyString } from "../../../core/common.js";
|
|
31
|
+
import { DERIVED_SUFFIX } from "../../../core/recognition-util.js";
|
|
32
|
+
/**
|
|
33
|
+
* Parse a belief edge (`supersededBy` / `contradictedBy` / `currentBeliefRefs`)
|
|
34
|
+
* to the bare memory name the identity channel keys on.
|
|
35
|
+
*
|
|
36
|
+
* Accepts BOTH spellings, because both reach this function:
|
|
37
|
+
* - `memory:<name>` — the internal identity spelling, and what belief edges
|
|
38
|
+
* written before 0.9.0 carry on disk;
|
|
39
|
+
* - `memories/<name>` / `<bundle>//memories/<name>` — the conceptId grammar
|
|
40
|
+
* the current writers emit (`akm remember --supersedes` and `akm import
|
|
41
|
+
* --supersedes` go through `writeSupersededEdge` with the write result's
|
|
42
|
+
* `ref`, which is fully qualified).
|
|
43
|
+
*
|
|
44
|
+
* Accepting only the first spelling silently reduced every edge written by the
|
|
45
|
+
* current code path to nothing, so a superseded memory read back as active.
|
|
46
|
+
* Both normalize to the bare name; the caller re-mints the internal
|
|
47
|
+
* `memory:<name>` form via {@link memoryIdentityRef}, so there is still exactly
|
|
48
|
+
* one identity spelling downstream.
|
|
49
|
+
*/
|
|
50
|
+
export function parseMemoryName(value) {
|
|
51
|
+
if (!value)
|
|
52
|
+
return undefined;
|
|
53
|
+
const trimmed = value.trim();
|
|
54
|
+
const MEMORY_PREFIX = "memory:";
|
|
55
|
+
if (trimmed.startsWith(MEMORY_PREFIX)) {
|
|
56
|
+
const name = trimmed.slice(MEMORY_PREFIX.length);
|
|
57
|
+
return name.length > 0 ? name : undefined;
|
|
58
|
+
}
|
|
59
|
+
try {
|
|
60
|
+
const parsed = parseRefInput(trimmed);
|
|
61
|
+
return parsed.type === "memory" && parsed.name.length > 0 ? parsed.name : undefined;
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Parse a current `source:` backref and return its canonical memory conceptId,
|
|
69
|
+
* or `undefined` when it is empty, invalid, or not a memory ref.
|
|
70
|
+
*/
|
|
71
|
+
export function parseMemoryRef(value) {
|
|
72
|
+
if (!value)
|
|
73
|
+
return undefined;
|
|
74
|
+
try {
|
|
75
|
+
const parsed = parseRefInput(value.trim());
|
|
76
|
+
return parsed.type === "memory" ? conceptIdFromTypeName("memory", parsed.name) : undefined;
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Format a bare memory name into the belief-edge IDENTITY channel ref
|
|
84
|
+
* `memory:<name>` — the ONE implementation of that spelling.
|
|
85
|
+
*
|
|
86
|
+
* Belief-edge / identity
|
|
87
|
+
* channel (`contradictedBy` / `supersededBy` / `currentBeliefRefs`, and a derived
|
|
88
|
+
* memory's own `record.ref`) uses `memory:<name>` and is compared against a
|
|
89
|
+
* derived memory's identity ref. This channel is separate from `source:` asset
|
|
90
|
+
* refs, which use `memories/<name>`. Both `memory-improve.ts` (`refArray`) and
|
|
91
|
+
* `memory-contradiction-detect.ts` (`toMemoryRef`) emit through here so the
|
|
92
|
+
* identity spelling has one implementation.
|
|
93
|
+
*/
|
|
94
|
+
export function memoryIdentityRef(name) {
|
|
95
|
+
return `memory:${name}`;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* True when the named memory is a derived/inferred child — either it carries
|
|
99
|
+
* `inferred: true` in its frontmatter or its name ends with the structural
|
|
100
|
+
* `.derived` suffix.
|
|
101
|
+
*/
|
|
102
|
+
export function isDerivedMemory(name, frontmatter) {
|
|
103
|
+
return frontmatter.inferred === true || name.endsWith(DERIVED_SUFFIX);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Resolve the parent (source) memory ref for a derived memory as a canonical
|
|
107
|
+
* `memories/<name>` conceptId, or `undefined` when none
|
|
108
|
+
* can be determined. Precedence:
|
|
109
|
+
* 1. `frontmatter.source` (normalised through {@link parseMemoryRef});
|
|
110
|
+
* 2. `frontmatter.derivedFrom` (a bare memory name → `memories/<name>`);
|
|
111
|
+
* 3. the `.derived` name suffix, stripped → `memories/<name>`.
|
|
112
|
+
*/
|
|
113
|
+
export function resolveParentRef(name, frontmatter) {
|
|
114
|
+
const fromSource = parseMemoryRef(asNonEmptyString(frontmatter.source));
|
|
115
|
+
if (fromSource)
|
|
116
|
+
return fromSource;
|
|
117
|
+
const derivedFrom = asNonEmptyString(frontmatter.derivedFrom);
|
|
118
|
+
if (derivedFrom)
|
|
119
|
+
return conceptIdFromTypeName("memory", derivedFrom);
|
|
120
|
+
if (name.endsWith(DERIVED_SUFFIX)) {
|
|
121
|
+
return conceptIdFromTypeName("memory", name.slice(0, -DERIVED_SUFFIX.length));
|
|
122
|
+
}
|
|
123
|
+
return undefined;
|
|
124
|
+
}
|
|
@@ -28,6 +28,25 @@
|
|
|
28
28
|
* - MemOS (arXiv:2507.03724) — formal archive/merge/transition with shared state model
|
|
29
29
|
*/
|
|
30
30
|
import { mutateFrontmatter } from "../../../core/asset/frontmatter.js";
|
|
31
|
+
// ── Shared edge-list reader ───────────────────────────────────────────────────
|
|
32
|
+
/**
|
|
33
|
+
* Read a frontmatter edge value (`supersededBy` / `contradictedBy`) as a
|
|
34
|
+
* string list, promoting a scalar string to a one-element list.
|
|
35
|
+
*
|
|
36
|
+
* Scalar edges are LIVE data: the indexer's `normalizeNonEmptyStringList`
|
|
37
|
+
* accepts them and lint deliberately never flags them. An Array.isArray-only
|
|
38
|
+
* read treats a scalar as "no existing edges" and silently destroys the edge
|
|
39
|
+
* on the next merge — mirror `mergeXrefsIntoContent`'s scalar promotion
|
|
40
|
+
* instead.
|
|
41
|
+
*/
|
|
42
|
+
function readEdgeList(value) {
|
|
43
|
+
if (Array.isArray(value)) {
|
|
44
|
+
return value.filter((v) => typeof v === "string" && v.trim().length > 0);
|
|
45
|
+
}
|
|
46
|
+
if (typeof value === "string" && value.trim())
|
|
47
|
+
return [value.trim()];
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
31
50
|
// ── Contradiction edge writer ─────────────────────────────────────────────────
|
|
32
51
|
/**
|
|
33
52
|
* Write `contradictedBy` and `beliefState: contradicted` edges to a memory
|
|
@@ -38,24 +57,77 @@ import { mutateFrontmatter } from "../../../core/asset/frontmatter.js";
|
|
|
38
57
|
* - `memory-contradiction-detect.ts` for the M-1 automated contradiction pass
|
|
39
58
|
* - `resolveFamilyContradictions` in `memory-improve.ts` for SCC resolution
|
|
40
59
|
*
|
|
41
|
-
* Idempotent: if the `contradictedByRef` is already in `contradictedBy
|
|
42
|
-
* the file is not rewritten.
|
|
60
|
+
* Idempotent: if the `contradictedByRef` is already in `contradictedBy` AND
|
|
61
|
+
* the file already carries the demotion state, the file is not rewritten. The
|
|
62
|
+
* guard is state-aware like its sibling {@link writeSupersededEdge}: an edge
|
|
63
|
+
* present WITHOUT the demotion (e.g. a hand-written `contradictedBy:` line,
|
|
64
|
+
* or a beliefState lost to a partial edit) is repaired, not skipped — an
|
|
65
|
+
* edge-only guard would make such a file a permanent no-op while
|
|
66
|
+
* contradiction writers report the contradiction as applied.
|
|
67
|
+
*
|
|
68
|
+
* Never weakens a stronger demotion: `archived` ranks BELOW `contradicted`
|
|
69
|
+
* (see `BELIEF_STATE_SCORE_CEILINGS` in
|
|
70
|
+
* src/indexer/search/ranking-contributors.ts), so contradicting an archived
|
|
71
|
+
* memory keeps `archived` and only appends the edge.
|
|
43
72
|
*
|
|
44
73
|
* @param filePath - Absolute path to the memory markdown file.
|
|
45
74
|
* @param contradictedByRef - The ref that contradicts this memory.
|
|
46
75
|
*/
|
|
47
76
|
export function writeContradictEdge(filePath, contradictedByRef) {
|
|
48
77
|
mutateFrontmatter(filePath, (parsed) => {
|
|
49
|
-
const existing =
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
if (existing.includes(contradictedByRef))
|
|
78
|
+
const existing = readEdgeList(parsed.data.contradictedBy);
|
|
79
|
+
const currentState = parsed.data.beliefState;
|
|
80
|
+
const nextState = currentState === "archived" ? currentState : "contradicted";
|
|
81
|
+
if (existing.includes(contradictedByRef) && currentState === nextState) {
|
|
53
82
|
return null; // Already written — idempotent.
|
|
83
|
+
}
|
|
54
84
|
const nextContradictedBy = [...new Set([...existing, contradictedByRef])].sort();
|
|
55
85
|
return {
|
|
56
86
|
...parsed.data,
|
|
57
87
|
contradictedBy: nextContradictedBy,
|
|
58
|
-
beliefState:
|
|
88
|
+
beliefState: nextState,
|
|
89
|
+
};
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
// ── Supersession edge writer ─────────────────────────────────────────────────
|
|
93
|
+
/**
|
|
94
|
+
* Write `supersededBy` and `beliefState: superseded` edges to an asset file's
|
|
95
|
+
* frontmatter (SPEC-5, stash-conventions-code-spec.md).
|
|
96
|
+
*
|
|
97
|
+
* Sibling of {@link writeContradictEdge}: the shared primitive for the
|
|
98
|
+
* conventions' corrections pattern — when a new asset supersedes an old one,
|
|
99
|
+
* the old asset gets a METADATA-ONLY demotion edit (every other frontmatter
|
|
100
|
+
* key and the body are preserved) so the ranker's beliefStateBoost demotes the
|
|
101
|
+
* stale incumbent and `--belief current` hides it. Used by
|
|
102
|
+
* `akm remember --supersedes` / `akm import --supersedes`.
|
|
103
|
+
*
|
|
104
|
+
* Idempotent: if `supersededByRef` is already in `supersededBy` and the file
|
|
105
|
+
* is already demoted, the file is not rewritten. Multiple corrections
|
|
106
|
+
* sorted-set-append their refs.
|
|
107
|
+
*
|
|
108
|
+
* Never WEAKENS an existing demotion: `contradicted` and `archived` rank
|
|
109
|
+
* BELOW `superseded` (severity order deprecated > superseded > contradicted >
|
|
110
|
+
* archived — see `BELIEF_STATE_SCORE_CEILINGS` in
|
|
111
|
+
* src/indexer/search/ranking-contributors.ts), so superseding an already
|
|
112
|
+
* contradicted/archived asset keeps the stronger state and only appends the
|
|
113
|
+
* `supersededBy` edge.
|
|
114
|
+
*
|
|
115
|
+
* @param filePath - Absolute path to the asset markdown file.
|
|
116
|
+
* @param supersededByRef - The ref of the correction that supersedes this asset.
|
|
117
|
+
*/
|
|
118
|
+
export function writeSupersededEdge(filePath, supersededByRef) {
|
|
119
|
+
mutateFrontmatter(filePath, (parsed) => {
|
|
120
|
+
const existing = readEdgeList(parsed.data.supersededBy);
|
|
121
|
+
const currentState = parsed.data.beliefState;
|
|
122
|
+
const nextState = currentState === "contradicted" || currentState === "archived" ? currentState : "superseded";
|
|
123
|
+
if (existing.includes(supersededByRef) && currentState === nextState) {
|
|
124
|
+
return null; // Already written — idempotent.
|
|
125
|
+
}
|
|
126
|
+
const nextSupersededBy = [...new Set([...existing, supersededByRef])].sort();
|
|
127
|
+
return {
|
|
128
|
+
...parsed.data,
|
|
129
|
+
supersededBy: nextSupersededBy,
|
|
130
|
+
beliefState: nextState,
|
|
59
131
|
};
|
|
60
132
|
});
|
|
61
133
|
}
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
*
|
|
23
23
|
* # LLM Feature Gate
|
|
24
24
|
*
|
|
25
|
-
* The pass is gated
|
|
25
|
+
* The pass is gated by the selected strategy's consolidate contradiction setting.
|
|
26
26
|
* When the gate is disabled or no LLM is configured,
|
|
27
27
|
* the pass is a no-op and `analyzeMemoryCleanup` proceeds with only manually
|
|
28
28
|
* annotated edges.
|
|
@@ -37,9 +37,12 @@ import fs from "node:fs";
|
|
|
37
37
|
import path from "node:path";
|
|
38
38
|
import contradictionJudgeTemplate from "../../../assets/prompts/contradiction-judge.md" with { type: "text" };
|
|
39
39
|
import { mutateFrontmatter, parseFrontmatter } from "../../../core/asset/frontmatter.js";
|
|
40
|
-
import {
|
|
41
|
-
import {
|
|
42
|
-
import {
|
|
40
|
+
import { parseEmbeddedJsonResponse } from "../../../core/parse.js";
|
|
41
|
+
import { getDefaultLlmConfig } from "../../../integrations/agent/engine-resolution.js";
|
|
42
|
+
import { materializeLlmRunnerConnection, resolveImproveProcessRunner } from "../../../integrations/agent/runner.js";
|
|
43
|
+
import { chatCompletion } from "../../../llm/client.js";
|
|
44
|
+
import { callStructured } from "../../../llm/structured-call.js";
|
|
45
|
+
import { isDerivedMemory, memoryIdentityRef, resolveParentRef } from "./derived-ref.js";
|
|
43
46
|
// ── Constants ────────────────────────────────────────────────────────────────
|
|
44
47
|
/**
|
|
45
48
|
* Maximum family size for pairwise contradiction checking. Families larger
|
|
@@ -54,8 +57,7 @@ const MAX_PAIRS_PER_RUN = 20;
|
|
|
54
57
|
/**
|
|
55
58
|
* Minimum confidence required to write a contradiction edge. Below this
|
|
56
59
|
* threshold the LLM may be flagging topic-overlap rather than genuine logical
|
|
57
|
-
* exclusivity (investigation 2026-06-18).
|
|
58
|
-
* 1.0 for backward compatibility with older judge responses.
|
|
60
|
+
* exclusivity (investigation 2026-06-18).
|
|
59
61
|
*/
|
|
60
62
|
const CONTRADICT_CONFIDENCE_THRESHOLD = 0.92;
|
|
61
63
|
/**
|
|
@@ -85,37 +87,17 @@ function* walkMarkdownFilesLocal(root) {
|
|
|
85
87
|
yield full;
|
|
86
88
|
}
|
|
87
89
|
}
|
|
90
|
+
// Build the derived memory's own belief-edge IDENTITY ref from its file path.
|
|
91
|
+
// Emits through the shared {@link memoryIdentityRef} so this — the former THIRD
|
|
92
|
+
// hand-rolled copy of the identity-channel spelling — no longer diverges from
|
|
93
|
+
// memory-improve's `refArray` (ref-grammar decision D-R3 identity-channel
|
|
94
|
+
// exception, documented at `memoryIdentityRef`).
|
|
88
95
|
function toMemoryRef(memoriesDir, filePath) {
|
|
89
96
|
const rel = path.relative(memoriesDir, filePath);
|
|
90
97
|
if (!rel || rel.startsWith(".."))
|
|
91
98
|
return undefined;
|
|
92
99
|
const name = rel.replace(/\\/g, "/").replace(/\.md$/i, "");
|
|
93
|
-
return
|
|
94
|
-
}
|
|
95
|
-
function isDerivedMemory(filePath, frontmatter) {
|
|
96
|
-
// Name-based guard (M-2): the .derived suffix is structural and immutable.
|
|
97
|
-
const base = path.basename(filePath, ".md");
|
|
98
|
-
if (base.endsWith(".derived"))
|
|
99
|
-
return true;
|
|
100
|
-
// Frontmatter-based guard: inferred: true marks explicit child memories.
|
|
101
|
-
return frontmatter.inferred === true;
|
|
102
|
-
}
|
|
103
|
-
function resolveParentRef(filePath, frontmatter, memoriesRootDir) {
|
|
104
|
-
// Prefer the explicit source: frontmatter.
|
|
105
|
-
const source = frontmatter.source;
|
|
106
|
-
if (typeof source === "string" && source.startsWith("memory:"))
|
|
107
|
-
return source;
|
|
108
|
-
// Fall back to deriving parent from the file name (strip .derived suffix).
|
|
109
|
-
const base = path.basename(filePath, ".md");
|
|
110
|
-
if (base.endsWith(".derived")) {
|
|
111
|
-
const parentName = base.slice(0, -".derived".length);
|
|
112
|
-
// Use the stash memories root so nested paths (e.g. memories/nested/foo.derived.md)
|
|
113
|
-
// resolve to the correct relative ref (memory:nested/foo, not memory:foo).
|
|
114
|
-
const rootDir = memoriesRootDir ?? path.dirname(filePath);
|
|
115
|
-
const rel = path.relative(rootDir, path.join(path.dirname(filePath), parentName));
|
|
116
|
-
return `memory:${rel.replace(/\\/g, "/")}`;
|
|
117
|
-
}
|
|
118
|
-
return undefined;
|
|
100
|
+
return memoryIdentityRef(name);
|
|
119
101
|
}
|
|
120
102
|
// ── Edge writing ─────────────────────────────────────────────────────────────
|
|
121
103
|
/**
|
|
@@ -173,14 +155,20 @@ function pickContradictionLoser(a, b) {
|
|
|
173
155
|
* @param config - Loaded AKM config (used to access LLM settings).
|
|
174
156
|
* @param chat - Optional chat seam for testing (defaults to chatCompletion).
|
|
175
157
|
*/
|
|
176
|
-
export async function detectAndWriteContradictions(stashDir, config, chat = chatCompletion) {
|
|
158
|
+
export async function detectAndWriteContradictions(stashDir, config, chat = chatCompletion, strategy, resolvedLlmConfig) {
|
|
177
159
|
const result = {
|
|
178
160
|
familiesExamined: 0,
|
|
179
161
|
pairsChecked: 0,
|
|
180
162
|
edgesWritten: 0,
|
|
181
163
|
warnings: [],
|
|
182
164
|
};
|
|
183
|
-
const contradictionLlm =
|
|
165
|
+
const contradictionLlm = resolvedLlmConfig === null
|
|
166
|
+
? undefined
|
|
167
|
+
: (resolvedLlmConfig ??
|
|
168
|
+
(() => {
|
|
169
|
+
const runner = resolveImproveProcessRunner(strategy, "consolidate", config);
|
|
170
|
+
return runner ? materializeLlmRunnerConnection(runner) : getDefaultLlmConfig(config);
|
|
171
|
+
})());
|
|
184
172
|
if (!contradictionLlm)
|
|
185
173
|
return result;
|
|
186
174
|
// Collect derived memories grouped by parent.
|
|
@@ -195,14 +183,20 @@ export async function detectAndWriteContradictions(stashDir, config, chat = chat
|
|
|
195
183
|
continue;
|
|
196
184
|
}
|
|
197
185
|
const parsed = parseFrontmatter(raw);
|
|
198
|
-
if (!isDerivedMemory(filePath, parsed.data))
|
|
199
|
-
continue;
|
|
200
|
-
const parentRef = resolveParentRef(filePath, parsed.data, memoriesDir);
|
|
201
|
-
if (!parentRef)
|
|
202
|
-
continue;
|
|
203
186
|
const ref = toMemoryRef(memoriesDir, filePath);
|
|
204
187
|
if (!ref)
|
|
205
188
|
continue;
|
|
189
|
+
// Key the shared derived-ref helpers on the memory NAME (stash-relative, no
|
|
190
|
+
// extension) — the same key the consumer uses — so producer and consumer
|
|
191
|
+
// resolve the identical parent (R12). This intentionally widens the producer
|
|
192
|
+
// to honour `derivedFrom` and normalised `source:` values it previously
|
|
193
|
+
// dropped (pinned by derived-ref.test.ts).
|
|
194
|
+
const name = ref.slice("memory:".length);
|
|
195
|
+
if (!isDerivedMemory(name, parsed.data))
|
|
196
|
+
continue;
|
|
197
|
+
const parentRef = resolveParentRef(name, parsed.data);
|
|
198
|
+
if (!parentRef)
|
|
199
|
+
continue;
|
|
206
200
|
const entry = {
|
|
207
201
|
filePath,
|
|
208
202
|
ref,
|
|
@@ -236,11 +230,6 @@ export async function detectAndWriteContradictions(stashDir, config, chat = chat
|
|
|
236
230
|
// edge already exists (no new information; avoids re-judging resolved
|
|
237
231
|
// pairs across runs).
|
|
238
232
|
//
|
|
239
|
-
// Legacy mutual A↔B edges written by the pre-fix pass self-heal: the
|
|
240
|
-
// skip fires this run, but the SCC resolver treats the 2-cycle as a sink
|
|
241
|
-
// and refreshes both to active — DELETING both `contradictedBy` arrays
|
|
242
|
-
// (memory-improve.ts persistBeliefStateTransition). The next detection
|
|
243
|
-
// run then sees no edge, re-judges, and writes the single canonical edge.
|
|
244
233
|
const aParsed = parseFrontmatter(fs.readFileSync(a.filePath, "utf8"));
|
|
245
234
|
const bParsed = parseFrontmatter(fs.readFileSync(b.filePath, "utf8"));
|
|
246
235
|
const { loser, winnerRef } = pickContradictionLoser(a, b);
|
|
@@ -249,12 +238,23 @@ export async function detectAndWriteContradictions(stashDir, config, chat = chat
|
|
|
249
238
|
if (loserCB.includes(winnerRef))
|
|
250
239
|
continue;
|
|
251
240
|
const prompt = buildContradictionJudgePrompt(a, b);
|
|
252
|
-
const judgeResult = await
|
|
253
|
-
|
|
241
|
+
const judgeResult = await callStructured({
|
|
242
|
+
feature: "memory_contradiction_detection",
|
|
243
|
+
akmConfig: config,
|
|
244
|
+
// Resolver-less key: the strategy decision IS the gate (default-off).
|
|
245
|
+
enabled: strategy?.processes?.consolidate?.contradictionDetection?.enabled ?? false,
|
|
246
|
+
config: contradictionLlm,
|
|
247
|
+
messages: [
|
|
254
248
|
{ role: "system", content: "Return only valid JSON. No prose." },
|
|
255
249
|
{ role: "user", content: prompt },
|
|
256
|
-
]
|
|
257
|
-
|
|
250
|
+
],
|
|
251
|
+
request: { chat },
|
|
252
|
+
parse: (raw) => raw ?? null,
|
|
253
|
+
// A transport throw used to escape the gated fn into the gate's
|
|
254
|
+
// catch and take the null fallback ("skip"); onError reproduces it.
|
|
255
|
+
onError: () => null,
|
|
256
|
+
fallback: null, // null means "skip" — gate disabled or LLM call failed.
|
|
257
|
+
});
|
|
258
258
|
totalPairsChecked++;
|
|
259
259
|
result.pairsChecked++;
|
|
260
260
|
if (!judgeResult)
|
|
@@ -269,10 +269,7 @@ export async function detectAndWriteContradictions(stashDir, config, chat = chat
|
|
|
269
269
|
}
|
|
270
270
|
if (!parsed?.contradicts)
|
|
271
271
|
continue;
|
|
272
|
-
|
|
273
|
-
// pre-confidence responses). Do NOT default to 0 — that would silently
|
|
274
|
-
// disable all detection during the rollout period.
|
|
275
|
-
const confidence = typeof parsed.confidence === "number" ? parsed.confidence : 1.0;
|
|
272
|
+
const confidence = typeof parsed.confidence === "number" ? parsed.confidence : 0;
|
|
276
273
|
if (confidence < CONTRADICT_CONFIDENCE_THRESHOLD) {
|
|
277
274
|
result.warnings.push(`Pair ${a.ref} / ${b.ref}: confidence ${confidence.toFixed(2)} below ${CONTRADICT_CONFIDENCE_THRESHOLD} threshold — skipped.`);
|
|
278
275
|
continue;
|
|
@@ -3,11 +3,12 @@
|
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
4
|
import fs from "node:fs";
|
|
5
5
|
import path from "node:path";
|
|
6
|
-
import { makeAssetRef, parseAssetRef } from "../../../core/asset/asset-ref.js";
|
|
7
6
|
import { assembleAsset } from "../../../core/asset/asset-serialize.js";
|
|
8
7
|
import { mutateFrontmatter, parseFrontmatter } from "../../../core/asset/frontmatter.js";
|
|
8
|
+
import { conceptIdFromTypeName } from "../../../core/asset/resolve-ref.js";
|
|
9
9
|
import { asNonEmptyString, groupBy, stringArray } from "../../../core/common.js";
|
|
10
|
-
|
|
10
|
+
import { DERIVED_SUFFIX } from "../../../core/recognition-util.js";
|
|
11
|
+
import { isDerivedMemory, memoryIdentityRef, parseMemoryName, resolveParentRef } from "./derived-ref.js";
|
|
11
12
|
export function analyzeMemoryCleanup(stashDir, options = {}) {
|
|
12
13
|
const records = collectDerivedMemories(stashDir, options.parentRef);
|
|
13
14
|
const byRef = new Map(records.map((record) => [record.ref, record]));
|
|
@@ -87,6 +88,8 @@ export function analyzeMemoryCleanup(stashDir, options = {}) {
|
|
|
87
88
|
if (duplicates.length < 2)
|
|
88
89
|
continue;
|
|
89
90
|
const [survivor, ...rest] = sortRecordsForSurvival(duplicates);
|
|
91
|
+
if (survivor === undefined)
|
|
92
|
+
continue;
|
|
90
93
|
for (const duplicate of rest) {
|
|
91
94
|
planPrune(duplicate, "duplicate-derived", survivor.ref);
|
|
92
95
|
}
|
|
@@ -587,7 +590,7 @@ function collectDerivedMemories(stashDir, parentRefFilter) {
|
|
|
587
590
|
const body = parsed.content.trim();
|
|
588
591
|
const signalKey = normalizeSignal(firstNonEmpty([title, description, searchHints[0]]));
|
|
589
592
|
records.push({
|
|
590
|
-
ref:
|
|
593
|
+
ref: `memory:${name}`,
|
|
591
594
|
name,
|
|
592
595
|
filePath,
|
|
593
596
|
parentRef,
|
|
@@ -596,7 +599,11 @@ function collectDerivedMemories(stashDir, parentRefFilter) {
|
|
|
596
599
|
tags,
|
|
597
600
|
searchHints,
|
|
598
601
|
body,
|
|
599
|
-
|
|
602
|
+
// parentRef is the 0.9.0 `memories/<name>` conceptId (Group-C item 2), so
|
|
603
|
+
// the canonical-child test compares the minted conceptId of the suffix-
|
|
604
|
+
// stripped name against it rather than slicing a fixed `memory:` prefix.
|
|
605
|
+
canonicalName: name.endsWith(DERIVED_SUFFIX) &&
|
|
606
|
+
parentRef === conceptIdFromTypeName("memory", name.slice(0, -DERIVED_SUFFIX.length)),
|
|
600
607
|
signalScore: computeSignalScore(title, description, tags, searchHints, body),
|
|
601
608
|
fingerprint: buildFingerprint(title, description, tags, searchHints, body),
|
|
602
609
|
...(signalKey ? { signalKey } : {}),
|
|
@@ -647,25 +654,19 @@ function resolveBeliefState(frontmatter) {
|
|
|
647
654
|
}
|
|
648
655
|
return "active";
|
|
649
656
|
}
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
return makeAssetRef("memory", derivedFrom);
|
|
660
|
-
if (name.endsWith(DERIVED_SUFFIX)) {
|
|
661
|
-
return makeAssetRef("memory", name.slice(0, -DERIVED_SUFFIX.length));
|
|
662
|
-
}
|
|
663
|
-
return undefined;
|
|
664
|
-
}
|
|
657
|
+
// Belief-edge refs (contradictedBy / supersededBy / currentBeliefRefs) are the
|
|
658
|
+
// IDENTITY channel: they are compared against a derived memory's own
|
|
659
|
+
// `memory:<name>` ref (resolveFamilyContradictions' familyRefSet,
|
|
660
|
+
// firstExistingRef's byRef map), so they are NORMALIZED to `memory:<name>` here.
|
|
661
|
+
// On disk they arrive in either spelling — `memory:<name>` from pre-0.9.0
|
|
662
|
+
// writes, or the `[<bundle>//]memories/<name>` conceptId that
|
|
663
|
+
// `writeSupersededEdge`/`writeContradictEdge` persist today — and
|
|
664
|
+
// `parseMemoryName` accepts both. Reading only the first spelling silently
|
|
665
|
+
// dropped every edge the current write path produces.
|
|
665
666
|
function refArray(value) {
|
|
666
667
|
if (typeof value === "string") {
|
|
667
|
-
const
|
|
668
|
-
return
|
|
668
|
+
const name = parseMemoryName(value);
|
|
669
|
+
return name === undefined ? [] : [memoryIdentityRef(name)];
|
|
669
670
|
}
|
|
670
671
|
if (!Array.isArray(value))
|
|
671
672
|
return [];
|
|
@@ -673,25 +674,12 @@ function refArray(value) {
|
|
|
673
674
|
for (const item of value) {
|
|
674
675
|
if (typeof item !== "string")
|
|
675
676
|
continue;
|
|
676
|
-
const
|
|
677
|
-
if (
|
|
678
|
-
refs.add(
|
|
677
|
+
const name = parseMemoryName(item);
|
|
678
|
+
if (name !== undefined)
|
|
679
|
+
refs.add(memoryIdentityRef(name));
|
|
679
680
|
}
|
|
680
681
|
return [...refs].sort();
|
|
681
682
|
}
|
|
682
|
-
function parseMemoryRef(value) {
|
|
683
|
-
if (!value)
|
|
684
|
-
return undefined;
|
|
685
|
-
try {
|
|
686
|
-
const parsed = parseAssetRef(value.trim());
|
|
687
|
-
if (parsed.type !== "memory")
|
|
688
|
-
return undefined;
|
|
689
|
-
return makeAssetRef(parsed.type, parsed.name);
|
|
690
|
-
}
|
|
691
|
-
catch {
|
|
692
|
-
return undefined;
|
|
693
|
-
}
|
|
694
|
-
}
|
|
695
683
|
function buildFingerprint(title, description, tags, searchHints, body) {
|
|
696
684
|
return JSON.stringify({
|
|
697
685
|
title: normalizeSignal(title),
|