akm-cli 0.9.16 → 0.9.17-alpha.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2101 -0
- package/STABILITY.md +11 -10
- package/dist/akm +124 -193
- package/dist/akm-migrate +38 -19
- package/dist/assets/hints/cli-hints-full.md +6 -7
- package/dist/assets/improve-strategies/catchup.json +0 -3
- package/dist/assets/improve-strategies/consolidate.json +0 -1
- package/dist/assets/improve-strategies/default.json +1 -2
- package/dist/assets/improve-strategies/proactive-maintenance.json +1 -2
- package/dist/assets/improve-strategies/quick.json +1 -2
- package/dist/assets/improve-strategies/reflect-distill.json +1 -2
- package/dist/assets/improve-strategies/thorough.json +0 -3
- package/dist/assets/prompts/consolidate-pair.md +20 -0
- package/dist/assets/prompts/consolidate-system.md +4 -11
- package/dist/assets/prompts/retrieval-relevance-judge.md +6 -0
- package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +20 -20
- package/dist/assets/stash-skeleton/facts/conventions/domains.md +2 -2
- package/dist/assets/templates/html/health.html +3 -5
- package/dist/cli/retired-commands.js +1 -1
- package/dist/cli/shared.js +6 -2
- package/dist/cli/unknown-flags.js +24 -1
- package/dist/cli.js +68 -10
- package/dist/commands/agent/agent-dispatch.js +1 -1
- package/dist/commands/command/command-execution.js +24 -62
- package/dist/commands/feedback-cli.js +0 -1
- package/dist/commands/health/accept-rate.js +6 -0
- package/dist/commands/health/archive-usage.js +92 -0
- package/dist/commands/health/checks.js +83 -74
- package/dist/commands/health/config-skew.js +38 -0
- package/dist/commands/health/data-dir-usage.js +25 -13
- package/dist/commands/health/egress.js +54 -0
- package/dist/commands/health/html-report.js +1 -42
- package/dist/commands/health/improve-metrics.js +136 -591
- package/dist/commands/health/md-report.js +1 -6
- package/dist/commands/health/plugin-staleness.js +53 -3
- package/dist/commands/health/renderers.js +12 -4
- package/dist/commands/health/report-view-model.js +14 -120
- package/dist/commands/health/types-improve.js +4 -19
- package/dist/commands/health/windows.js +64 -74
- package/dist/commands/health.js +145 -143
- package/dist/commands/improve/consolidate/chunking.js +26 -117
- package/dist/commands/improve/consolidate/continuity-check.js +137 -0
- package/dist/commands/improve/consolidate/pair-pass.js +791 -0
- package/dist/commands/improve/consolidate/sanitize.js +54 -149
- package/dist/commands/improve/consolidate.js +589 -1127
- package/dist/commands/improve/content-hash.js +16 -24
- package/dist/commands/improve/distill/content-repair.js +18 -100
- package/dist/commands/improve/distill-guards.js +20 -81
- package/dist/commands/improve/distill-promotion-policy.js +23 -243
- package/dist/commands/improve/distill.js +608 -1041
- package/dist/commands/improve/eligibility.js +126 -390
- package/dist/commands/improve/execution.js +8 -10
- package/dist/commands/improve/extract-prompt.js +1 -2
- package/dist/commands/improve/extract.js +487 -1046
- package/dist/commands/improve/feedback-valence.js +0 -25
- package/dist/commands/improve/improve-cli.js +75 -169
- package/dist/commands/improve/improve-result-file.js +10 -66
- package/dist/commands/improve/improve-strategies.js +52 -4
- package/dist/commands/improve/improve-usage-report.js +18 -64
- package/dist/commands/improve/improve.js +480 -1074
- package/dist/commands/improve/ledger.js +119 -0
- package/dist/commands/improve/locks.js +2 -8
- package/dist/commands/improve/loop-stages.js +415 -1073
- package/dist/commands/improve/memory/derived-ref.js +12 -77
- package/dist/commands/improve/memory/memory-belief.js +16 -118
- package/dist/commands/improve/memory/memory-improve.js +266 -14
- package/dist/commands/improve/outcome-loop.js +28 -156
- package/dist/commands/improve/planner.js +5 -15
- package/dist/commands/improve/preparation.js +779 -2319
- package/dist/commands/improve/proactive-maintenance.js +34 -101
- package/dist/commands/improve/reflect-noise.js +104 -280
- package/dist/commands/improve/reflect.js +642 -1353
- package/dist/commands/improve/retrieval-gate.js +127 -0
- package/dist/commands/improve/retrieval-scope.js +92 -0
- package/dist/commands/improve/salience.js +41 -240
- package/dist/commands/improve/session-asset.js +19 -100
- package/dist/commands/improve/stage.js +322 -0
- package/dist/commands/lint/base-linter.js +37 -15
- package/dist/commands/proposal/drain.js +261 -578
- package/dist/commands/proposal/proposal-cli.js +19 -20
- package/dist/commands/proposal/proposal-types.js +31 -24
- package/dist/commands/proposal/proposal.js +38 -8
- package/dist/commands/proposal/propose.js +134 -160
- package/dist/commands/proposal/repository.js +1097 -1394
- package/dist/commands/proposal/validators/proposal-quality-validators.js +71 -174
- package/dist/commands/proposal/validators/proposal-validators.js +1 -1
- package/dist/commands/proposal/validators/proposals.js +22 -89
- package/dist/commands/read/curate.js +105 -462
- package/dist/commands/read/knowledge.js +3 -2
- package/dist/commands/read/search-cli.js +16 -33
- package/dist/commands/read/search.js +17 -23
- package/dist/commands/read/show.js +57 -108
- package/dist/commands/sources/bundle-cli.js +25 -2
- package/dist/commands/sources/bundle-config-ops.js +4 -0
- package/dist/commands/sources/dangerous-env-audit.js +1 -2
- package/dist/commands/sources/info.js +127 -29
- package/dist/commands/sources/installed-stashes.js +197 -746
- package/dist/commands/sources/schema-repair.js +98 -129
- package/dist/commands/sources/source-add.js +62 -12
- package/dist/commands/sources/source-manage.js +9 -2
- package/dist/commands/sources/stash-cli.js +24 -4
- package/dist/commands/tasks/explain.js +10 -13
- package/dist/commands/tasks/tasks-cli.js +12 -13
- package/dist/commands/tasks/tasks.js +350 -936
- package/dist/commands/tasks/validate.js +26 -24
- package/dist/commands/workflow/plan.js +22 -29
- package/dist/commands/workflow-cli.js +4 -4
- package/dist/core/adapter/adapters/akm-adapter.js +2 -1
- package/dist/core/adapter/adapters/akm-lint.js +2 -3
- package/dist/core/adapter/adapters/akm-metadata.js +42 -12
- package/dist/core/adapter/adapters/akm-task-adapter.js +29 -8
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +1 -1
- package/dist/core/adapter/execution-source.js +17 -29
- package/dist/core/asset/asset-placement.js +4 -13
- package/dist/core/asset/frontmatter.js +106 -1
- package/dist/core/asset/resolve-ref.js +1 -1
- package/dist/core/bundle-id.js +42 -5
- package/dist/core/bundle-rename.js +285 -0
- package/dist/core/config/config-io.js +1 -2
- package/dist/core/config/config-schema.js +9 -34
- package/dist/core/config/config-walker.js +1 -1
- package/dist/core/config/config.js +184 -111
- package/dist/core/config/engine-semantics.js +0 -2
- package/dist/core/config/legacy-source-shape-shim.js +38 -9
- package/dist/core/config/schema/embedding.js +20 -5
- package/dist/core/config/schema/engines.js +5 -0
- package/dist/core/config/schema/execution.js +1 -1
- package/dist/core/config/schema/experimental.js +1 -1
- package/dist/core/config/schema/improve-processes.js +54 -125
- package/dist/core/config/schema/improve.js +4 -42
- package/dist/core/config/schema/index-config.js +9 -48
- package/dist/core/config/schema/scheduler.js +12 -12
- package/dist/core/config/schema/search.js +6 -22
- package/dist/core/env-secret-ref.js +0 -1
- package/dist/core/errors.js +8 -9
- package/dist/core/file-change.js +13 -5
- package/dist/core/file-lock.js +76 -173
- package/dist/core/improve-result.js +35 -7
- package/dist/core/improve-types.js +0 -1
- package/dist/core/logs-db.js +2 -2
- package/dist/core/loopback.js +7 -12
- package/dist/core/non-task-input.js +20 -0
- package/dist/core/parse.js +13 -16
- package/dist/core/paths.js +0 -24
- package/dist/core/redaction.js +109 -2
- package/dist/core/run-lock.js +2 -5
- package/dist/core/spawn-env.js +1 -1
- package/dist/core/state/migrations.js +123 -61
- package/dist/core/state-db-scope.js +2 -4
- package/dist/core/state-db.js +126 -692
- package/dist/core/time.js +0 -20
- package/dist/core/type-presentation.js +1 -9
- package/dist/core/write-source.js +294 -1005
- package/dist/execution/input-contract.js +1 -1
- package/dist/execution/resolved-request.js +135 -689
- package/dist/execution/source.js +63 -257
- package/dist/execution/target-ref.js +1 -1
- package/dist/indexer/bundle-identity-guard.js +2 -2
- package/dist/indexer/db/llm-cache.js +2 -2
- package/dist/indexer/ensure-index.js +77 -73
- package/dist/indexer/index-rebuild-lock.js +3 -11
- package/dist/indexer/index-writer-lock.js +8 -17
- package/dist/indexer/index-written-assets.js +141 -154
- package/dist/indexer/indexer.js +400 -1124
- package/dist/indexer/links/declared-links.js +90 -0
- package/dist/indexer/materialize-embeddings.js +60 -397
- package/dist/indexer/passes/memory-inference.js +96 -90
- package/dist/indexer/passes/metadata.js +132 -219
- package/dist/indexer/read-preflight.js +0 -7
- package/dist/indexer/scan/doc-to-entry.js +2 -3
- package/dist/indexer/scan/drain-dir.js +1 -1
- package/dist/indexer/search/db-search.js +190 -590
- package/dist/indexer/search/fts-query.js +30 -41
- package/dist/indexer/search/ranking.js +28 -154
- package/dist/indexer/search/search-attribution.js +12 -32
- package/dist/indexer/search/search-fields.js +11 -15
- package/dist/indexer/search/search-hit-enrichers.js +54 -85
- package/dist/indexer/search/search-source.js +1 -4
- package/dist/indexer/usage/usage-events.js +36 -7
- package/dist/indexer/walk/walker.js +3 -4
- package/dist/integrations/agent/engine-fallback.js +23 -40
- package/dist/integrations/agent/engine-resolution.js +93 -183
- package/dist/integrations/agent/execution.js +507 -0
- package/dist/integrations/agent/model-map.js +28 -156
- package/dist/integrations/agent/request-lowering.js +66 -141
- package/dist/integrations/agent/runner-dispatch.js +143 -321
- package/dist/integrations/agent/runner.js +54 -14
- package/dist/integrations/lockfile.js +53 -101
- package/dist/llm/client.js +18 -6
- package/dist/llm/embedders/deterministic.js +2 -3
- package/dist/llm/embedders/profile.js +71 -0
- package/dist/llm/embedders/remote.js +11 -17
- package/dist/llm/feature-gate.js +0 -8
- package/dist/llm/index-passes.js +3 -5
- package/dist/llm/memory-infer.js +1 -2
- package/dist/llm/structured-call.js +5 -24
- package/dist/output/generic-render.js +23 -11
- package/dist/output/html-render.js +13 -10
- package/dist/output/render-registry.js +3 -32
- package/dist/output/shapes/helpers.js +25 -38
- package/dist/output/shapes/passthrough.js +1 -9
- package/dist/{indexer/graph/graph-types.js → output/text/bundle-rename.js} +4 -1
- package/dist/output/text/command-format.js +69 -31
- package/dist/output/text/helpers.js +1 -1
- package/dist/output/text/migrate.js +5 -14
- package/dist/output/text/proposal-format.js +48 -3
- package/dist/output/text/show-format.js +13 -17
- package/dist/output/text/workflow-format.js +0 -32
- package/dist/output/text.js +2 -0
- package/dist/registry/factory.js +4 -19
- package/dist/registry/network.js +66 -220
- package/dist/registry/providers/index.js +0 -2
- package/dist/registry/providers/skills-sh.js +3 -14
- package/dist/registry/providers/static-index.js +24 -26
- package/dist/registry/resolve.js +55 -131
- package/dist/scripts/akm-migrate-node.js +42948 -92369
- package/dist/scripts/akm-migrate.js +42935 -92354
- package/dist/setup/registry-stash-loader.js +4 -13
- package/dist/setup/semantic-assets.js +3 -44
- package/dist/setup/setup.js +1 -1
- package/dist/setup/steps/connection.js +5 -6
- package/dist/setup/steps/platforms.js +2 -2
- package/dist/setup/steps/tasks.js +25 -15
- package/dist/sources/provider-factory.js +17 -18
- package/dist/sources/providers/filesystem.js +2 -3
- package/dist/sources/providers/git-install.js +7 -1
- package/dist/sources/providers/git-provider.js +0 -3
- package/dist/sources/providers/git-stash.js +83 -21
- package/dist/sources/providers/npm.js +2 -4
- package/dist/sources/providers/provider-utils.js +5 -10
- package/dist/sources/providers/website.js +0 -2
- package/dist/sources/snapshot-fetchers/website-ingest.js +1 -1
- package/dist/sources/website-url.js +2 -2
- package/dist/storage/database.js +9 -35
- package/dist/storage/repositories/improve-ledger-repository.js +209 -0
- package/dist/storage/repositories/index-connection.js +39 -72
- package/dist/storage/repositories/index-entries-repository.js +131 -129
- package/dist/storage/repositories/index-entry-mapper.js +1 -2
- package/dist/storage/repositories/index-entry-schema.js +101 -268
- package/dist/storage/repositories/index-fts-repository.js +86 -256
- package/dist/storage/repositories/index-links-repository.js +143 -0
- package/dist/storage/repositories/index-llm-cache-repository.js +7 -9
- package/dist/storage/repositories/index-meta-repository.js +6 -4
- package/dist/storage/repositories/index-schema.js +257 -325
- package/dist/storage/repositories/index-utility-repository.js +8 -29
- package/dist/storage/repositories/index-vec-repository.js +133 -414
- package/dist/storage/repositories/outcome-repository.js +2 -1
- package/dist/storage/repositories/proposals-repository.js +104 -1
- package/dist/storage/repositories/registry-index-cache-repository.js +100 -0
- package/dist/storage/repositories/salience-repository.js +1 -19
- package/dist/storage/repositories/task-history-repository.js +26 -4
- package/dist/storage/repositories/workflow-runs-repository.js +53 -244
- package/dist/storage/sqlite-migrations.js +136 -0
- package/dist/storage/sqlite-pragmas.js +11 -9
- package/dist/storage/sqlite-transaction.js +170 -0
- package/dist/storage/state-db-integrity.js +130 -0
- package/dist/tasks/activation-config.js +134 -62
- package/dist/tasks/backends/cron.js +191 -302
- package/dist/tasks/backends/exec-utils.js +2 -5
- package/dist/tasks/backends/launchd.js +141 -748
- package/dist/tasks/backends/schtasks.js +119 -623
- package/dist/tasks/prepare/prepare-support.js +5 -15
- package/dist/tasks/prepare/prepare.js +0 -2
- package/dist/tasks/resolve-akm-bin.js +20 -79
- package/dist/tasks/run/attempt-lifecycle.js +0 -1
- package/dist/tasks/run/load-task.js +1 -1
- package/dist/tasks/scheduler-binding.js +20 -238
- package/dist/tasks/scheduler-invocation.js +136 -244
- package/dist/tasks/scheduler-lock.js +53 -0
- package/dist/tasks/scheduler-sync.js +368 -679
- package/dist/tasks/source/parse-task-source.js +55 -9
- package/dist/tasks/source/task-source-v3-frozen.js +3 -4
- package/dist/tasks/source/task-to-v4.js +464 -88
- package/dist/workflows/authoring/authoring.js +3 -12
- package/dist/workflows/compile.js +211 -0
- package/dist/workflows/concurrency-policy.js +13 -74
- package/dist/workflows/exec/child-invocation.js +3 -17
- package/dist/workflows/exec/child-workflow.js +32 -141
- package/dist/workflows/exec/dispatch-redaction.js +13 -53
- package/dist/workflows/exec/environment.js +98 -0
- package/dist/workflows/exec/exec-unit.js +33 -140
- package/dist/workflows/exec/frozen-judge.js +7 -59
- package/dist/workflows/exec/native-executor.js +82 -341
- package/dist/workflows/exec/param-secrets.js +29 -47
- package/dist/workflows/exec/run-workflow.js +154 -387
- package/dist/workflows/exec/scheduler.js +9 -36
- package/dist/workflows/exec/step-work.js +127 -430
- package/dist/workflows/exec/unit-dispatch.js +11 -63
- package/dist/workflows/exec/unit-writer.js +8 -52
- package/dist/workflows/exec/worktree.js +39 -273
- package/dist/workflows/freeze/child-output-references.js +4 -15
- package/dist/workflows/freeze/environment.js +99 -92
- package/dist/workflows/freeze/freeze.js +172 -0
- package/dist/workflows/freeze/step-values.js +19 -21
- package/dist/workflows/freeze/targets/child-workflow.js +23 -92
- package/dist/workflows/freeze/targets/command.js +10 -33
- package/dist/workflows/freeze/targets/script.js +5 -12
- package/dist/workflows/freeze/targets/shell.js +3 -6
- package/dist/workflows/freeze/targets/task.js +25 -80
- package/dist/workflows/freeze/task-bindings.js +20 -67
- package/dist/workflows/{source-ir/github-yaml.js → github-yaml.js} +88 -206
- package/dist/workflows/ir/params.js +6 -51
- package/dist/workflows/ir/plan-hash.js +2 -34
- package/dist/workflows/parser.js +140 -43
- package/dist/{commands/improve/consolidate/types.js → workflows/plan.js} +2 -1
- package/dist/workflows/renderer.js +36 -69
- package/dist/workflows/resource-limits.js +12 -120
- package/dist/workflows/runtime/agent-identity.js +8 -40
- package/dist/workflows/runtime/run-outputs.js +3 -6
- package/dist/workflows/runtime/run-plan.js +316 -0
- package/dist/workflows/runtime/runs.js +48 -200
- package/dist/workflows/runtime/workflow-asset-loader.js +24 -57
- package/dist/workflows/{source-ir/semantics.js → source-semantics.js} +16 -20
- package/dist/workflows/validate-summary.js +2 -7
- package/docs/integration/bundling-akm.md +49 -42
- package/docs/migration/README.md +1 -0
- package/docs/migration/release-notes/0.9.17.md +43 -0
- package/docs/migration/v0.9.1-to-v0.9.2.md +23 -7
- package/docs/reference/cli.md +232 -135
- package/docs/reference/configuration.md +71 -57
- package/docs/reference/data-and-telemetry.md +20 -21
- package/docs/reference/tasks.md +105 -39
- package/docs/reference/workflow-schema.md +14 -18
- package/docs/reference/workflows.md +6 -9
- package/package.json +1 -1
- package/schemas/akm-config.json +115 -738
- package/schemas/akm-workflow.json +1 -0
- package/dist/assets/improve-strategies/graph-refresh.json +0 -15
- package/dist/assets/prompts/contradiction-judge.md +0 -33
- package/dist/assets/prompts/graph-extract-system.md +0 -1
- package/dist/assets/prompts/graph-extract-user-prompt.md +0 -35
- package/dist/assets/prompts/metadata-enhance-system.md +0 -1
- package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +0 -4
- package/dist/commands/health/advisories.js +0 -150
- package/dist/commands/health/metrics.js +0 -329
- package/dist/commands/health/surfaces.js +0 -102
- package/dist/commands/improve/anti-collapse.js +0 -83
- package/dist/commands/improve/collapse-detector.js +0 -432
- package/dist/commands/improve/consolidate/eligibility.js +0 -48
- package/dist/commands/improve/consolidate/merge.js +0 -149
- package/dist/commands/improve/distill/promote-memory.js +0 -291
- package/dist/commands/improve/distill/quality-gate.js +0 -337
- package/dist/commands/improve/eval-cases.js +0 -52
- package/dist/commands/improve/memory/memory-contradiction-detect.js +0 -291
- package/dist/commands/improve/proposal-envelope.js +0 -31
- package/dist/commands/improve/run-context.js +0 -123
- package/dist/commands/improve/shared.js +0 -31
- package/dist/commands/improve/source-identity.js +0 -28
- package/dist/commands/improve/triage.js +0 -96
- package/dist/commands/proposal/drain-policies.js +0 -151
- package/dist/commands/sources/update-transaction.js +0 -220
- package/dist/core/action-contributors.js +0 -28
- package/dist/core/config/config-version-shim.js +0 -101
- package/dist/core/fs-txn.js +0 -405
- package/dist/core/lexical-score.js +0 -25
- package/dist/core/maintenance-barrier.js +0 -167
- package/dist/execution/executable-identity.js +0 -105
- package/dist/execution/guarded-source.js +0 -427
- package/dist/indexer/db/graph-db.js +0 -444
- package/dist/indexer/graph/graph-boost.js +0 -427
- package/dist/indexer/graph/graph-dedup.js +0 -95
- package/dist/indexer/graph/graph-extraction.js +0 -1108
- package/dist/indexer/search/name-match.js +0 -35
- package/dist/indexer/search/ranking-contributors.js +0 -515
- package/dist/indexer/search/ranking-types.js +0 -4
- package/dist/indexer/walk/project-context.js +0 -192
- package/dist/integrations/agent/execution-cascade.js +0 -566
- package/dist/integrations/agent/execution-definitions.js +0 -202
- package/dist/integrations/agent/execution-lowering.js +0 -841
- package/dist/integrations/agent/execution-preparation.js +0 -98
- package/dist/integrations/agent/inline-execution.js +0 -74
- package/dist/llm/graph-extract.js +0 -728
- package/dist/llm/metadata-enhance.js +0 -96
- package/dist/registry/create-provider-registry.js +0 -29
- package/dist/registry/pinned-request-helper.js +0 -247
- package/dist/registry/pinned-transport.js +0 -717
- package/dist/sources/providers/index.js +0 -14
- package/dist/storage/engines/sqlite-migrations.js +0 -271
- package/dist/storage/repositories/canaries-repository.js +0 -107
- package/dist/storage/repositories/embedding-salvage-repository.js +0 -184
- package/dist/storage/repositories/registry-cache.js +0 -113
- package/dist/tasks/scheduler-sync-preview.js +0 -52
- package/dist/tasks/source/task-to-v3.js +0 -507
- package/dist/workflows/freeze/resolve-steps.js +0 -86
- package/dist/workflows/freeze/source-freeze.js +0 -64
- package/dist/workflows/ir/compile.js +0 -321
- package/dist/workflows/ir/environment-v4.js +0 -330
- package/dist/workflows/ir/freeze-v4.js +0 -153
- package/dist/workflows/ir/schema-v4.js +0 -745
- package/dist/workflows/ir/schema.js +0 -354
- package/dist/workflows/program/schema.js +0 -77
- package/dist/workflows/runtime/checkin.js +0 -57
- package/dist/workflows/runtime/plan-classifier.js +0 -196
- package/dist/workflows/runtime/unit-checkin.js +0 -45
- package/dist/workflows/runtime/unit-phases.js +0 -20
- package/dist/workflows/schema.js +0 -4
- package/dist/workflows/source-ir/compile.js +0 -200
- package/dist/workflows/source-ir/program.js +0 -50
- package/dist/workflows/source-ir/result.js +0 -26
- package/dist/workflows/source-ir/schema.js +0 -786
- package/dist/workflows/source-ir/triggers.js +0 -79
- package/dist/workflows/source-ir/uses.js +0 -40
- package/dist/workflows/validator.js +0 -60
|
@@ -20,7 +20,7 @@ function renderTable(headers, rows) {
|
|
|
20
20
|
*
|
|
21
21
|
* Columns: ts | ok | actions | refl_ok/fail/cd/skip |
|
|
22
22
|
* distill_q/llm-fail/qrej/cfg/skip | cons_proc/promo/merge/del |
|
|
23
|
-
* mem_cons/written/skip |
|
|
23
|
+
* mem_cons/written/skip | orphans | lint_f/fl
|
|
24
24
|
*/
|
|
25
25
|
export function renderRunsDetailMd(runs) {
|
|
26
26
|
const headers = [
|
|
@@ -32,7 +32,6 @@ export function renderRunsDetailMd(runs) {
|
|
|
32
32
|
"distill_q/llm-fail/judge/validator/cfg/skip",
|
|
33
33
|
"cons_proc/promo/merge/del",
|
|
34
34
|
"mem_cons/written/skip",
|
|
35
|
-
"graph_f/e/r",
|
|
36
35
|
"orphans",
|
|
37
36
|
"lint_f/fl",
|
|
38
37
|
"result_status",
|
|
@@ -50,7 +49,6 @@ export function renderRunsDetailMd(runs) {
|
|
|
50
49
|
r.actions.distill.skipped +
|
|
51
50
|
r.actions.memoryPrune +
|
|
52
51
|
r.actions.memoryInference +
|
|
53
|
-
r.actions.graphExtraction +
|
|
54
52
|
r.actions.error;
|
|
55
53
|
return [
|
|
56
54
|
r.startedAt,
|
|
@@ -61,7 +59,6 @@ export function renderRunsDetailMd(runs) {
|
|
|
61
59
|
`${r.actions.distill.queued}/${r.actions.distill.llmFailed}/${r.actions.distill.judgeRejected}/${r.actions.distill.validatorRejected}/${r.actions.distill.configDisabled}/${r.actions.distill.skipped}`,
|
|
62
60
|
`${r.consolidation.processed}/${r.consolidation.promoted}/${r.consolidation.merged}/${r.consolidation.deleted}`,
|
|
63
61
|
`${r.memoryInference.considered}/${r.memoryInference.written}/${r.memoryInference.skippedNoFacts}`,
|
|
64
|
-
`${r.graphExtraction.extractedFiles}/${r.graphExtraction.entities}/${r.graphExtraction.relations}`,
|
|
65
62
|
String(r.orphansPurged),
|
|
66
63
|
`${r.lintFixed}/${r.lintFlagged}`,
|
|
67
64
|
r.resultStatus ?? "valid",
|
|
@@ -81,8 +78,6 @@ export function renderWindowCompareMd(windows, deltas) {
|
|
|
81
78
|
const badIfPositive = new Set([
|
|
82
79
|
"improve.actions.reflect.failed",
|
|
83
80
|
"improve.actions.distill.llmFailed",
|
|
84
|
-
"improve.graphExtraction.failures",
|
|
85
|
-
"improve.graphExtraction.nonArrayBatchFailures",
|
|
86
81
|
"improve.wallTime.medianMs",
|
|
87
82
|
"improve.wallTime.p95Ms",
|
|
88
83
|
"improve.memoryInference.skippedNoFacts",
|
|
@@ -63,6 +63,46 @@ import { isExactSemver, isSemverRange, maxSatisfying, satisfiesRange } from "../
|
|
|
63
63
|
function claudePluginsDir() {
|
|
64
64
|
return process.env.AKM_CLAUDE_PLUGINS_DIR ?? path.join(os.homedir(), ".claude", "plugins");
|
|
65
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Root of OpenCode's package cache, same override pattern as
|
|
68
|
+
* {@link claudePluginsDir} (`AKM_OPENCODE_CACHE_DIR` for tests).
|
|
69
|
+
* The OpenCode plugin (`akm-opencode`) bundles its own `akm-cli` under
|
|
70
|
+
* `packages/akm-opencode/node_modules/akm-cli` and runs it in-process,
|
|
71
|
+
* sharing the host's databases with every other akm install — its version
|
|
72
|
+
* lag matters the same way a stale Claude plugin's does.
|
|
73
|
+
*/
|
|
74
|
+
function opencodeCacheDir() {
|
|
75
|
+
return process.env.AKM_OPENCODE_CACHE_DIR ?? path.join(os.homedir(), ".cache", "opencode");
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Read the OpenCode plugin's bundled `akm-cli` version from its
|
|
79
|
+
* `package.json` — never executed, just parsed, mirroring
|
|
80
|
+
* {@link detectInstalledPlugins}'s manifest read. `undefined` when the
|
|
81
|
+
* OpenCode plugin, or its bundled akm-cli, is not installed.
|
|
82
|
+
*/
|
|
83
|
+
function detectOpencodeBundledAkmVersion(cacheRoot) {
|
|
84
|
+
const pkgPath = path.join(cacheRoot, "packages", "akm-opencode", "node_modules", "akm-cli", "package.json");
|
|
85
|
+
try {
|
|
86
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
|
|
87
|
+
return typeof pkg.version === "string" ? pkg.version : undefined;
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
return undefined;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
function buildOpencodeBundledAdvisory(bundledVersion, cliVersion) {
|
|
94
|
+
const stale = bundledVersion !== cliVersion;
|
|
95
|
+
return {
|
|
96
|
+
name: "opencode-plugin-version",
|
|
97
|
+
kind: "deterministic",
|
|
98
|
+
status: stale ? "warn" : "pass",
|
|
99
|
+
confidence: "high",
|
|
100
|
+
message: stale
|
|
101
|
+
? `OpenCode's bundled akm-cli is v${bundledVersion}, but the running CLI is v${cliVersion} — it shares the same databases in-process; update the OpenCode plugin.`
|
|
102
|
+
: `OpenCode's bundled akm-cli matches the running v${cliVersion}.`,
|
|
103
|
+
evidence: { bundledVersion, cliVersion },
|
|
104
|
+
};
|
|
105
|
+
}
|
|
66
106
|
/**
|
|
67
107
|
* Scan `<pluginsRoot>/cache/<marketplace>/akm/<version>/` for every
|
|
68
108
|
* `akm` plugin cache entry, picking the highest cached version per
|
|
@@ -165,14 +205,24 @@ const realListRemoteTags = (marketplaceDir) => {
|
|
|
165
205
|
return [...new Set(tags)];
|
|
166
206
|
};
|
|
167
207
|
/**
|
|
168
|
-
* Build one `plugin-version` advisory per detected `akm` harness plugin
|
|
169
|
-
*
|
|
208
|
+
* Build one `plugin-version` advisory per detected `akm` harness plugin,
|
|
209
|
+
* plus one `opencode-plugin-version` advisory when the
|
|
210
|
+
* OpenCode plugin's bundled `akm-cli` is found — it shares the host's
|
|
211
|
+
* databases in-process, so its lag matters the same way a stale Claude
|
|
212
|
+
* plugin's does. Returns `[]` when neither is installed — the benign,
|
|
213
|
+
* common case.
|
|
170
214
|
*/
|
|
171
215
|
export function collectPluginStalenessAdvisories(options) {
|
|
172
216
|
const pluginsRoot = options.pluginsRoot ?? claudePluginsDir();
|
|
173
217
|
const listRemoteTags = options.listRemoteTags ?? realListRemoteTags;
|
|
174
218
|
const plugins = detectInstalledPlugins(pluginsRoot);
|
|
175
|
-
|
|
219
|
+
const results = plugins.map((plugin) => buildAdvisory(plugin, options.cliVersion, pluginsRoot, listRemoteTags));
|
|
220
|
+
const opencodeCacheRoot = options.opencodeCacheRoot ?? opencodeCacheDir();
|
|
221
|
+
const bundledVersion = detectOpencodeBundledAkmVersion(opencodeCacheRoot);
|
|
222
|
+
if (bundledVersion !== undefined) {
|
|
223
|
+
results.push(buildOpencodeBundledAdvisory(bundledVersion, options.cliVersion));
|
|
224
|
+
}
|
|
225
|
+
return results;
|
|
176
226
|
}
|
|
177
227
|
function buildAdvisory(plugin, cliVersion, pluginsRoot, listRemoteTags) {
|
|
178
228
|
const pluginRef = `${plugin.pluginName}@${plugin.marketplace}`;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
4
|
/**
|
|
5
|
-
* `akm health` document renderers
|
|
5
|
+
* `akm health` document renderers.
|
|
6
6
|
*
|
|
7
7
|
* Both handlers are **pure functions of the shaped result**. Everything the
|
|
8
8
|
* rich report needs — per-run rows, window-compare deltas, the pending
|
|
@@ -13,12 +13,19 @@
|
|
|
13
13
|
* renderer to call order and made the command branch on the output format to
|
|
14
14
|
* know when to bind it. Putting the data in the envelope removed both.
|
|
15
15
|
*
|
|
16
|
+
* The Markdown renderer registers into the shared per-command registry (D7,
|
|
17
|
+
* `../../output/render-registry.ts`) alongside every other command's `--format
|
|
18
|
+
* md` renderer. The HTML renderer does not: `health` was, and remains, the
|
|
19
|
+
* only command with a bespoke HTML report, so `cli/shared.ts` calls
|
|
20
|
+
* {@link renderHealthHtml} directly instead of going through a registry with
|
|
21
|
+
* exactly one possible registrant.
|
|
22
|
+
*
|
|
16
23
|
* Returning `null` falls through to the generic renderer, so a result without
|
|
17
24
|
* the report dataset still renders — generically — instead of erroring or
|
|
18
25
|
* emitting an empty table.
|
|
19
26
|
*/
|
|
20
27
|
import { renderHtml, resolveTemplatePath } from "../../output/html-render.js";
|
|
21
|
-
import {
|
|
28
|
+
import { registerMdRenderer } from "../../output/render-registry.js";
|
|
22
29
|
import { buildHealthHtmlReplacements } from "./html-report.js";
|
|
23
30
|
import { renderRunsDetailMd, renderWindowCompareMd } from "./md-report.js";
|
|
24
31
|
function isHealthResult(value) {
|
|
@@ -34,7 +41,8 @@ registerMdRenderer("health", (result) => {
|
|
|
34
41
|
return renderRunsDetailMd(result.runs);
|
|
35
42
|
return null;
|
|
36
43
|
});
|
|
37
|
-
|
|
44
|
+
/** `--format html` renderer for `akm health`, called directly from `cli/shared.ts`. */
|
|
45
|
+
export function renderHealthHtml(result) {
|
|
38
46
|
if (!isHealthResult(result) || !result.report)
|
|
39
47
|
return null;
|
|
40
48
|
return renderHtml(resolveTemplatePath("health"), buildHealthHtmlReplacements(result, {
|
|
@@ -44,4 +52,4 @@ registerHtmlRenderer("health", (result) => {
|
|
|
44
52
|
proposals: result.report.pendingProposals,
|
|
45
53
|
deltas: result.deltas,
|
|
46
54
|
}));
|
|
47
|
-
}
|
|
55
|
+
}
|
|
@@ -64,11 +64,9 @@ function coercePct(raw) {
|
|
|
64
64
|
function reshapeRun(r) {
|
|
65
65
|
const cons = r.consolidation;
|
|
66
66
|
const mi = r.memoryInference;
|
|
67
|
-
const ge = r.graphExtraction;
|
|
68
67
|
const wall = r.wallTimeMs || 0;
|
|
69
68
|
const consMs = cons.durationMs || 0;
|
|
70
69
|
const miMs = mi.durationMs || 0;
|
|
71
|
-
const geMs = ge.durationMs || 0;
|
|
72
70
|
return {
|
|
73
71
|
id: r.id,
|
|
74
72
|
resultStatus: r.resultStatus ?? "valid",
|
|
@@ -79,31 +77,15 @@ function reshapeRun(r) {
|
|
|
79
77
|
completedAt: r.completedAt,
|
|
80
78
|
wallTimeMs: wall,
|
|
81
79
|
ok: r.ok,
|
|
82
|
-
mode: r.scope.mode,
|
|
83
80
|
consDurationMs: consMs,
|
|
84
81
|
miDurationMs: miMs,
|
|
85
|
-
|
|
86
|
-
otherMs: Math.max(0, wall - consMs - miMs - geMs),
|
|
87
|
-
consRan: cons.ran,
|
|
82
|
+
otherMs: Math.max(0, wall - consMs - miMs),
|
|
88
83
|
promoted: cons.promoted,
|
|
89
84
|
merged: cons.merged,
|
|
90
85
|
deleted: cons.deleted,
|
|
91
86
|
contradicted: cons.contradicted,
|
|
92
87
|
judgedNoAction: cons.judgedNoAction,
|
|
93
|
-
processed: cons.processed,
|
|
94
|
-
failedChunks: cons.failedChunks,
|
|
95
|
-
totalChunks: cons.totalChunks,
|
|
96
88
|
miWritten: mi.written,
|
|
97
|
-
miConsidered: mi.considered,
|
|
98
|
-
miYieldRate: mi.yieldRate,
|
|
99
|
-
miCacheHits: mi.cacheHits,
|
|
100
|
-
geEntities: ge.entities,
|
|
101
|
-
geRelations: ge.relations,
|
|
102
|
-
geCacheHitRate: ge.cacheHitRate,
|
|
103
|
-
geFailures: ge.failures,
|
|
104
|
-
distillSkipped: r.actions.distill.skipped,
|
|
105
|
-
distillQueued: r.actions.distill.queued,
|
|
106
|
-
distillLlmFailed: r.actions.distill.llmFailed,
|
|
107
89
|
distillByReason: r.actions.distill.skippedByReason,
|
|
108
90
|
reflectOk: r.actions.reflect.ok,
|
|
109
91
|
reflectFailed: r.actions.reflect.failed,
|
|
@@ -111,9 +93,6 @@ function reshapeRun(r) {
|
|
|
111
93
|
eligible: r.memorySummary.eligible,
|
|
112
94
|
lintFlagged: r.lintFlagged,
|
|
113
95
|
lintFixed: r.lintFixed,
|
|
114
|
-
reflectsWithErrorContext: r.reflectsWithErrorContext,
|
|
115
|
-
orphansPurged: r.orphansPurged,
|
|
116
|
-
evalCasesWritten: r.evalCasesWritten,
|
|
117
96
|
};
|
|
118
97
|
}
|
|
119
98
|
function compareRuns(a, b) {
|
|
@@ -136,16 +115,11 @@ function classify(deltas, metricKeys, lowerIsBetter = false) {
|
|
|
136
115
|
}
|
|
137
116
|
function buildTrend(deltas) {
|
|
138
117
|
const decisionQuality = classify(deltas, ["improve.memoryInference.yieldRate", "improve.consolidation.promoted"]);
|
|
139
|
-
const outputVolume = classify(deltas, [
|
|
140
|
-
"improve.consolidation.promoted",
|
|
141
|
-
"improve.memoryInference.written",
|
|
142
|
-
"improve.sessionExtraction.proposalsCreated",
|
|
143
|
-
]);
|
|
144
|
-
const failures = classify(deltas, ["improve.graphExtraction.failures"], true);
|
|
118
|
+
const outputVolume = classify(deltas, ["improve.consolidation.promoted", "improve.memoryInference.written"]);
|
|
145
119
|
const latency = classify(deltas, ["improve.wallTime.medianMs", "improve.wallTime.p95Ms"], true);
|
|
146
|
-
const score = [decisionQuality, outputVolume,
|
|
120
|
+
const score = [decisionQuality, outputVolume, latency].reduce((acc, d) => acc + (d === "up" ? 1 : d === "down" ? -1 : 0), 0);
|
|
147
121
|
const overall = score >= 1 ? "improving" : score <= -1 ? "degrading" : "mixed";
|
|
148
|
-
return { decisionQuality, outputVolume,
|
|
122
|
+
return { decisionQuality, outputVolume, latency, overall };
|
|
149
123
|
}
|
|
150
124
|
function readSemSearch(advisories) {
|
|
151
125
|
const check = advisories.find((a) => a.name === "semantic-search-runtime");
|
|
@@ -204,21 +178,8 @@ function buildAggregatesPhase(result, runsPhase) {
|
|
|
204
178
|
const improve = result.improve;
|
|
205
179
|
const cons = improve.consolidation;
|
|
206
180
|
const mi = improve.memoryInference;
|
|
207
|
-
const ge = improve.graphExtraction;
|
|
208
181
|
const wallTime = improve.wallTime;
|
|
209
|
-
// WS-5: perf telemetry, coverage, and degradation metrics.
|
|
210
|
-
const perf = improve.perfTelemetry ?? {
|
|
211
|
-
dedupPoolSize: 0,
|
|
212
|
-
llmPoolSize: 0,
|
|
213
|
-
embedMs: 0,
|
|
214
|
-
embedCacheHits: 0,
|
|
215
|
-
embedCacheMisses: 0,
|
|
216
|
-
overBudgetRuns: 0,
|
|
217
|
-
runsWithTelemetry: 0,
|
|
218
|
-
};
|
|
219
182
|
const coverage = improve.coverage;
|
|
220
|
-
const degradation = improve.degradation;
|
|
221
|
-
const minting = improve.enrichmentMinting;
|
|
222
183
|
// #576: real per-stage LLM token/time accounting (replaces the GPU-time
|
|
223
184
|
// proxy). Optional-guarded so reports built from older health JSON without
|
|
224
185
|
// the aggregate still render.
|
|
@@ -241,12 +202,8 @@ function buildAggregatesPhase(result, runsPhase) {
|
|
|
241
202
|
return {
|
|
242
203
|
consolidation: cons,
|
|
243
204
|
memoryInference: mi,
|
|
244
|
-
graphExtraction: ge,
|
|
245
205
|
wallTime,
|
|
246
|
-
perf,
|
|
247
206
|
coverage,
|
|
248
|
-
degradation,
|
|
249
|
-
minting,
|
|
250
207
|
llm,
|
|
251
208
|
memorySummary: improve.memorySummary,
|
|
252
209
|
includedResultRows: improve.resultRows?.included ?? totalRuns,
|
|
@@ -344,7 +301,7 @@ function groupProposalsBySource(proposals) {
|
|
|
344
301
|
}
|
|
345
302
|
/** Summary table rows: the base metric set + the WS-5 coverage/minting/perf/degradation extensions, when present. */
|
|
346
303
|
function buildSummaryRows(aggregates, trend) {
|
|
347
|
-
const { consolidation: cons,
|
|
304
|
+
const { consolidation: cons, wallTime, llm, coverage } = aggregates;
|
|
348
305
|
const summaryRows = [
|
|
349
306
|
["Task fail rate", aggregates.taskFailRate, "flat"],
|
|
350
307
|
["Agent fail rate", aggregates.agentFailRate, "flat"],
|
|
@@ -367,8 +324,6 @@ function buildSummaryRows(aggregates, trend) {
|
|
|
367
324
|
"Candidates reviewed but intentionally left unchanged (the 'judgedNoAction' field).",
|
|
368
325
|
],
|
|
369
326
|
["Chunk failure", aggregates.chunkFail, "flat"],
|
|
370
|
-
["Graph entities", num(ge.entities), "up"],
|
|
371
|
-
["Graph relations", num(ge.relations), "up"],
|
|
372
327
|
[
|
|
373
328
|
"Stash derived",
|
|
374
329
|
num(aggregates.memorySummary.derived),
|
|
@@ -389,80 +344,19 @@ function buildSummaryRows(aggregates, trend) {
|
|
|
389
344
|
"Tokens spent on model reasoning/thinking, billed separately from prompt and completion.",
|
|
390
345
|
],
|
|
391
346
|
["LLM wall time", fmtMs(llm.totalDurationMs), trend.latency],
|
|
392
|
-
|
|
393
|
-
// WS-5: denominator-fixed coverage rows (only when we have real data).
|
|
394
|
-
if (coverage && !Number.isNaN(coverage.rate)) {
|
|
395
|
-
summaryRows.push([
|
|
396
|
-
"Coverage rate",
|
|
397
|
-
pct(coverage.rate, 1),
|
|
398
|
-
"flat",
|
|
399
|
-
"Distinct accepted refs / total stash assets (denominator-fixed). Shows what fraction of the corpus has been touched.",
|
|
400
|
-
], [
|
|
401
|
-
"Eligible fraction",
|
|
402
|
-
pct(coverage.eligibleFraction, 1),
|
|
403
|
-
"flat",
|
|
404
|
-
"Eligible assets / total stash assets. Fraction the improve pipeline actively considers.",
|
|
405
|
-
], [
|
|
347
|
+
[
|
|
406
348
|
"Coverage accepted",
|
|
407
349
|
num(coverage.acceptedProposals),
|
|
408
350
|
"flat",
|
|
409
|
-
"
|
|
410
|
-
],
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
"Accepted proposals / distinct refs touched. >1.5 = the loop is repeatedly rewriting the same assets (churn, not coverage).",
|
|
415
|
-
]);
|
|
416
|
-
}
|
|
417
|
-
// Enrichment-vs-minting policy rollup (reporting-only).
|
|
418
|
-
if (minting && Number.isFinite(minting.share)) {
|
|
419
|
-
summaryRows.push([
|
|
420
|
-
"Enrichment-lane minted share",
|
|
421
|
-
pct(minting.share, 1),
|
|
422
|
-
minting.share > 0.05 ? "down" : "flat",
|
|
423
|
-
`New assets minted by enrichment lanes / their accepted total (${minting.minted} minted vs ${minting.updated} updated). Enrichment lanes are ratified to edit existing assets only; WARN >5%, FAIL >15%.`,
|
|
424
|
-
]);
|
|
425
|
-
}
|
|
426
|
-
// WS-5: perf telemetry rows (only when at least one run reported telemetry).
|
|
427
|
-
if (perf.runsWithTelemetry > 0) {
|
|
428
|
-
const embedCacheTotal = perf.embedCacheHits + perf.embedCacheMisses;
|
|
429
|
-
const embedCacheHitRate = embedCacheTotal > 0 ? pct(perf.embedCacheHits / embedCacheTotal, 1) : "—";
|
|
430
|
-
summaryRows.push([
|
|
431
|
-
"Embed cache hit rate",
|
|
432
|
-
embedCacheHitRate,
|
|
433
|
-
"flat",
|
|
434
|
-
"Fraction of embedding lookups served from cache (>95% is healthy). Aggregated across WS-5 runs.",
|
|
435
|
-
], [
|
|
436
|
-
"Embed wall time",
|
|
437
|
-
fmtMs(perf.embedMs),
|
|
438
|
-
"flat",
|
|
439
|
-
"Cumulative embedding wall-clock time across consolidation runs in the window.",
|
|
440
|
-
], [
|
|
441
|
-
"Dedup pool size",
|
|
442
|
-
num(perf.dedupPoolSize),
|
|
443
|
-
"flat",
|
|
444
|
-
"Memory pool size after incremental narrowing, before the limit cap. WS-5 perf telemetry.",
|
|
445
|
-
], [
|
|
446
|
-
"Over-budget consolidation runs",
|
|
447
|
-
String(perf.overBudgetRuns),
|
|
448
|
-
perf.overBudgetRuns > 0 ? "down" : "flat",
|
|
449
|
-
"Runs where consolidation alone exceeded the total run budget (estimatedBudgetFractionUsed > 1.0).",
|
|
450
|
-
]);
|
|
451
|
-
}
|
|
452
|
-
// WS-5: degradation metrics rows.
|
|
453
|
-
if (degradation) {
|
|
454
|
-
summaryRows.push([
|
|
455
|
-
"Corpus diversity (Gini)",
|
|
456
|
-
num(degradation.corpusCentroidDistance),
|
|
457
|
-
degradation.entrenchmentFlagged || degradation.salienceUniformityFlagged ? "down" : "flat",
|
|
458
|
-
`Gini coefficient of positive retrieval_salience values across ${degradation.retrievalSalienceSampleSize} resolvable assets. Two-tailed: >0.35 = entrenchment risk; <0.08 = collapsed toward uniform.`,
|
|
459
|
-
], [
|
|
460
|
-
"Merge fidelity contradiction rate",
|
|
461
|
-
pct(degradation.mergeFidelityContradictionRate, 1),
|
|
351
|
+
"Accepted proposals in the window (raw volume — includes repeated rewrites of the same asset).",
|
|
352
|
+
],
|
|
353
|
+
[
|
|
354
|
+
"Distinct assets touched",
|
|
355
|
+
num(coverage.distinctRefs),
|
|
462
356
|
"flat",
|
|
463
|
-
"
|
|
464
|
-
]
|
|
465
|
-
|
|
357
|
+
"Distinct assets touched by accepted proposals in the window.",
|
|
358
|
+
],
|
|
359
|
+
];
|
|
466
360
|
return summaryRows;
|
|
467
361
|
}
|
|
468
362
|
/**
|
|
@@ -2,28 +2,13 @@
|
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* New-asset generation belongs to the signal-gated minting lanes
|
|
8
|
-
* (extract/distill/memory-inference).
|
|
9
|
-
*/
|
|
10
|
-
export const ENRICHMENT_LANES = ["proactive", "high-salience", "signal-delta"];
|
|
11
|
-
/** Minted share of enrichment-lane accepts that triggers a WARN advisory. */
|
|
12
|
-
export const ENRICHMENT_MINTED_WARN_SHARE = 0.05;
|
|
13
|
-
/** Minted share of enrichment-lane accepts that triggers a FAIL advisory. */
|
|
14
|
-
export const ENRICHMENT_MINTED_FAIL_SHARE = 0.15;
|
|
15
|
-
/**
|
|
16
|
-
* Cron task failure rate at or above which the `task-fail-rate` health advisory
|
|
17
|
-
* warns. 0.05 (5%) is the SAME threshold the HTML report already applies as its
|
|
18
|
-
* fail-rate pass/warn cutoff (`failOk = taskFailRate < 0.05` in
|
|
19
|
-
* src/commands/health/html-report.ts) — this constant makes it the single
|
|
20
|
-
* source so the advisory and the rendered badge cannot drift.
|
|
5
|
+
* Cron task failure rate at or above which the `task-fail-rate` advisory
|
|
6
|
+
* warns; also the HTML report's fail-rate badge cutoff, so the two cannot drift.
|
|
21
7
|
*/
|
|
22
8
|
export const TASK_FAIL_RATE_WARN = 0.05;
|
|
23
9
|
/**
|
|
24
10
|
* Minimum task_history rows a single task_id needs in the window before its
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* run) reading as a 100% fail rate off a single noisy sample.
|
|
11
|
+
* own fail rate feeds `task-fail-rate` — a task run once and failed once is
|
|
12
|
+
* not a 100% signal.
|
|
28
13
|
*/
|
|
29
14
|
export const MIN_ROWS_FOR_WORST_TASK_FAIL_RATE = 5;
|
|
@@ -3,17 +3,14 @@
|
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
4
|
/**
|
|
5
5
|
* Window handling for `akm health`: `--window-compare` / `--windows` parsing,
|
|
6
|
-
* per-window metric assembly,
|
|
6
|
+
* per-window metric assembly, and delta computation between two windows.
|
|
7
7
|
*/
|
|
8
|
-
import fs from "node:fs";
|
|
9
8
|
import { UsageError } from "../../core/errors.js";
|
|
10
9
|
import { readEvents } from "../../core/events.js";
|
|
11
|
-
import { buildTaskRunId, getLoggedRunIds } from "../../core/logs-db.js";
|
|
12
10
|
import { DURATION_UNITS, parseDuration } from "../../core/time.js";
|
|
13
11
|
import { queryTaskHistory } from "../../storage/repositories/task-history-repository.js";
|
|
14
|
-
import { buildImproveSkipSummary, computeWallTimeStats, countAgentFailureReasons, isAgentTaskHistoryRow, roundRate,
|
|
12
|
+
import { buildImproveSkipSummary, computeWallTimeStats, computeWindowProposalCoverage, countAgentFailureReasons, isAgentTaskHistoryRow, roundRate, summarizeImproveRuns, taskFailureDetail, } from "./improve-metrics.js";
|
|
15
13
|
import { readLlmUsageAggregate } from "./llm-usage.js";
|
|
16
|
-
import { computeDegradationMetrics, computeDenominatorFixedCoverage } from "./metrics.js";
|
|
17
14
|
import { buildPerRunSummaries } from "./task-runs.js";
|
|
18
15
|
import { ACTIVE_RUN_WARN_MS, IMPROVE_COMPLETED_EVENT, } from "./types.js";
|
|
19
16
|
/**
|
|
@@ -71,28 +68,29 @@ export function parseWindowSpec(raw) {
|
|
|
71
68
|
...(fields.until ? { until: fields.until } : {}),
|
|
72
69
|
};
|
|
73
70
|
}
|
|
74
|
-
/**
|
|
71
|
+
/**
|
|
72
|
+
* Metric paths diffed between the earliest and latest window (`deltas` in the
|
|
73
|
+
* JSON result; the delta column of `--format md`). Paths are relative to a
|
|
74
|
+
* {@link WindowResult}.
|
|
75
|
+
*/
|
|
75
76
|
export const INTERESTING_DELTA_PATHS = [
|
|
76
77
|
"improve.actions.reflect.failed",
|
|
77
|
-
"improve.actions.reflect.guardRejected",
|
|
78
|
-
"improve.actions.distill.llmFailed",
|
|
79
78
|
"improve.actions.distill.queued",
|
|
80
|
-
"improve.actions.distill.
|
|
79
|
+
"improve.actions.distill.llmFailed",
|
|
81
80
|
"improve.consolidation.promoted",
|
|
82
81
|
"improve.memoryInference.written",
|
|
83
82
|
"improve.memoryInference.yieldRate",
|
|
84
83
|
"improve.memoryInference.skippedNoFacts",
|
|
85
|
-
"improve.memoryInference.htmlErrorCount",
|
|
86
|
-
"improve.graphExtraction.cacheHitRate",
|
|
87
|
-
"improve.graphExtraction.failures",
|
|
88
|
-
"improve.graphExtraction.htmlErrors",
|
|
89
|
-
"improve.graphExtraction.nonArrayBatchFailures",
|
|
90
|
-
"improve.sessionExtraction.sessionsScanned",
|
|
91
|
-
"improve.sessionExtraction.proposalsCreated",
|
|
92
84
|
"improve.autoAccept.promoted",
|
|
93
85
|
"improve.autoAccept.validationFailed",
|
|
86
|
+
"improve.coverage.acceptedProposals",
|
|
87
|
+
"improve.coverage.distinctRefs",
|
|
94
88
|
"improve.wallTime.medianMs",
|
|
95
89
|
"improve.wallTime.p95Ms",
|
|
90
|
+
"metrics.llmUsage.calls",
|
|
91
|
+
"metrics.llmUsage.totalTokens",
|
|
92
|
+
"metrics.llmUsage.totalDurationMs",
|
|
93
|
+
"metrics.llmUsage.failures",
|
|
96
94
|
];
|
|
97
95
|
export function readNumericPath(obj, path) {
|
|
98
96
|
const parts = path.split(".");
|
|
@@ -123,74 +121,66 @@ export function computeDeltas(first, last) {
|
|
|
123
121
|
return out;
|
|
124
122
|
}
|
|
125
123
|
/**
|
|
126
|
-
*
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
*
|
|
124
|
+
* Task-history-derived rates, shared by the main health path
|
|
125
|
+
* (`health.ts`'s `gatherTaskHistoryPhase`) and {@link buildWindowMetrics}
|
|
126
|
+
* below — previously computed twice with the only difference being whether
|
|
127
|
+
* the caller had already bounded `taskRows` by an `until`. Pure projection of
|
|
128
|
+
* already-queried rows; callers own the `since`/`until` query.
|
|
131
129
|
*/
|
|
132
|
-
export function
|
|
133
|
-
const withLogs = taskRows.filter((row) => row.log_path !== null);
|
|
134
|
-
const loggedRunIds = logsDb
|
|
135
|
-
? getLoggedRunIds(logsDb, withLogs.map((row) => buildTaskRunId(row.task_id, row.started_at)))
|
|
136
|
-
: new Set();
|
|
137
|
-
const backed = withLogs.filter((row) => loggedRunIds.has(buildTaskRunId(row.task_id, row.started_at)) ||
|
|
138
|
-
(row.log_path !== null && fs.existsSync(row.log_path)));
|
|
139
|
-
return { withLogs, backed };
|
|
140
|
-
}
|
|
141
|
-
export function buildWindowMetrics(db, stateDbPath, since, until, now = () => Date.now(), logsDb) {
|
|
142
|
-
const taskRows = queryTaskHistory(db, { since }).filter((row) => {
|
|
143
|
-
const startMs = new Date(row.started_at).getTime();
|
|
144
|
-
const untilMs = new Date(until).getTime();
|
|
145
|
-
return !Number.isFinite(untilMs) || startMs < untilMs;
|
|
146
|
-
});
|
|
147
|
-
const { withLogs: taskRowsWithLogs, backed: existingLogRows } = partitionLogBackedRows(taskRows, logsDb);
|
|
130
|
+
export function computeTaskWindowRates(taskRows, now) {
|
|
148
131
|
const failedTaskRows = taskRows.filter((row) => row.status === "failed");
|
|
149
132
|
const activeRows = taskRows.filter((row) => row.status === "active" && row.completed_at === null);
|
|
150
|
-
const
|
|
133
|
+
const stuckActiveRows = activeRows.filter((row) => now() - new Date(row.started_at).getTime() > ACTIVE_RUN_WARN_MS);
|
|
151
134
|
const agentRows = taskRows.filter((row) => isAgentTaskHistoryRow(row));
|
|
152
135
|
const agentFailures = agentRows.filter((row) => {
|
|
153
136
|
const detail = taskFailureDetail(row);
|
|
154
137
|
return typeof detail?.reason === "string" && detail.reason.length > 0;
|
|
155
138
|
});
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
139
|
+
return {
|
|
140
|
+
taskFailRate: taskRows.length === 0 ? 0 : failedTaskRows.length / taskRows.length,
|
|
141
|
+
agentFailureRate: agentRows.length === 0 ? 0 : agentFailures.length / agentRows.length,
|
|
142
|
+
agentFailureReasonCounts: countAgentFailureReasons(agentFailures),
|
|
143
|
+
stuckActiveRuns: stuckActiveRows.length,
|
|
144
|
+
stuckActiveRows,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Improve-pipeline window summary, shared by the main health path
|
|
149
|
+
* (`health.ts`) and {@link buildWindowMetrics} below: events-derived
|
|
150
|
+
* invoked/completed/skipped counts, the `result_json` aggregate, wall-time
|
|
151
|
+
* stats from the same per-run rows, and accepted-proposal coverage, all over
|
|
152
|
+
* one `[since, until)`.
|
|
153
|
+
*/
|
|
154
|
+
export function buildImproveWindowSummary(db, stateDbPath, since, until) {
|
|
155
|
+
const untilMs = new Date(until).getTime();
|
|
156
|
+
const eventsBeforeUntil = (type) => readEvents({ since, type }, { dbPath: stateDbPath }).events.filter((event) => new Date(event.ts ?? since).getTime() < untilMs);
|
|
157
|
+
const { metrics: improve, runCount } = summarizeImproveRuns(db, since, until);
|
|
158
|
+
improve.invoked = eventsBeforeUntil("improve_invoked").length;
|
|
159
|
+
improve.completed = eventsBeforeUntil(IMPROVE_COMPLETED_EVENT).length;
|
|
160
|
+
const skipSummary = buildImproveSkipSummary(eventsBeforeUntil("improve_skipped"));
|
|
161
|
+
improve.skipped = skipSummary.skipped;
|
|
162
|
+
improve.skipReasons = skipSummary.skipReasons;
|
|
163
|
+
// Wall times come from the same improve-runs window as the per-run
|
|
164
|
+
// reporting so counts and percentiles stay aligned with it.
|
|
173
165
|
const perRunSummaries = buildPerRunSummaries(db, since, until);
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
}
|
|
166
|
+
improve.wallTime = computeWallTimeStats(perRunSummaries.map((run) => run.wallTimeMs).filter((ms) => Number.isFinite(ms) && ms > 0));
|
|
167
|
+
improve.coverage = computeWindowProposalCoverage(db, since, until);
|
|
168
|
+
return { improve, runCount, perRunSummaries };
|
|
169
|
+
}
|
|
170
|
+
export function buildWindowMetrics(db, stateDbPath, since, until, now = () => Date.now()) {
|
|
171
|
+
const untilMs = new Date(until).getTime();
|
|
172
|
+
const taskRows = queryTaskHistory(db, { since }).filter((row) => {
|
|
173
|
+
const startMs = new Date(row.started_at).getTime();
|
|
174
|
+
return !Number.isFinite(untilMs) || startMs < untilMs;
|
|
175
|
+
});
|
|
176
|
+
const rates = computeTaskWindowRates(taskRows, now);
|
|
177
|
+
const { improve, runCount } = buildImproveWindowSummary(db, stateDbPath, since, until);
|
|
186
178
|
const metrics = {
|
|
187
|
-
taskFailRate: roundRate(taskFailRate),
|
|
188
|
-
agentFailureRate: roundRate(agentFailureRate),
|
|
189
|
-
agentFailureReasonCounts,
|
|
190
|
-
stuckActiveRuns,
|
|
191
|
-
logBackingRate: roundRate(logBackingRate),
|
|
192
|
-
probeRoundTripMs: null,
|
|
179
|
+
taskFailRate: roundRate(rates.taskFailRate),
|
|
180
|
+
agentFailureRate: roundRate(rates.agentFailureRate),
|
|
181
|
+
agentFailureReasonCounts: rates.agentFailureReasonCounts,
|
|
182
|
+
stuckActiveRuns: rates.stuckActiveRuns,
|
|
193
183
|
llmUsage: readLlmUsageAggregate(stateDbPath, since, until),
|
|
194
184
|
};
|
|
195
|
-
return { improve
|
|
185
|
+
return { improve, metrics, runs: runCount };
|
|
196
186
|
}
|