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
package/dist/commands/health.js
CHANGED
|
@@ -7,8 +7,9 @@ import { resolveStashDir } from "../core/common.js";
|
|
|
7
7
|
import { loadConfig } from "../core/config/config.js";
|
|
8
8
|
import { ConfigError, UsageError } from "../core/errors.js";
|
|
9
9
|
import { readEvents } from "../core/events.js";
|
|
10
|
+
import { listTxnJournalsTolerant, TXN_SWEEP_GRACE_MS } from "../core/fs-txn.js";
|
|
10
11
|
import { openLogsDatabase } from "../core/logs-db.js";
|
|
11
|
-
import { getCacheDir,
|
|
12
|
+
import { getCacheDir, getConfigPath, getDataDir, getStateDbPathInDataDir } from "../core/paths.js";
|
|
12
13
|
import { listExistingTableNames, openStateDatabase } from "../core/state-db.js";
|
|
13
14
|
import { DURATION_UNITS, parseDuration, parseSinceToIso } from "../core/time.js";
|
|
14
15
|
import { readSemanticStatus } from "../indexer/search/semantic-status.js";
|
|
@@ -18,11 +19,11 @@ import { collectImproveAdvisories } from "./health/advisories.js";
|
|
|
18
19
|
import { HEALTH_CHECKS } from "./health/checks.js";
|
|
19
20
|
import { buildImproveSkipSummary, computeWallTimeStats, parseTaskMetadata, roundRate, summarizeImproveCompleted, summarizeImproveRuns, } from "./health/improve-metrics.js";
|
|
20
21
|
import { readLlmUsageAggregate } from "./health/llm-usage.js";
|
|
21
|
-
import { computeDegradationMetrics, computeDenominatorFixedCoverage, computeEnrichmentMintingRollup, probeStateDbRoundTrip,
|
|
22
|
+
import { computeDegradationMetrics, computeDenominatorFixedCoverage, computeEnrichmentMintingRollup, probeStateDbRoundTrip, } from "./health/metrics.js";
|
|
22
23
|
import { collectStashExposureAdvisory } from "./health/stash-exposure.js";
|
|
23
24
|
import { collectSurfacesAdvisories } from "./health/surfaces.js";
|
|
24
25
|
import { buildPerRunSummaries } from "./health/task-runs.js";
|
|
25
|
-
import { ACTIVE_RUN_WARN_MS, IMPROVE_COMPLETED_EVENT, } from "./health/types.js";
|
|
26
|
+
import { ACTIVE_RUN_WARN_MS, IMPROVE_COMPLETED_EVENT, MIN_ROWS_FOR_WORST_TASK_FAIL_RATE, } from "./health/types.js";
|
|
26
27
|
import { buildWindowMetrics, computeDeltas, partitionLogBackedRows, resolveWindowCompare } from "./health/windows.js";
|
|
27
28
|
const DEFAULT_SINCE_MS = 24 * 60 * 60 * 1000;
|
|
28
29
|
export function parseHealthSince(since) {
|
|
@@ -60,6 +61,273 @@ function validateAkmHealthOptions(options) {
|
|
|
60
61
|
}
|
|
61
62
|
}
|
|
62
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* Item 7: dedupe stuck-active rows by task_id (keeping the oldest/largest age
|
|
66
|
+
* per id) so the `active-runs` check can name WHICH tasks are stuck instead of
|
|
67
|
+
* just a count. No pid/liveness probing — purely a projection of the rows
|
|
68
|
+
* already read.
|
|
69
|
+
*/
|
|
70
|
+
function dedupeStuckActiveTasks(rows, now) {
|
|
71
|
+
const byTask = new Map();
|
|
72
|
+
for (const row of rows) {
|
|
73
|
+
const ageMs = now() - new Date(row.started_at).getTime();
|
|
74
|
+
const existing = byTask.get(row.task_id);
|
|
75
|
+
if (existing === undefined || ageMs > existing)
|
|
76
|
+
byTask.set(row.task_id, ageMs);
|
|
77
|
+
}
|
|
78
|
+
return [...byTask.entries()].map(([taskId, ageMs]) => ({ taskId, ageMs }));
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Item 6: group task_history rows by task_id and return the one with the
|
|
82
|
+
* highest fail rate among tasks with at least MIN_ROWS_FOR_WORST_TASK_FAIL_RATE
|
|
83
|
+
* rows in the window — surfaces a consistently-failing task that a large,
|
|
84
|
+
* mostly-healthy population would otherwise hide behind the aggregate rate.
|
|
85
|
+
* `null` when no task_id meets the row-count floor. Ties break toward the
|
|
86
|
+
* task with more rows (a stronger signal), then by task_id for determinism.
|
|
87
|
+
*/
|
|
88
|
+
function computeWorstTaskFailRate(rows) {
|
|
89
|
+
const byTask = new Map();
|
|
90
|
+
for (const row of rows) {
|
|
91
|
+
const entry = byTask.get(row.task_id) ?? { total: 0, failed: 0 };
|
|
92
|
+
entry.total += 1;
|
|
93
|
+
if (row.status === "failed")
|
|
94
|
+
entry.failed += 1;
|
|
95
|
+
byTask.set(row.task_id, entry);
|
|
96
|
+
}
|
|
97
|
+
let worst = null;
|
|
98
|
+
for (const [taskId, { total, failed }] of byTask) {
|
|
99
|
+
if (total < MIN_ROWS_FOR_WORST_TASK_FAIL_RATE)
|
|
100
|
+
continue;
|
|
101
|
+
const rate = failed / total;
|
|
102
|
+
if (worst === null ||
|
|
103
|
+
rate > worst.rate ||
|
|
104
|
+
(rate === worst.rate && (total > worst.rows || (total === worst.rows && taskId < worst.taskId)))) {
|
|
105
|
+
worst = { taskId, rate, rows: total };
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return worst;
|
|
109
|
+
}
|
|
110
|
+
/** Table presence, the state.db round-trip probe, and task_history-derived rates. */
|
|
111
|
+
function gatherTaskHistoryPhase(db, logsDb, since, stateDbPath, now) {
|
|
112
|
+
const tables = listExistingTableNames(db, ["events", "task_history", "proposals", "schema_migrations"]);
|
|
113
|
+
const tableNames = tables.map((row) => row.name).sort();
|
|
114
|
+
const requiredTables = ["events", "proposals", "schema_migrations", "task_history"];
|
|
115
|
+
const missingTables = requiredTables.filter((name) => !tableNames.includes(name));
|
|
116
|
+
const probe = probeStateDbRoundTrip(stateDbPath);
|
|
117
|
+
const taskRows = queryTaskHistory(db, { since });
|
|
118
|
+
const { withLogs: taskRowsWithLogs, backed: existingLogRows } = partitionLogBackedRows(taskRows, logsDb);
|
|
119
|
+
const failedTaskRows = taskRows.filter((row) => row.status === "failed");
|
|
120
|
+
const activeRows = taskRows.filter((row) => row.status === "active" && row.completed_at === null);
|
|
121
|
+
const stuckActiveRows = activeRows.filter((row) => now() - new Date(row.started_at).getTime() > ACTIVE_RUN_WARN_MS);
|
|
122
|
+
const promptRows = taskRows.filter((row) => row.target_kind === "prompt");
|
|
123
|
+
const promptFailures = promptRows.filter((row) => {
|
|
124
|
+
const detail = parseTaskMetadata(row).detail;
|
|
125
|
+
return typeof detail?.reason === "string" && detail.reason.length > 0;
|
|
126
|
+
});
|
|
127
|
+
const logBackingRate = taskRowsWithLogs.length === 0 ? 1 : existingLogRows.length / taskRowsWithLogs.length;
|
|
128
|
+
const taskFailRate = taskRows.length === 0 ? 0 : failedTaskRows.length / taskRows.length;
|
|
129
|
+
const agentFailureRate = promptRows.length === 0 ? 0 : promptFailures.length / promptRows.length;
|
|
130
|
+
return {
|
|
131
|
+
tableNames,
|
|
132
|
+
missingTables,
|
|
133
|
+
probe,
|
|
134
|
+
taskRowCount: taskRows.length,
|
|
135
|
+
taskRowsWithLogsCount: taskRowsWithLogs.length,
|
|
136
|
+
existingLogRowsCount: existingLogRows.length,
|
|
137
|
+
stuckActiveRuns: stuckActiveRows.length,
|
|
138
|
+
stuckActiveTasks: dedupeStuckActiveTasks(stuckActiveRows, now),
|
|
139
|
+
logBackingRate,
|
|
140
|
+
taskFailRate,
|
|
141
|
+
worstTaskFailRate: computeWorstTaskFailRate(taskRows),
|
|
142
|
+
agentFailureRate,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Item 4: leftover durable-transaction journals under `$DATA/txn` (stranded
|
|
147
|
+
* recovery state seen twice in a real 0.9 migration) had zero health
|
|
148
|
+
* visibility. Uses the tolerant scan variant so one corrupt journal.json is
|
|
149
|
+
* counted rather than aborting the whole gather; a journal younger than
|
|
150
|
+
* {@link TXN_SWEEP_GRACE_MS} is presumed to belong to a currently-running
|
|
151
|
+
* operation and is not counted as stale. Best-effort: any unexpected error
|
|
152
|
+
* (e.g. a permissions issue under `$DATA/txn`) degrades to "no signal" rather
|
|
153
|
+
* than aborting the health report.
|
|
154
|
+
*/
|
|
155
|
+
function gatherStaleTxnJournalsPhase(now) {
|
|
156
|
+
const dir = path.join(getDataDir(), "txn");
|
|
157
|
+
try {
|
|
158
|
+
const { matches, unreadableMtimes } = listTxnJournalsTolerant(() => true);
|
|
159
|
+
const nowMs = now();
|
|
160
|
+
const staleAges = [
|
|
161
|
+
...matches.map((m) => nowMs - m.mtimeMs),
|
|
162
|
+
...unreadableMtimes.map((mtimeMs) => nowMs - mtimeMs),
|
|
163
|
+
].filter((ageMs) => ageMs >= TXN_SWEEP_GRACE_MS);
|
|
164
|
+
const staleUnreadableCount = unreadableMtimes.filter((mtimeMs) => nowMs - mtimeMs >= TXN_SWEEP_GRACE_MS).length;
|
|
165
|
+
return {
|
|
166
|
+
dir,
|
|
167
|
+
count: staleAges.length,
|
|
168
|
+
oldestAgeMs: staleAges.length > 0 ? Math.max(...staleAges) : null,
|
|
169
|
+
unreadable: staleUnreadableCount,
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
return { dir, count: 0, oldestAgeMs: null, unreadable: 0 };
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Semantic-search status + the config fields the embedding-endpoint and
|
|
178
|
+
* surfaces advisories need. Best-effort: an unloadable config leaves the
|
|
179
|
+
* config-derived fields undefined and callers fall back to generic messages.
|
|
180
|
+
*/
|
|
181
|
+
function gatherSemanticConfigPhase() {
|
|
182
|
+
const semanticStatus = readSemanticStatus();
|
|
183
|
+
let semanticSearchMode;
|
|
184
|
+
let embeddingEndpoint;
|
|
185
|
+
let egressConfigView;
|
|
186
|
+
try {
|
|
187
|
+
const config = loadConfig();
|
|
188
|
+
semanticSearchMode = config.semanticSearchMode;
|
|
189
|
+
embeddingEndpoint = config.embedding?.endpoint;
|
|
190
|
+
egressConfigView = config;
|
|
191
|
+
}
|
|
192
|
+
catch {
|
|
193
|
+
// fall through with undefined
|
|
194
|
+
}
|
|
195
|
+
return { semanticStatus, semanticSearchMode, embeddingEndpoint, egressConfigView };
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Assemble the window's improve-pipeline summary: invoked/completed/skipped
|
|
199
|
+
* counts from events, the per-run result_json aggregate, wall-time stats, and
|
|
200
|
+
* the WS-5 coverage/degradation/enrichment-minting rollups.
|
|
201
|
+
*/
|
|
202
|
+
function gatherImproveSummaryPhase(db, stateDbPath, since, now) {
|
|
203
|
+
const improveInvoked = readEvents({ since, type: "improve_invoked" }, { dbPath: stateDbPath }).events.length;
|
|
204
|
+
const improveCompletedEvents = readEvents({ since, type: IMPROVE_COMPLETED_EVENT }, { dbPath: stateDbPath }).events;
|
|
205
|
+
const improveSkippedEvents = readEvents({ since, type: "improve_skipped" }, { dbPath: stateDbPath }).events;
|
|
206
|
+
const eventsMetrics = summarizeImproveCompleted(improveCompletedEvents);
|
|
207
|
+
const { metrics: improveSummary } = summarizeImproveRuns(db, since);
|
|
208
|
+
improveSummary.invoked = improveInvoked;
|
|
209
|
+
improveSummary.completed = eventsMetrics.completed;
|
|
210
|
+
const skipSummary = buildImproveSkipSummary(improveSkippedEvents);
|
|
211
|
+
improveSummary.skipped = skipSummary.skipped;
|
|
212
|
+
improveSummary.skipReasons = skipSummary.skipReasons;
|
|
213
|
+
const perRunSummaries = buildPerRunSummaries(db, since);
|
|
214
|
+
const wallTimes = perRunSummaries.map((run) => run.wallTimeMs).filter((ms) => Number.isFinite(ms) && ms > 0);
|
|
215
|
+
improveSummary.wallTime = computeWallTimeStats(wallTimes, improveSummary.wallTime.byPhase);
|
|
216
|
+
// WS-5: Compute denominator-fixed coverage and per-run degradation metrics
|
|
217
|
+
// for the main health path (not just window-compare mode).
|
|
218
|
+
const until = new Date(now()).toISOString();
|
|
219
|
+
const totalAssetsMain = improveSummary.memorySummary.eligible + improveSummary.memorySummary.derived;
|
|
220
|
+
improveSummary.coverage = computeDenominatorFixedCoverage(db, totalAssetsMain, improveSummary.memorySummary.eligible, since, until);
|
|
221
|
+
const degradationMain = computeDegradationMetrics(db, since, until);
|
|
222
|
+
if (degradationMain) {
|
|
223
|
+
improveSummary.degradation = degradationMain;
|
|
224
|
+
}
|
|
225
|
+
improveSummary.enrichmentMinting = computeEnrichmentMintingRollup(db, since, until);
|
|
226
|
+
return { improveSummary, perRunSummaries };
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* The three best-effort advisory groups beyond the health-check registry:
|
|
230
|
+
* improve advisories, the `stash-git-exposure` probe, and the 08 surfaces
|
|
231
|
+
* group (secret-file-perms, binary-config-skew, egress-endpoints). Order
|
|
232
|
+
* matches emission order in the returned array. A
|
|
233
|
+
* probe/filesystem failure in either try/catch must not abort the health
|
|
234
|
+
* report — each group degrades to "no advisory" independently.
|
|
235
|
+
*/
|
|
236
|
+
function gatherAncillaryAdvisories(db, stateDbPath, since, improveSummary, options, egressConfigView) {
|
|
237
|
+
const advisories = [...collectImproveAdvisories(db, stateDbPath, since, improveSummary)];
|
|
238
|
+
// 08-F1: surface a `stash-git-exposure` advisory when env/secret assets are
|
|
239
|
+
// git-tracked AND a remote is configured (the leak moment). Best-effort.
|
|
240
|
+
// Cheap guard: only shell out to git when the stash has its OWN `.git` (or a
|
|
241
|
+
// test injected a fake seam), so the hot path never spawns for a non-git
|
|
242
|
+
// stash — the common unit-test case. Trade-off: a stash manually pointed at a
|
|
243
|
+
// bare subdirectory of a parent git repo (no `.git` of its own) is not
|
|
244
|
+
// checked. akm-init always creates `.git` at the stash root, so any
|
|
245
|
+
// akm-initialised stash is covered; this only skips hand-pointed nested ones.
|
|
246
|
+
try {
|
|
247
|
+
const exposureStashDir = options.stashDir ?? resolveStashDir();
|
|
248
|
+
if (options.stashExposureGit || fs.existsSync(path.join(exposureStashDir, ".git"))) {
|
|
249
|
+
const stashExposure = collectStashExposureAdvisory(exposureStashDir, options.stashExposureGit);
|
|
250
|
+
if (stashExposure)
|
|
251
|
+
advisories.push(stashExposure);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
catch {
|
|
255
|
+
// Non-fatal — a git/probe failure must not abort the health report.
|
|
256
|
+
}
|
|
257
|
+
// 08 surfaces: the remaining read-only advisory group (secret-file-perms,
|
|
258
|
+
// binary-config-skew, egress-endpoints). Best-effort — a
|
|
259
|
+
// filesystem probe failure must not abort the health report.
|
|
260
|
+
try {
|
|
261
|
+
advisories.push(...collectSurfacesAdvisories({
|
|
262
|
+
stashDir: options.stashDir ?? resolveStashDir(),
|
|
263
|
+
cacheDir: getCacheDir(),
|
|
264
|
+
configPath: getConfigPath(),
|
|
265
|
+
config: egressConfigView,
|
|
266
|
+
}));
|
|
267
|
+
}
|
|
268
|
+
catch {
|
|
269
|
+
// Non-fatal.
|
|
270
|
+
}
|
|
271
|
+
return advisories;
|
|
272
|
+
}
|
|
273
|
+
/** Execution-log-derived session advisories. Best-effort: any failure yields an empty list. */
|
|
274
|
+
function gatherSessionLogAdvisories(since, now, getExecutionLogCandidatesFn) {
|
|
275
|
+
try {
|
|
276
|
+
const sinceDays = Math.max(0, Math.ceil((now() - new Date(since).getTime()) / (24 * 60 * 60 * 1000)));
|
|
277
|
+
return getExecutionLogCandidatesFn(sinceDays).map((entry) => ({
|
|
278
|
+
topic: entry.topic,
|
|
279
|
+
frequency: entry.frequency,
|
|
280
|
+
source: entry.source,
|
|
281
|
+
isFailurePattern: entry.isFailurePattern,
|
|
282
|
+
}));
|
|
283
|
+
}
|
|
284
|
+
catch {
|
|
285
|
+
return [];
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Phase 3 — window-compare mode. Resolves `--window-compare`/`--windows` into
|
|
290
|
+
* per-window bundles and computes deltas between the earliest and latest
|
|
291
|
+
* window. Top-level metrics retain the primary `--since` query.
|
|
292
|
+
*/
|
|
293
|
+
function resolveWindowComparePhase(options, db, stateDbPath, now, logsDb) {
|
|
294
|
+
let windowSpecs;
|
|
295
|
+
if (options.windowCompare) {
|
|
296
|
+
windowSpecs = resolveWindowCompare(options.windowCompare, now);
|
|
297
|
+
}
|
|
298
|
+
else if (options.windows && options.windows.length > 0) {
|
|
299
|
+
windowSpecs = options.windows;
|
|
300
|
+
}
|
|
301
|
+
let windowResults;
|
|
302
|
+
let deltas;
|
|
303
|
+
if (windowSpecs) {
|
|
304
|
+
windowResults = windowSpecs.map((spec) => {
|
|
305
|
+
const winSince = parseHealthSince(spec.since);
|
|
306
|
+
const winUntil = spec.until ? parseHealthSince(spec.until) : new Date(now()).toISOString();
|
|
307
|
+
const bundle = buildWindowMetrics(db, stateDbPath, winSince, winUntil, now, logsDb);
|
|
308
|
+
return {
|
|
309
|
+
name: spec.name,
|
|
310
|
+
since: winSince,
|
|
311
|
+
until: winUntil,
|
|
312
|
+
runs: bundle.runs,
|
|
313
|
+
improve: bundle.improve,
|
|
314
|
+
metrics: bundle.metrics,
|
|
315
|
+
};
|
|
316
|
+
});
|
|
317
|
+
if (windowResults.length >= 2) {
|
|
318
|
+
// Deltas always read chronologically: `from` = earliest window,
|
|
319
|
+
// `to` = latest. Positive pctChange on a failure metric (e.g.
|
|
320
|
+
// distill.llmFailed) means things got WORSE going forward in
|
|
321
|
+
// time; negative means improvement. Window 0 in the output
|
|
322
|
+
// array is whatever the user specified first (typically
|
|
323
|
+
// `current` for --window-compare), but the delta direction is
|
|
324
|
+
// independent of that array order.
|
|
325
|
+
const sorted = [...windowResults].sort((a, b) => new Date(a.since).getTime() - new Date(b.since).getTime());
|
|
326
|
+
deltas = computeDeltas(sorted[0], sorted[sorted.length - 1]);
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
return { windowResults, deltas };
|
|
330
|
+
}
|
|
63
331
|
export function akmHealth(options = {}) {
|
|
64
332
|
validateAkmHealthOptions(options);
|
|
65
333
|
const now = options.now ?? (() => Date.now());
|
|
@@ -86,112 +354,13 @@ export function akmHealth(options = {}) {
|
|
|
86
354
|
logsDb = undefined;
|
|
87
355
|
}
|
|
88
356
|
try {
|
|
89
|
-
const
|
|
90
|
-
const tableNames
|
|
91
|
-
const
|
|
92
|
-
const
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
const
|
|
96
|
-
const failedTaskRows = taskRows.filter((row) => row.status === "failed");
|
|
97
|
-
const activeRows = taskRows.filter((row) => row.status === "active");
|
|
98
|
-
const stuckActiveRuns = activeRows.filter((row) => now() - new Date(row.started_at).getTime() > ACTIVE_RUN_WARN_MS).length;
|
|
99
|
-
const promptRows = taskRows.filter((row) => row.target_kind === "prompt");
|
|
100
|
-
const promptFailures = promptRows.filter((row) => {
|
|
101
|
-
const detail = parseTaskMetadata(row).detail;
|
|
102
|
-
return typeof detail?.reason === "string" && detail.reason.length > 0;
|
|
103
|
-
});
|
|
104
|
-
const logBackingRate = taskRowsWithLogs.length === 0 ? 1 : existingLogRows.length / taskRowsWithLogs.length;
|
|
105
|
-
const taskFailRate = taskRows.length === 0 ? 0 : failedTaskRows.length / taskRows.length;
|
|
106
|
-
const agentFailureRate = promptRows.length === 0 ? 0 : promptFailures.length / promptRows.length;
|
|
107
|
-
const semanticStatus = readSemanticStatus();
|
|
108
|
-
// For the embedding-endpoint advisory. Best-effort: an unloadable config
|
|
109
|
-
// leaves both undefined and the check falls back to its generic message.
|
|
110
|
-
let semanticSearchMode;
|
|
111
|
-
let embeddingEndpoint;
|
|
112
|
-
let egressConfigView;
|
|
113
|
-
try {
|
|
114
|
-
const config = loadConfig();
|
|
115
|
-
semanticSearchMode = config.semanticSearchMode;
|
|
116
|
-
embeddingEndpoint = config.embedding?.endpoint;
|
|
117
|
-
egressConfigView = config;
|
|
118
|
-
}
|
|
119
|
-
catch {
|
|
120
|
-
// fall through with undefined
|
|
121
|
-
}
|
|
122
|
-
const improveInvoked = readEvents({ since, type: "improve_invoked" }, { dbPath: stateDbPath }).events.length;
|
|
123
|
-
const improveCompletedEvents = readEvents({ since, type: IMPROVE_COMPLETED_EVENT }, { dbPath: stateDbPath }).events;
|
|
124
|
-
const improveSkippedEvents = readEvents({ since, type: "improve_skipped" }, { dbPath: stateDbPath }).events;
|
|
125
|
-
const eventsMetrics = summarizeImproveCompleted(improveCompletedEvents);
|
|
126
|
-
const { metrics: improveSummary } = summarizeImproveRuns(db, since);
|
|
127
|
-
improveSummary.invoked = improveInvoked;
|
|
128
|
-
improveSummary.completed = eventsMetrics.completed;
|
|
129
|
-
const skipSummary = buildImproveSkipSummary(improveSkippedEvents);
|
|
130
|
-
improveSummary.skipped = skipSummary.skipped;
|
|
131
|
-
improveSummary.skipReasons = skipSummary.skipReasons;
|
|
132
|
-
const perRunSummaries = buildPerRunSummaries(db, since);
|
|
133
|
-
const wallTimes = perRunSummaries.map((run) => run.wallTimeMs).filter((ms) => Number.isFinite(ms) && ms > 0);
|
|
134
|
-
improveSummary.wallTime = computeWallTimeStats(wallTimes, improveSummary.wallTime.byPhase);
|
|
135
|
-
improveSummary.calibration = readCalibration(db, since);
|
|
136
|
-
// WS-5: Compute denominator-fixed coverage and per-run degradation metrics
|
|
137
|
-
// for the main health path (not just window-compare mode).
|
|
138
|
-
const until = new Date(now()).toISOString();
|
|
139
|
-
const totalAssetsMain = improveSummary.memorySummary.eligible + improveSummary.memorySummary.derived;
|
|
140
|
-
improveSummary.coverage = computeDenominatorFixedCoverage(db, totalAssetsMain, improveSummary.memorySummary.eligible, since, until);
|
|
141
|
-
const degradationMain = computeDegradationMetrics(db, since, until);
|
|
142
|
-
if (degradationMain) {
|
|
143
|
-
improveSummary.degradation = degradationMain;
|
|
144
|
-
}
|
|
145
|
-
improveSummary.enrichmentMinting = computeEnrichmentMintingRollup(db, since, until);
|
|
146
|
-
advisories.push(...collectImproveAdvisories(db, stateDbPath, since, improveSummary));
|
|
147
|
-
// 08-F1: surface a `stash-git-exposure` advisory when env/secret assets are
|
|
148
|
-
// git-tracked AND a remote is configured (the leak moment). Best-effort.
|
|
149
|
-
// Cheap guard: only shell out to git when the stash has its OWN `.git` (or a
|
|
150
|
-
// test injected a fake seam), so the hot path never spawns for a non-git
|
|
151
|
-
// stash — the common unit-test case. Trade-off: a stash manually pointed at a
|
|
152
|
-
// bare subdirectory of a parent git repo (no `.git` of its own) is not
|
|
153
|
-
// checked. akm-init always creates `.git` at the stash root, so any
|
|
154
|
-
// akm-initialised stash is covered; this only skips hand-pointed nested ones.
|
|
155
|
-
try {
|
|
156
|
-
const exposureStashDir = options.stashDir ?? resolveStashDir();
|
|
157
|
-
if (options.stashExposureGit || fs.existsSync(path.join(exposureStashDir, ".git"))) {
|
|
158
|
-
const stashExposure = collectStashExposureAdvisory(exposureStashDir, options.stashExposureGit);
|
|
159
|
-
if (stashExposure)
|
|
160
|
-
advisories.push(stashExposure);
|
|
161
|
-
}
|
|
162
|
-
}
|
|
163
|
-
catch {
|
|
164
|
-
// Non-fatal — a git/probe failure must not abort the health report.
|
|
165
|
-
}
|
|
166
|
-
// 08 surfaces: the remaining read-only advisory group (secret-file-perms,
|
|
167
|
-
// binary-config-skew, orphan-stores, egress-endpoints). Best-effort — a
|
|
168
|
-
// filesystem probe failure must not abort the health report.
|
|
169
|
-
try {
|
|
170
|
-
advisories.push(...collectSurfacesAdvisories({
|
|
171
|
-
stashDir: options.stashDir ?? resolveStashDir(),
|
|
172
|
-
cacheDir: getCacheDir(),
|
|
173
|
-
dataDir: getDataDir(),
|
|
174
|
-
configDir: getConfigDir(),
|
|
175
|
-
configPath: getConfigPath(),
|
|
176
|
-
config: egressConfigView,
|
|
177
|
-
}));
|
|
178
|
-
}
|
|
179
|
-
catch {
|
|
180
|
-
// Non-fatal.
|
|
181
|
-
}
|
|
182
|
-
let sessionLogEntries = [];
|
|
183
|
-
try {
|
|
184
|
-
const sinceDays = Math.max(0, Math.ceil((now() - new Date(since).getTime()) / (24 * 60 * 60 * 1000)));
|
|
185
|
-
sessionLogEntries = getExecutionLogCandidatesFn(sinceDays).map((entry) => ({
|
|
186
|
-
topic: entry.topic,
|
|
187
|
-
frequency: entry.frequency,
|
|
188
|
-
source: entry.source,
|
|
189
|
-
isFailurePattern: entry.isFailurePattern,
|
|
190
|
-
}));
|
|
191
|
-
}
|
|
192
|
-
catch {
|
|
193
|
-
sessionLogEntries = [];
|
|
194
|
-
}
|
|
357
|
+
const taskHistory = gatherTaskHistoryPhase(db, logsDb, since, stateDbPath, now);
|
|
358
|
+
const { tableNames, missingTables, probe } = taskHistory;
|
|
359
|
+
const staleTxnJournals = gatherStaleTxnJournalsPhase(now);
|
|
360
|
+
const { semanticStatus, semanticSearchMode, embeddingEndpoint, egressConfigView } = gatherSemanticConfigPhase();
|
|
361
|
+
const { improveSummary } = gatherImproveSummaryPhase(db, stateDbPath, since, now);
|
|
362
|
+
advisories.push(...gatherAncillaryAdvisories(db, stateDbPath, since, improveSummary, options, egressConfigView));
|
|
363
|
+
const sessionLogEntries = gatherSessionLogAdvisories(since, now, getExecutionLogCandidatesFn);
|
|
195
364
|
// Run the ordered health-check registry. Each check projects the shared
|
|
196
365
|
// context computed above into one HealthCheckResult; `channel` routes it to
|
|
197
366
|
// hardChecks or advisories. Declaration order in HEALTH_CHECKS is the
|
|
@@ -202,12 +371,15 @@ export function akmHealth(options = {}) {
|
|
|
202
371
|
tableNames,
|
|
203
372
|
missingTables,
|
|
204
373
|
probe,
|
|
205
|
-
taskRowCount:
|
|
206
|
-
taskFailRate,
|
|
207
|
-
taskRowsWithLogsCount:
|
|
208
|
-
existingLogRowsCount:
|
|
209
|
-
logBackingRate,
|
|
210
|
-
stuckActiveRuns,
|
|
374
|
+
taskRowCount: taskHistory.taskRowCount,
|
|
375
|
+
taskFailRate: taskHistory.taskFailRate,
|
|
376
|
+
taskRowsWithLogsCount: taskHistory.taskRowsWithLogsCount,
|
|
377
|
+
existingLogRowsCount: taskHistory.existingLogRowsCount,
|
|
378
|
+
logBackingRate: taskHistory.logBackingRate,
|
|
379
|
+
stuckActiveRuns: taskHistory.stuckActiveRuns,
|
|
380
|
+
stuckActiveTasks: taskHistory.stuckActiveTasks,
|
|
381
|
+
worstTaskFailRate: taskHistory.worstTaskFailRate,
|
|
382
|
+
staleTxnJournals,
|
|
211
383
|
semanticStatus,
|
|
212
384
|
semanticSearchMode,
|
|
213
385
|
embeddingEndpoint,
|
|
@@ -223,10 +395,10 @@ export function akmHealth(options = {}) {
|
|
|
223
395
|
advisories.push(result);
|
|
224
396
|
}
|
|
225
397
|
const metrics = {
|
|
226
|
-
taskFailRate: roundRate(taskFailRate),
|
|
227
|
-
agentFailureRate: roundRate(agentFailureRate),
|
|
228
|
-
stuckActiveRuns,
|
|
229
|
-
logBackingRate: roundRate(logBackingRate),
|
|
398
|
+
taskFailRate: roundRate(taskHistory.taskFailRate),
|
|
399
|
+
agentFailureRate: roundRate(taskHistory.agentFailureRate),
|
|
400
|
+
stuckActiveRuns: taskHistory.stuckActiveRuns,
|
|
401
|
+
logBackingRate: roundRate(taskHistory.logBackingRate),
|
|
230
402
|
probeRoundTripMs: probe.durationMs,
|
|
231
403
|
llmUsage: readLlmUsageAggregate(stateDbPath, since),
|
|
232
404
|
};
|
|
@@ -234,64 +406,21 @@ export function akmHealth(options = {}) {
|
|
|
234
406
|
const deterministicWarnings = [...hardChecks, ...advisories].some((check) => check.status === "warn" && check.kind === "deterministic");
|
|
235
407
|
const status = hardFailure ? "fail" : deterministicWarnings ? "warn" : "pass";
|
|
236
408
|
// ── Window-compare mode (Phase 3) ─────────────────────────────────────
|
|
237
|
-
|
|
238
|
-
if (options.windowCompare) {
|
|
239
|
-
windowSpecs = resolveWindowCompare(options.windowCompare, now);
|
|
240
|
-
}
|
|
241
|
-
else if (options.windows && options.windows.length > 0) {
|
|
242
|
-
windowSpecs = options.windows;
|
|
243
|
-
}
|
|
244
|
-
let windowResults;
|
|
245
|
-
let deltas;
|
|
246
|
-
let topLevelImprove = improveSummary;
|
|
247
|
-
let topLevelMetrics = metrics;
|
|
248
|
-
let topLevelSince = since;
|
|
249
|
-
if (windowSpecs && db) {
|
|
250
|
-
windowResults = windowSpecs.map((spec) => {
|
|
251
|
-
const winSince = parseHealthSince(spec.since);
|
|
252
|
-
const winUntil = spec.until ? parseHealthSince(spec.until) : new Date(now()).toISOString();
|
|
253
|
-
const bundle = buildWindowMetrics(db, stateDbPath, winSince, winUntil, now, logsDb);
|
|
254
|
-
return {
|
|
255
|
-
name: spec.name,
|
|
256
|
-
since: winSince,
|
|
257
|
-
until: winUntil,
|
|
258
|
-
runs: bundle.runs,
|
|
259
|
-
improve: bundle.improve,
|
|
260
|
-
metrics: bundle.metrics,
|
|
261
|
-
};
|
|
262
|
-
});
|
|
263
|
-
// Preserve backward compat: top-level improve/metrics reflect window 0.
|
|
264
|
-
if (windowResults.length > 0) {
|
|
265
|
-
topLevelImprove = windowResults[0].improve;
|
|
266
|
-
topLevelMetrics = { ...windowResults[0].metrics, probeRoundTripMs: probe.durationMs };
|
|
267
|
-
topLevelSince = windowResults[0].since;
|
|
268
|
-
}
|
|
269
|
-
if (windowResults.length >= 2) {
|
|
270
|
-
// Deltas always read chronologically: `from` = earliest window,
|
|
271
|
-
// `to` = latest. Positive pctChange on a failure metric (e.g.
|
|
272
|
-
// distill.llmFailed) means things got WORSE going forward in
|
|
273
|
-
// time; negative means improvement. Window 0 in the output
|
|
274
|
-
// array is whatever the user specified first (typically
|
|
275
|
-
// `current` for --window-compare), but the delta direction is
|
|
276
|
-
// independent of that array order.
|
|
277
|
-
const sorted = [...windowResults].sort((a, b) => new Date(a.since).getTime() - new Date(b.since).getTime());
|
|
278
|
-
deltas = computeDeltas(sorted[0], sorted[sorted.length - 1]);
|
|
279
|
-
}
|
|
280
|
-
}
|
|
409
|
+
const { windowResults, deltas } = resolveWindowComparePhase(options, db, stateDbPath, now, logsDb);
|
|
281
410
|
// ── Per-run mode (Phase 2) ────────────────────────────────────────────
|
|
282
411
|
let runs;
|
|
283
412
|
if (options.groupBy === "run") {
|
|
284
413
|
runs = buildPerRunSummaries(db, since);
|
|
285
414
|
}
|
|
286
415
|
return {
|
|
287
|
-
schemaVersion:
|
|
416
|
+
schemaVersion: 3,
|
|
288
417
|
ok: !hardFailure,
|
|
289
418
|
status,
|
|
290
|
-
since
|
|
419
|
+
since,
|
|
291
420
|
hardChecks,
|
|
292
421
|
advisories,
|
|
293
|
-
metrics
|
|
294
|
-
improve:
|
|
422
|
+
metrics,
|
|
423
|
+
improve: improveSummary,
|
|
295
424
|
sessionLogAdvisories: sessionLogEntries,
|
|
296
425
|
...(runs ? { runs } : {}),
|
|
297
426
|
...(windowResults ? { windows: windowResults } : {}),
|
|
@@ -72,8 +72,8 @@ function distinctTokens(text) {
|
|
|
72
72
|
}
|
|
73
73
|
/**
|
|
74
74
|
* A merge must strictly increase information (R5 §4.2):
|
|
75
|
-
* 1. Provenance: the merged asset's `
|
|
76
|
-
*
|
|
75
|
+
* 1. Provenance: the merged asset's `xrefs` must be a superset of the union of
|
|
76
|
+
* all participants' `xrefs` plus the participant refs
|
|
77
77
|
* themselves — provenance never shrinks through a merge.
|
|
78
78
|
* 2. Specificity: distinctTokens(mergedBody) ≥ minSpecificityRetention ×
|
|
79
79
|
* |union(distinctTokens(participant bodies))| — a merge that only
|
|
@@ -91,8 +91,8 @@ export function checkMergeInformationFloor(mergedBody, mergedSourceRefs, partici
|
|
|
91
91
|
const required = new Set();
|
|
92
92
|
for (const p of participants) {
|
|
93
93
|
required.add(p.ref);
|
|
94
|
-
for (const
|
|
95
|
-
required.add(
|
|
94
|
+
for (const xref of p.xrefs)
|
|
95
|
+
required.add(xref);
|
|
96
96
|
}
|
|
97
97
|
const after = new Set(mergedSourceRefs);
|
|
98
98
|
const missing = [...required].filter((r) => !after.has(r));
|
|
@@ -111,7 +111,7 @@ export function checkMergeInformationFloor(mergedBody, mergedSourceRefs, partici
|
|
|
111
111
|
const specificityOk = specificityRetention >= minRetention;
|
|
112
112
|
const reasons = [];
|
|
113
113
|
if (!provenanceOk) {
|
|
114
|
-
reasons.push(`provenance shrank: merged
|
|
114
|
+
reasons.push(`provenance shrank: merged xrefs missing ${missing.length} ref(s) (e.g. ${missing[0]})`);
|
|
115
115
|
}
|
|
116
116
|
if (!specificityOk) {
|
|
117
117
|
reasons.push(`specificity retention ${specificityRetention.toFixed(2)} < ${minRetention} (merge genericized/shortened)`);
|
|
@@ -0,0 +1,68 @@
|
|
|
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 { IMPROVE_AUTONOMY_CONFIG_KEY, isImproveAutonomyEnabled, } from "../../core/config/experimental.js";
|
|
5
|
+
/** The lanes `experimental.improveAutonomy` gates. */
|
|
6
|
+
export const AUTONOMY_LANES = ["memoryInference", "triagePromote", "memoryCleanup"];
|
|
7
|
+
const LANE_REASONS = {
|
|
8
|
+
memoryInference: "writes derived memory children and rewrites parent frontmatter",
|
|
9
|
+
triagePromote: "auto-accepts queued proposals into the stash (downgraded to queue)",
|
|
10
|
+
memoryCleanup: "rewrites belief-state frontmatter and moves files into the cleanup archive",
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* The lanes that bypass the strategy config and ask the gate at their own call
|
|
14
|
+
* site. They have no `processes.<name>.enabled` flag to downgrade, so
|
|
15
|
+
* {@link applyAutonomyGate} cannot see them — anything reporting the full gated
|
|
16
|
+
* set has to add these.
|
|
17
|
+
*/
|
|
18
|
+
export const DIRECT_AUTONOMY_LANES = ["memoryCleanup"];
|
|
19
|
+
function gatedLane(lane) {
|
|
20
|
+
return { lane, configKey: IMPROVE_AUTONOMY_CONFIG_KEY, reason: LANE_REASONS[lane] };
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Describe lanes for reporting — the warning line, the `improve_skipped` event,
|
|
24
|
+
* and `akm task doctor` all render the same {@link GatedLane} shape, so the
|
|
25
|
+
* lane name, config key, and reason cannot drift between the three surfaces.
|
|
26
|
+
*/
|
|
27
|
+
export function describeGatedLanes(lanes) {
|
|
28
|
+
return lanes.map(gatedLane);
|
|
29
|
+
}
|
|
30
|
+
/** Configured capabilities that tasks doctor reports behind the autonomy gate. */
|
|
31
|
+
export function configuredDirectAutonomyLanes() {
|
|
32
|
+
return ["memoryCleanup"];
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* True when a lane may mutate. Used by the lane that bypasses the strategy
|
|
36
|
+
* config; the other three are handled by {@link applyAutonomyGate}.
|
|
37
|
+
*/
|
|
38
|
+
export function isAutonomyLaneAllowed(_lane, config) {
|
|
39
|
+
// Every lane shares one opt-in today. The parameter is kept so a call site
|
|
40
|
+
// names the lane it is asking about — that name is what reaches the operator
|
|
41
|
+
// in the skip event — and so a future per-lane split does not have to revisit
|
|
42
|
+
// every caller.
|
|
43
|
+
return isImproveAutonomyEnabled(config);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Downgrade a strategy config to review-first unless autonomy is opted into.
|
|
47
|
+
*
|
|
48
|
+
* Returns the config to actually run plus every downgrade made. With autonomy on
|
|
49
|
+
* the input is returned untouched and `gated` is empty.
|
|
50
|
+
*/
|
|
51
|
+
export function applyAutonomyGate(strategy, config) {
|
|
52
|
+
if (isImproveAutonomyEnabled(config))
|
|
53
|
+
return { config: strategy, gated: [] };
|
|
54
|
+
const gated = [];
|
|
55
|
+
const processes = { ...(strategy.processes ?? {}) };
|
|
56
|
+
if (processes.memoryInference?.enabled === true) {
|
|
57
|
+
processes.memoryInference = { ...processes.memoryInference, enabled: false };
|
|
58
|
+
gated.push(gatedLane("memoryInference"));
|
|
59
|
+
}
|
|
60
|
+
// Triage stays ENABLED — queued proposals are still triaged, they just are not
|
|
61
|
+
// auto-accepted. Disabling it would remove review work the user asked for,
|
|
62
|
+
// which is the opposite of what a review-first default should do.
|
|
63
|
+
if (processes.triage?.applyMode === "promote") {
|
|
64
|
+
processes.triage = { ...processes.triage, applyMode: "queue" };
|
|
65
|
+
gated.push(gatedLane("triagePromote"));
|
|
66
|
+
}
|
|
67
|
+
return { config: { ...strategy, processes }, gated };
|
|
68
|
+
}
|