akm-cli 0.9.0-rc.8 → 0.9.0
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 +1063 -44
- package/README.md +51 -25
- package/SECURITY.md +14 -1
- package/STABILITY.md +497 -0
- package/dist/akm +148 -35
- package/dist/{akm-migrate-storage → akm-migrate} +6 -9
- package/dist/assets/hints/cli-hints-full.md +223 -95
- package/dist/assets/hints/cli-hints-short.md +85 -22
- package/dist/assets/improve-strategies/default.json +1 -1
- package/dist/assets/improve-strategies/reflect-distill.json +1 -1
- package/dist/assets/prompts/memory-infer-user.md +2 -3
- package/dist/assets/stash-skeleton/README.md +6 -5
- package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/domains.md +2 -0
- package/dist/assets/stash-skeleton/facts/conventions/organization.md +20 -9
- package/dist/assets/tasks/core/extract.yml +1 -1
- package/dist/assets/tasks/core/version-check.yml +1 -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 +1 -3
- package/dist/assets/workflows/workflow-template.md +32 -15
- package/dist/cli/invocation.js +40 -15
- package/dist/cli/parse-args.js +0 -22
- package/dist/cli/retired-commands.js +121 -0
- package/dist/cli/shared.js +154 -22
- package/dist/cli/unknown-flags.js +236 -0
- package/dist/cli-node.mjs +2 -1
- package/dist/cli.js +696 -258
- package/dist/commands/agent/agent-dispatch.js +14 -3
- package/dist/commands/agent/contribute-cli.js +73 -88
- package/dist/commands/completions.js +79 -22
- package/dist/commands/config-cli.js +17 -150
- package/dist/commands/env/env-cli.js +59 -143
- package/dist/commands/env/env.js +12 -163
- package/dist/commands/env/marker-path.js +6 -0
- package/dist/commands/env/secret-cli.js +36 -66
- package/dist/commands/env/secret.js +24 -57
- package/dist/commands/feedback-cli.js +141 -87
- package/dist/commands/health/accept-rate.js +58 -0
- package/dist/commands/health/advisories.js +3 -4
- package/dist/commands/health/checks.js +85 -23
- package/dist/commands/health/html-report.js +7 -10
- package/dist/commands/health/improve-metrics.js +25 -83
- package/dist/commands/health/md-report.js +5 -9
- package/dist/commands/health/metrics.js +62 -20
- package/dist/commands/health/renderers.js +47 -0
- package/dist/commands/health/report-view-model.js +4 -5
- package/dist/commands/health/stash-exposure.js +1 -1
- package/dist/commands/health/surfaces.js +3 -48
- package/dist/commands/health/task-runs.js +3 -67
- package/dist/commands/health/types-improve.js +7 -0
- package/dist/commands/health.js +99 -28
- package/dist/commands/improve/anti-collapse.js +2 -2
- package/dist/commands/improve/autonomy-gate.js +68 -0
- package/dist/commands/improve/collapse-detector.js +41 -40
- package/dist/commands/improve/consolidate/eligibility.js +1 -23
- package/dist/commands/improve/consolidate/merge.js +4 -0
- package/dist/commands/improve/consolidate.js +140 -1000
- package/dist/commands/improve/distill/promote-memory.js +12 -12
- package/dist/commands/improve/distill/quality-gate.js +6 -6
- package/dist/commands/improve/distill.js +58 -69
- package/dist/commands/improve/eligibility.js +105 -57
- package/dist/commands/improve/extract-cli.js +14 -133
- package/dist/commands/improve/improve-cli.js +98 -114
- package/dist/commands/improve/improve-result-file.js +1 -28
- package/dist/commands/improve/improve-strategies.js +8 -5
- package/dist/commands/improve/improve.js +128 -91
- package/dist/commands/improve/loop-stages.js +182 -20
- package/dist/commands/improve/memory/derived-ref.js +45 -43
- package/dist/commands/improve/memory/memory-belief.js +1 -1
- package/dist/commands/improve/memory/memory-contradiction-detect.js +4 -12
- package/dist/commands/improve/memory/memory-improve.js +6 -5
- package/dist/commands/improve/outcome-loop.js +22 -65
- package/dist/commands/improve/preparation.js +114 -123
- package/dist/commands/improve/proactive-maintenance.js +2 -5
- package/dist/commands/improve/reflect.js +56 -160
- package/dist/commands/improve/salience.js +11 -122
- package/dist/commands/improve/source-identity.js +10 -38
- package/dist/commands/lint/base-linter.js +20 -124
- package/dist/commands/lint/env-key-rules.js +31 -47
- package/dist/commands/lint/index.js +249 -43
- package/dist/commands/{events.js → log.js} +33 -38
- package/dist/commands/migrate-cli.js +92 -12
- package/dist/commands/migration-tool.js +46 -0
- package/dist/commands/observability-cli.js +70 -209
- package/dist/commands/proposal/drain.js +101 -29
- package/dist/commands/proposal/proposal-cli.js +76 -48
- package/dist/commands/proposal/proposal.js +54 -18
- package/dist/commands/proposal/propose-cli.js +88 -0
- package/dist/commands/proposal/propose.js +23 -15
- package/dist/commands/proposal/repository.js +701 -278
- package/dist/commands/proposal/validators/proposal-quality-validators.js +2 -8
- package/dist/commands/proposal/validators/proposal-validators.js +55 -7
- package/dist/commands/proposal/validators/proposals.js +4 -7
- package/dist/commands/read/curate.js +34 -53
- package/dist/commands/read/knowledge.js +150 -95
- package/dist/commands/read/registry-search.js +2 -2
- package/dist/commands/read/remember-cli.js +42 -15
- package/dist/commands/read/search-cli.js +180 -78
- package/dist/commands/read/search.js +58 -43
- package/dist/commands/read/show.js +197 -141
- package/dist/commands/registry-cli.js +12 -51
- package/dist/commands/remember.js +14 -57
- package/dist/commands/sources/add-cli.js +100 -31
- package/dist/commands/sources/bundle-cli.js +166 -0
- package/dist/commands/sources/bundle-config-ops.js +7 -2
- package/dist/commands/sources/info.js +18 -5
- package/dist/commands/sources/init.js +12 -12
- package/dist/commands/sources/installed-stashes.js +382 -98
- package/dist/commands/sources/schema-repair.js +3 -2
- package/dist/commands/sources/self-update.js +131 -38
- package/dist/commands/sources/source-add.js +72 -17
- package/dist/commands/sources/source-clone.js +129 -45
- package/dist/commands/sources/source-manage.js +43 -23
- package/dist/commands/sources/sources-cli.js +57 -208
- package/dist/commands/sources/stash-cli.js +46 -53
- package/dist/commands/tasks/tasks-cli.js +91 -97
- package/dist/commands/tasks/tasks.js +276 -421
- package/dist/commands/workflow-cli.js +175 -450
- package/dist/core/adapter/adapters/akm-adapter.js +47 -28
- package/dist/core/adapter/adapters/akm-lint.js +42 -27
- package/dist/core/adapter/adapters/akm-metadata.js +15 -44
- package/dist/core/adapter/adapters/akm-task-adapter.js +15 -13
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +55 -71
- package/dist/core/adapter/adapters/dotenv-adapter.js +1 -1
- package/dist/core/adapter/adapters/generic-files-adapter.js +2 -0
- package/dist/core/adapter/adapters/index.js +6 -6
- package/dist/core/adapter/adapters/llm-wiki-adapter.js +14 -8
- package/dist/core/adapter/adapters/okf-adapter.js +187 -19
- package/dist/core/adapter/adapters/shared.js +3 -19
- package/dist/core/adapter/adapters/tool-dir-shared.js +8 -3
- package/dist/core/adapter/adapters/website-snapshot-adapter.js +1 -0
- package/dist/core/adapter/detect-adapter.js +17 -0
- package/dist/core/adapter/recognize-match.js +6 -4
- package/dist/core/adapter/validate-context.js +214 -0
- package/dist/core/asset/akm-markdown.js +63 -0
- package/dist/core/asset/asset-placement.js +20 -6
- package/dist/core/asset/asset-ref.js +11 -9
- package/dist/core/asset/frontmatter-lint.js +30 -0
- package/dist/core/asset/frontmatter.js +37 -9
- package/dist/core/asset/markdown.js +40 -51
- package/dist/core/asset/resolve-ref.js +89 -18
- package/dist/core/asset/stash-meta.js +1 -1
- package/dist/core/bundle-id.js +51 -0
- package/dist/core/common.js +152 -38
- package/dist/core/config/config-io.js +12 -1
- package/dist/core/config/config-schema.js +35 -8
- package/dist/core/config/config-sources.js +55 -11
- package/dist/core/config/config-walker.js +25 -9
- package/dist/core/config/config.js +9 -48
- package/dist/core/config/experimental.js +21 -0
- package/dist/core/config/schema/embedding.js +5 -1
- package/dist/core/config/schema/experimental.js +30 -0
- package/dist/core/config/schema/improve-processes.js +0 -6
- package/dist/core/config/schema/improve.js +21 -3
- package/dist/core/config/schema/index-config.js +8 -15
- package/dist/core/config/schema/output.js +4 -1
- package/dist/core/config/schema/setup.js +9 -18
- package/dist/core/config/schema/sources-bundles.js +49 -33
- package/dist/core/config/schema/workflow.js +3 -3
- package/dist/core/env-secret-ref.js +76 -46
- package/dist/core/errors.js +18 -12
- package/dist/core/events.js +46 -128
- package/dist/core/file-change.js +6 -5
- package/dist/core/fs-txn.js +83 -7
- package/dist/core/git-message.js +2 -2
- package/dist/core/improve-result.js +1 -100
- package/dist/core/lesson-lint.js +1 -17
- package/dist/core/logs-db.js +2 -1
- package/dist/core/migration-operation.js +16 -0
- package/dist/core/mutation-target.js +78 -0
- package/dist/core/parse.js +4 -1
- package/dist/core/paths.js +17 -20
- package/dist/core/recognition-util.js +12 -14
- package/dist/core/redaction.js +34 -0
- package/dist/core/standards/resolve-standards-context.js +2 -14
- package/dist/core/standards/resolve-stash-standards.js +2 -2
- package/dist/core/standards/resolve-type-conventions.js +2 -2
- package/dist/core/state/migrations.js +41 -18
- package/dist/core/state-db.js +5 -14
- package/dist/core/structured.js +1 -1
- package/dist/core/subprocess.js +6 -4
- package/dist/core/text-truncation.js +9 -5
- package/dist/core/type-presentation.js +3 -3
- package/dist/core/warn.js +0 -3
- package/dist/core/write-source.js +771 -95
- package/dist/indexer/bundle-identity-guard.js +3 -2
- package/dist/indexer/db/graph-db.js +0 -24
- package/dist/indexer/ensure-index.js +1 -0
- package/dist/indexer/graph/graph-boost.js +9 -34
- package/dist/indexer/graph/graph-extraction.js +8 -5
- package/dist/indexer/index-writer-lock.js +53 -17
- package/dist/indexer/index-written-assets.js +16 -22
- package/dist/indexer/indexer.js +497 -239
- package/dist/indexer/installations.js +14 -96
- package/dist/indexer/passes/dir-staleness.js +16 -9
- package/dist/indexer/passes/memory-inference.js +11 -9
- package/dist/indexer/passes/metadata.js +113 -47
- package/dist/indexer/scan/doc-to-entry.js +38 -1
- package/dist/indexer/scan/drain-dir.js +13 -23
- package/dist/indexer/search/db-search.js +99 -54
- package/dist/indexer/search/fts-query.js +47 -24
- package/dist/indexer/search/ranking-contributors.js +42 -20
- package/dist/indexer/search/ranking.js +18 -99
- package/dist/indexer/search/search-fields.js +7 -2
- package/dist/indexer/search/search-source.js +82 -93
- package/dist/indexer/usage/usage-events.js +0 -89
- package/dist/indexer/walk/file-context.js +2 -1
- package/dist/indexer/walk/matchers.js +30 -43
- package/dist/indexer/walk/path-resolver.js +7 -2
- package/dist/indexer/walk/walker.js +38 -12
- package/dist/integrations/agent/builders.js +0 -6
- package/dist/integrations/agent/config.js +2 -2
- package/dist/integrations/agent/detect.js +49 -19
- package/dist/integrations/agent/engine-fallback.js +76 -0
- package/dist/integrations/agent/profiles.js +14 -0
- package/dist/integrations/agent/prompts.js +12 -8
- package/dist/integrations/agent/runner-dispatch.js +4 -2
- package/dist/integrations/agent/runner.js +0 -1
- package/dist/integrations/agent/spawn.js +5 -6
- package/dist/integrations/github.js +1 -1
- package/dist/integrations/harnesses/aider/agent-builder.js +6 -4
- package/dist/integrations/harnesses/amazonq/agent-builder.js +7 -4
- package/dist/integrations/harnesses/claude/session-log.js +0 -10
- package/dist/integrations/harnesses/codex/agent-builder.js +5 -2
- package/dist/integrations/harnesses/copilot/agent-builder.js +5 -3
- package/dist/integrations/harnesses/gemini/agent-builder.js +5 -3
- package/dist/integrations/harnesses/index.js +3 -7
- package/dist/integrations/harnesses/opencode/agent-builder.js +21 -2
- package/dist/integrations/harnesses/opencode/session-log.js +0 -15
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +13 -4
- package/dist/integrations/harnesses/openhands/agent-builder.js +9 -6
- package/dist/integrations/harnesses/pi/agent-builder.js +6 -4
- package/dist/integrations/lockfile.js +101 -6
- package/dist/integrations/session-logs/index.js +3 -28
- package/dist/llm/client.js +136 -100
- package/dist/llm/embedders/remote.js +13 -5
- package/dist/llm/feature-gate.js +4 -12
- package/dist/llm/graph-extract.js +5 -11
- package/dist/llm/memory-infer.js +144 -1
- package/dist/llm/metadata-enhance.js +5 -7
- package/dist/llm/structured-call.js +1 -1
- package/dist/llm/usage-persist.js +26 -5
- package/dist/llm/usage-telemetry.js +25 -2
- package/dist/output/cli-hints.js +1 -2
- package/dist/output/context.js +22 -7
- package/dist/output/format-exempt.js +80 -0
- package/dist/output/generic-render.js +259 -0
- package/dist/output/render-registry.js +57 -0
- package/dist/output/renderers.js +14 -36
- package/dist/output/shapes/curate.js +10 -1
- package/dist/output/shapes/events.js +12 -7
- package/dist/output/shapes/helpers.js +56 -83
- package/dist/output/shapes/migrate.js +8 -0
- package/dist/output/shapes/passthrough.js +7 -41
- package/dist/output/shapes/proposal/producer.js +15 -7
- package/dist/output/shapes.js +2 -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 +164 -96
- package/dist/output/text/env.js +1 -3
- package/dist/output/text/events.js +8 -7
- package/dist/output/text/health-format.js +103 -0
- package/dist/output/text/health.js +7 -0
- package/dist/output/text/helpers.js +10 -8
- package/dist/output/text/lint-format.js +43 -0
- package/dist/output/text/{save.js → lint.js} +2 -2
- package/dist/output/text/migrate.js +88 -0
- package/dist/output/text/proposal/producer.js +4 -2
- package/dist/output/text/proposal-format.js +44 -72
- package/dist/output/text/registry-commands.js +1 -2
- package/dist/output/text/show-directives.js +15 -7
- package/dist/output/text/status-list.js +32 -0
- package/dist/output/text/sync.js +5 -0
- package/dist/output/text/workflow-format.js +24 -203
- package/dist/output/text/workflow.js +1 -7
- package/dist/output/text.js +16 -17
- 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 +13 -23
- package/dist/registry/resolve.js +42 -7
- package/dist/registry/semver.js +34 -84
- package/dist/runtime.js +2 -23
- package/dist/scripts/akm-migrate-node.js +60290 -0
- package/dist/scripts/akm-migrate.js +59628 -0
- package/dist/setup/detect.js +42 -15
- package/dist/setup/registry-stash-loader.js +2 -2
- package/dist/setup/setup.js +236 -136
- package/dist/setup/steps/connection.js +7 -9
- package/dist/setup/steps/platforms.js +9 -9
- package/dist/setup/steps/semantic.js +15 -3
- package/dist/setup/steps/sources.js +12 -13
- package/dist/setup/steps/stashdir.js +2 -3
- package/dist/setup/steps/tasks.js +237 -120
- package/dist/sources/freshness.js +1 -1
- 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 +25 -23
- package/dist/sources/providers/git-stash.js +395 -106
- package/dist/sources/providers/git.js +2 -2
- package/dist/sources/providers/npm.js +16 -19
- package/dist/sources/providers/provider-utils.js +7 -4
- package/dist/sources/providers/sync-from-ref.js +3 -9
- package/dist/sources/providers/website.js +6 -1
- package/dist/sources/resolve.js +6 -5
- package/dist/sources/snapshot-fetchers/bluesky.js +146 -0
- package/dist/sources/snapshot-fetchers/content-extract.js +566 -0
- package/dist/sources/snapshot-fetchers/fetcher-util.js +41 -0
- package/dist/sources/snapshot-fetchers/github.js +100 -0
- package/dist/sources/snapshot-fetchers/host-guard.js +291 -0
- package/dist/sources/snapshot-fetchers/registry.js +17 -1
- package/dist/sources/snapshot-fetchers/robots.js +348 -0
- package/dist/sources/snapshot-fetchers/rss.js +282 -0
- package/dist/sources/snapshot-fetchers/secret-seam.js +42 -0
- package/dist/sources/snapshot-fetchers/website-ingest.js +566 -268
- package/dist/sources/snapshot-fetchers/x.js +910 -0
- package/dist/storage/database.js +7 -0
- package/dist/storage/engines/sqlite-migrations.js +23 -111
- package/dist/storage/managed-db.js +2 -2
- package/dist/storage/repositories/canaries-repository.js +1 -1
- package/dist/storage/repositories/events-repository.js +27 -11
- package/dist/storage/repositories/improve-runs-repository.js +6 -12
- package/dist/storage/repositories/index-connection.js +17 -6
- package/dist/storage/repositories/index-entries-repository.js +151 -240
- package/dist/storage/repositories/index-entry-mapper.js +15 -11
- package/dist/storage/repositories/index-fts-repository.js +5 -2
- package/dist/storage/repositories/index-llm-cache-repository.js +0 -1
- package/dist/storage/repositories/index-meta-repository.js +2 -3
- package/dist/storage/repositories/index-schema.js +10 -25
- package/dist/storage/repositories/index-utility-repository.js +15 -28
- package/dist/storage/repositories/index-vec-repository.js +6 -1
- package/dist/storage/repositories/outcome-repository.js +119 -0
- package/dist/storage/repositories/proposals-repository.js +296 -59
- package/dist/storage/repositories/registry-cache.js +19 -0
- package/dist/storage/repositories/salience-repository.js +172 -0
- package/dist/storage/repositories/task-history-repository.js +15 -13
- package/dist/storage/repositories/workflow-runs-repository.js +52 -40
- package/dist/tasks/backends/cron.js +105 -15
- package/dist/tasks/backends/index.js +1 -1
- package/dist/tasks/backends/launchd.js +85 -38
- package/dist/tasks/backends/schtasks.js +135 -15
- package/dist/tasks/embedded.js +56 -40
- package/dist/tasks/parser.js +7 -157
- package/dist/tasks/resolve-akm-bin.js +137 -59
- package/dist/tasks/runner.js +79 -42
- package/dist/tasks/scheduler-invocation.js +220 -10
- package/dist/tasks/schema.js +24 -1
- package/dist/tasks/task-id.js +1 -3
- package/dist/tasks/validator.js +20 -6
- package/dist/workflows/authoring/authoring.js +94 -143
- package/dist/workflows/authoring/scope-key.js +1 -1
- package/dist/workflows/exec/frozen-judge.js +28 -2
- package/dist/workflows/exec/native-executor.js +77 -57
- package/dist/workflows/exec/param-secrets.js +9 -9
- package/dist/workflows/exec/run-workflow.js +133 -79
- package/dist/workflows/exec/step-work.js +219 -346
- package/dist/{migrate-storage-node.mjs → workflows/exec/unit-dispatch.js} +1 -5
- package/dist/workflows/ir/compile.js +141 -270
- package/dist/workflows/ir/freeze.js +40 -30
- package/dist/workflows/ir/params.js +135 -11
- package/dist/workflows/ir/plan-hash.js +1 -1
- package/dist/workflows/ir/schema.js +25 -26
- package/dist/workflows/parser.js +872 -307
- package/dist/workflows/program/expressions.js +20 -208
- package/dist/workflows/program/schema.js +7 -10
- package/dist/workflows/renderer.js +95 -68
- package/dist/workflows/resource-limits.js +2 -0
- package/dist/workflows/runtime/checkin.js +3 -3
- package/dist/workflows/runtime/plan-classifier.js +16 -75
- package/dist/workflows/runtime/runs.js +186 -127
- package/dist/workflows/runtime/unit-checkin.js +1 -1
- package/dist/workflows/runtime/unit-phases.js +2 -2
- package/dist/workflows/runtime/workflow-asset-loader.js +232 -83
- package/dist/workflows/schema.js +1 -11
- package/dist/workflows/validate-summary.js +30 -36
- package/dist/workflows/validator.js +21 -62
- package/docs/README.md +68 -0
- package/docs/migration/README.md +8 -0
- package/docs/migration/release-notes/0.7.0.md +11 -11
- package/docs/migration/release-notes/0.9.0.md +208 -27
- package/docs/migration/v0.7-to-v0.8.md +46 -47
- package/docs/migration/v0.8-to-v0.9.md +564 -208
- package/docs/migration/v0.9.0-troubleshooting.md +561 -0
- package/docs/reference/README.md +12 -0
- package/docs/reference/cli.md +2253 -0
- package/docs/reference/configuration.md +358 -0
- package/docs/reference/data-and-telemetry.md +105 -42
- package/docs/reference/workflows.md +647 -0
- package/package.json +22 -11
- package/schemas/akm-asset-envelope.json +93 -0
- package/schemas/akm-config.json +81 -128
- package/schemas/akm-workflow.json +74 -73
- package/dist/assets/tasks/core/backup.yml +0 -5
- package/dist/assets/tasks/graph-refresh-weekly.yml +0 -10
- package/dist/cli/config-migrate.js +0 -1806
- package/dist/cli/config-validate.js +0 -41
- package/dist/commands/backup-cli.js +0 -56
- package/dist/commands/bundle/bundle-cli.js +0 -68
- package/dist/commands/bundle/bundle.js +0 -219
- package/dist/commands/graph/graph-cli.js +0 -124
- package/dist/commands/graph/graph.js +0 -489
- package/dist/commands/improve/extract-watch.js +0 -140
- package/dist/commands/mv-cli.js +0 -1221
- package/dist/commands/sources/history.js +0 -201
- package/dist/commands/tasks/default-tasks.js +0 -186
- package/dist/core/migration-backup.js +0 -1234
- package/dist/indexer/usage/unmigrated-vaults-guard.js +0 -95
- package/dist/llm/memory-infer-impl.js +0 -138
- package/dist/migrate/legacy/config-source-migration.js +0 -223
- package/dist/migrate/legacy/content-migration.js +0 -305
- package/dist/migrate/legacy/legacy-layout.js +0 -779
- package/dist/migrate/legacy/legacy-paths.js +0 -25
- package/dist/migrate/legacy/legacy-stash-json.js +0 -72
- package/dist/migrate/legacy/proposal-fs-import.js +0 -168
- package/dist/migrate/legacy/task-target-ref-migration.js +0 -272
- package/dist/migrate/legacy/three-db-cutover.js +0 -841
- package/dist/migrate/legacy/workflow-migrations-bodies.js +0 -52
- package/dist/migrate/legacy/workflow-migrations-frozen.js +0 -21
- package/dist/migrate/legacy-ref-grammar.js +0 -214
- 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/registry/build-index.js +0 -382
- package/dist/schemas/akm-config.json +0 -4704
- package/dist/schemas/akm-task.json +0 -87
- package/dist/schemas/akm-workflow.json +0 -372
- package/dist/scripts/migrate-storage.js +0 -3816
- package/dist/workflows/authoring/workflow-program-template.yaml +0 -31
- package/dist/workflows/cli.js +0 -53
- package/dist/workflows/exec/brief.js +0 -481
- package/dist/workflows/exec/report.js +0 -1460
- package/dist/workflows/exec/watch.js +0 -116
- package/dist/workflows/program/parser.js +0 -813
- package/dist/workflows/program/project.js +0 -104
|
@@ -4,11 +4,10 @@
|
|
|
4
4
|
/**
|
|
5
5
|
* The remaining `surfaces` advisory group for `akm health` (meta-review 08).
|
|
6
6
|
* `stash-git-exposure` (08-F1) shipped first in ./stash-exposure.ts; this
|
|
7
|
-
* module adds the other
|
|
7
|
+
* module adds the other three read-only checks the adjudication approved:
|
|
8
8
|
*
|
|
9
9
|
* - `secret-file-perms` — env/secret/backup files not 0600, dirs not 0700 (F4)
|
|
10
10
|
* - `binary-config-skew` — config.json written by a NEWER akm than this binary (F3)
|
|
11
|
-
* - `orphan-stores` — legacy config-backups dirs + 0-byte stash state.db decoy (F4/F7)
|
|
12
11
|
* - `egress-endpoints` — the remote-destination list, for eyeball diff (surfaces 3/9)
|
|
13
12
|
*
|
|
14
13
|
* Every collector is a pure projection over injected paths/config (no
|
|
@@ -120,49 +119,6 @@ export function collectConfigSkewAdvisory(configPath) {
|
|
|
120
119
|
evidence: { onDiskConfigVersion: onDisk, binaryConfigVersion: CURRENT_CONFIG_VERSION },
|
|
121
120
|
};
|
|
122
121
|
}
|
|
123
|
-
/**
|
|
124
|
-
* `orphan-stores` (08-F4/F7): stores that look load-bearing but are dead —
|
|
125
|
-
* legacy `config-backups/` dirs in $DATA/$CONFIG (only `$CACHE/config-backups`
|
|
126
|
-
* is written and pruned today) and a 0-byte `<stash>/.akm/state.db` decoy that
|
|
127
|
-
* misleads debugging (the live state.db lives in the data dir). Read-only:
|
|
128
|
-
* this advisory NAMES them; removal stays an owner-approved per-path action.
|
|
129
|
-
*/
|
|
130
|
-
export function collectOrphanStoresAdvisory(input) {
|
|
131
|
-
const orphans = [];
|
|
132
|
-
for (const [label, dir] of [
|
|
133
|
-
["legacy data-dir backup location", path.join(input.dataDir, "config-backups")],
|
|
134
|
-
["legacy config-dir backup location", path.join(input.configDir, "config-backups")],
|
|
135
|
-
]) {
|
|
136
|
-
try {
|
|
137
|
-
if (fs.statSync(dir).isDirectory())
|
|
138
|
-
orphans.push(`${dir}/ (${label}; live backups are in $CACHE/config-backups)`);
|
|
139
|
-
}
|
|
140
|
-
catch {
|
|
141
|
-
// absent — fine
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
const decoy = path.join(input.stashDir, ".akm", "state.db");
|
|
145
|
-
try {
|
|
146
|
-
const stat = fs.statSync(decoy);
|
|
147
|
-
if (stat.isFile() && stat.size === 0) {
|
|
148
|
-
orphans.push(`${decoy} (0-byte decoy; the live state.db is in the data dir)`);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
catch {
|
|
152
|
-
// absent — fine
|
|
153
|
-
}
|
|
154
|
-
if (orphans.length === 0)
|
|
155
|
-
return undefined;
|
|
156
|
-
return {
|
|
157
|
-
name: "orphan-stores",
|
|
158
|
-
kind: "deterministic",
|
|
159
|
-
status: "warn",
|
|
160
|
-
confidence: "high",
|
|
161
|
-
message: `${orphans.length} orphan store(s) found: ${orphans.join("; ")}. ` +
|
|
162
|
-
"These are dead locations that mislead debugging/recovery — review and remove them (owner-approved, per-path).",
|
|
163
|
-
evidence: { orphans },
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
122
|
/**
|
|
167
123
|
* `egress-endpoints` (08 surfaces 3/9): the full list of remote destinations
|
|
168
124
|
* akm can talk to under the effective config — registries, remote sources,
|
|
@@ -207,14 +163,13 @@ export function collectEgressAdvisory(config) {
|
|
|
207
163
|
};
|
|
208
164
|
}
|
|
209
165
|
/**
|
|
210
|
-
* Aggregate the
|
|
211
|
-
* consumes. Order is fixed: perms → skew →
|
|
166
|
+
* Aggregate the three collectors into the advisories array shape `akmHealth`
|
|
167
|
+
* consumes. Order is fixed: perms → skew → egress.
|
|
212
168
|
*/
|
|
213
169
|
export function collectSurfacesAdvisories(input) {
|
|
214
170
|
const results = [
|
|
215
171
|
collectSecretPermsAdvisory({ stashDir: input.stashDir, cacheDir: input.cacheDir }, input.platform ?? process.platform),
|
|
216
172
|
collectConfigSkewAdvisory(input.configPath),
|
|
217
|
-
collectOrphanStoresAdvisory({ dataDir: input.dataDir, configDir: input.configDir, stashDir: input.stashDir }),
|
|
218
173
|
collectEgressAdvisory(input.config),
|
|
219
174
|
];
|
|
220
175
|
return results.filter((r) => r !== undefined);
|
|
@@ -2,57 +2,8 @@
|
|
|
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
|
import { queryImproveRuns } from "../../storage/repositories/improve-runs-repository.js";
|
|
5
|
-
import {
|
|
5
|
+
import { queryTaskHistory } from "../../storage/repositories/task-history-repository.js";
|
|
6
6
|
import { projectImproveRunSummary } from "./improve-metrics.js";
|
|
7
|
-
/**
|
|
8
|
-
* Load task_history intervals for `task_id='akm-improve'` in the window.
|
|
9
|
-
* Returned sorted by startMs ascending so containment lookups can use a
|
|
10
|
-
* linear scan (typical N is ~24/day; not worth a tree).
|
|
11
|
-
*
|
|
12
|
-
* The window filter is widened by 5 minutes on each side because the cron
|
|
13
|
-
* task wraps `akm improve` — the task `started_at` fires at e.g. :07:01
|
|
14
|
-
* while `recordImproveRun` writes the matching `improve_runs.started_at`
|
|
15
|
-
* later (after config load, planning, etc.), so the improve_runs row can
|
|
16
|
-
* be inside the window even when its enclosing task_history row started
|
|
17
|
-
* just before the window opened.
|
|
18
|
-
*/
|
|
19
|
-
function loadTaskIntervals(db, since, until) {
|
|
20
|
-
const sinceMs = new Date(since).getTime();
|
|
21
|
-
const untilMs = until ? new Date(until).getTime() : Number.POSITIVE_INFINITY;
|
|
22
|
-
const widenedSince = new Date(sinceMs - 5 * 60 * 1000).toISOString();
|
|
23
|
-
const widenedUntil = Number.isFinite(untilMs) ? new Date(untilMs + 5 * 60 * 1000).toISOString() : undefined;
|
|
24
|
-
const rows = queryCompletedTaskIntervals(db, widenedSince, widenedUntil);
|
|
25
|
-
const intervals = [];
|
|
26
|
-
for (const row of rows) {
|
|
27
|
-
const startMs = new Date(row.started_at).getTime();
|
|
28
|
-
const endMs = new Date(row.completed_at).getTime();
|
|
29
|
-
if (!Number.isFinite(startMs) || !Number.isFinite(endMs) || endMs < startMs)
|
|
30
|
-
continue;
|
|
31
|
-
intervals.push({ startMs, endMs, durationMs: endMs - startMs });
|
|
32
|
-
}
|
|
33
|
-
return intervals;
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Find the task_history interval that contains the given timestamp. The
|
|
37
|
-
* task wraps `akm improve`, so `improve_runs.started_at` (when
|
|
38
|
-
* `recordImproveRun` writes) always falls inside the enclosing task's
|
|
39
|
-
* [started_at, completed_at]. Returns undefined when no interval
|
|
40
|
-
* contains the timestamp (which happens for manually-invoked improve
|
|
41
|
-
* runs not driven by the `akm-improve` task).
|
|
42
|
-
*
|
|
43
|
-
* Linear scan because N is small. We tolerate a 1s slop on the upper
|
|
44
|
-
* bound to handle clock skew between the wrapper's `completed_at` write
|
|
45
|
-
* and recordImproveRun's `started_at` write.
|
|
46
|
-
*/
|
|
47
|
-
function findContainingTaskInterval(timestampMs, intervals) {
|
|
48
|
-
const SLOP_MS = 1000;
|
|
49
|
-
for (const interval of intervals) {
|
|
50
|
-
if (timestampMs >= interval.startMs && timestampMs <= interval.endMs + SLOP_MS) {
|
|
51
|
-
return interval;
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
return undefined;
|
|
55
|
-
}
|
|
56
7
|
/**
|
|
57
8
|
* Load `task_history` rows whose `task_id` begins `akm-improve` (the scheduled
|
|
58
9
|
* improve tasks: `akm-improve-frequent`, `akm-improve-proactive-weekly`, …) in
|
|
@@ -88,7 +39,7 @@ export function matchImproveTaskId(startedAt, completedAt, taskRuns) {
|
|
|
88
39
|
const startMs = new Date(startedAt).getTime();
|
|
89
40
|
if (!Number.isFinite(startMs))
|
|
90
41
|
return "manual";
|
|
91
|
-
const endMs =
|
|
42
|
+
const endMs = new Date(completedAt).getTime();
|
|
92
43
|
let best;
|
|
93
44
|
let bestScore = Number.POSITIVE_INFINITY;
|
|
94
45
|
for (const task of taskRuns) {
|
|
@@ -107,27 +58,12 @@ export function matchImproveTaskId(startedAt, completedAt, taskRuns) {
|
|
|
107
58
|
}
|
|
108
59
|
export function buildPerRunSummaries(db, since, until) {
|
|
109
60
|
const rows = queryImproveRuns(db, since, until);
|
|
110
|
-
const taskIntervals = loadTaskIntervals(db, since, until);
|
|
111
61
|
const improveTaskRuns = loadImproveTaskRuns(db, since, until);
|
|
112
62
|
const summaries = [];
|
|
113
63
|
for (const row of rows) {
|
|
114
64
|
const startMs = new Date(row.started_at).getTime();
|
|
115
65
|
const endMs = new Date(row.completed_at).getTime();
|
|
116
|
-
|
|
117
|
-
// recordImproveRun now persists distinct start/end timestamps, so the
|
|
118
|
-
// row's own delta is the authoritative per-run wall time even for
|
|
119
|
-
// manually-invoked `akm improve` runs with no enclosing task_history.
|
|
120
|
-
// Only fall back to the task_history containing-interval join for legacy/
|
|
121
|
-
// backfill rows where started_at == completed_at (row delta is 0).
|
|
122
|
-
const hasRowDelta = Number.isFinite(startMs) && Number.isFinite(endMs) && endMs > startMs;
|
|
123
|
-
let wallTimeMs;
|
|
124
|
-
if (hasRowDelta) {
|
|
125
|
-
wallTimeMs = endMs - startMs;
|
|
126
|
-
}
|
|
127
|
-
else {
|
|
128
|
-
const interval = Number.isFinite(startMs) ? findContainingTaskInterval(startMs, taskIntervals) : undefined;
|
|
129
|
-
wallTimeMs = interval?.durationMs ?? 0;
|
|
130
|
-
}
|
|
66
|
+
const wallTimeMs = Number.isFinite(startMs) && Number.isFinite(endMs) && endMs >= startMs ? endMs - startMs : 0;
|
|
131
67
|
const taskId = matchImproveTaskId(row.started_at, row.completed_at, improveTaskRuns);
|
|
132
68
|
summaries.push(projectImproveRunSummary(row, wallTimeMs, taskId));
|
|
133
69
|
}
|
|
@@ -20,3 +20,10 @@ export const ENRICHMENT_MINTED_FAIL_SHARE = 0.15;
|
|
|
20
20
|
* source so the advisory and the rendered badge cannot drift.
|
|
21
21
|
*/
|
|
22
22
|
export const TASK_FAIL_RATE_WARN = 0.05;
|
|
23
|
+
/**
|
|
24
|
+
* Minimum task_history rows a single task_id needs in the window before its
|
|
25
|
+
* per-task fail rate feeds the `task-fail-rate` advisory's "worst single
|
|
26
|
+
* task" signal. Guards against a rarely-run task (e.g. 1 failure out of 1
|
|
27
|
+
* run) reading as a 100% fail rate off a single noisy sample.
|
|
28
|
+
*/
|
|
29
|
+
export const MIN_ROWS_FOR_WORST_TASK_FAIL_RATE = 5;
|
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";
|
|
@@ -22,7 +23,7 @@ import { computeDegradationMetrics, computeDenominatorFixedCoverage, computeEnri
|
|
|
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,52 @@ 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
|
+
}
|
|
63
110
|
/** Table presence, the state.db round-trip probe, and task_history-derived rates. */
|
|
64
111
|
function gatherTaskHistoryPhase(db, logsDb, since, stateDbPath, now) {
|
|
65
112
|
const tables = listExistingTableNames(db, ["events", "task_history", "proposals", "schema_migrations"]);
|
|
@@ -71,7 +118,7 @@ function gatherTaskHistoryPhase(db, logsDb, since, stateDbPath, now) {
|
|
|
71
118
|
const { withLogs: taskRowsWithLogs, backed: existingLogRows } = partitionLogBackedRows(taskRows, logsDb);
|
|
72
119
|
const failedTaskRows = taskRows.filter((row) => row.status === "failed");
|
|
73
120
|
const activeRows = taskRows.filter((row) => row.status === "active" && row.completed_at === null);
|
|
74
|
-
const
|
|
121
|
+
const stuckActiveRows = activeRows.filter((row) => now() - new Date(row.started_at).getTime() > ACTIVE_RUN_WARN_MS);
|
|
75
122
|
const promptRows = taskRows.filter((row) => row.target_kind === "prompt");
|
|
76
123
|
const promptFailures = promptRows.filter((row) => {
|
|
77
124
|
const detail = parseTaskMetadata(row).detail;
|
|
@@ -87,12 +134,45 @@ function gatherTaskHistoryPhase(db, logsDb, since, stateDbPath, now) {
|
|
|
87
134
|
taskRowCount: taskRows.length,
|
|
88
135
|
taskRowsWithLogsCount: taskRowsWithLogs.length,
|
|
89
136
|
existingLogRowsCount: existingLogRows.length,
|
|
90
|
-
stuckActiveRuns,
|
|
137
|
+
stuckActiveRuns: stuckActiveRows.length,
|
|
138
|
+
stuckActiveTasks: dedupeStuckActiveTasks(stuckActiveRows, now),
|
|
91
139
|
logBackingRate,
|
|
92
140
|
taskFailRate,
|
|
141
|
+
worstTaskFailRate: computeWorstTaskFailRate(taskRows),
|
|
93
142
|
agentFailureRate,
|
|
94
143
|
};
|
|
95
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
|
+
}
|
|
96
176
|
/**
|
|
97
177
|
* Semantic-search status + the config fields the embedding-endpoint and
|
|
98
178
|
* surfaces advisories need. Best-effort: an unloadable config leaves the
|
|
@@ -148,8 +228,8 @@ function gatherImproveSummaryPhase(db, stateDbPath, since, now) {
|
|
|
148
228
|
/**
|
|
149
229
|
* The three best-effort advisory groups beyond the health-check registry:
|
|
150
230
|
* improve advisories, the `stash-git-exposure` probe, and the 08 surfaces
|
|
151
|
-
* group (secret-file-perms, binary-config-skew,
|
|
152
|
-
*
|
|
231
|
+
* group (secret-file-perms, binary-config-skew, egress-endpoints). Order
|
|
232
|
+
* matches emission order in the returned array. A
|
|
153
233
|
* probe/filesystem failure in either try/catch must not abort the health
|
|
154
234
|
* report — each group degrades to "no advisory" independently.
|
|
155
235
|
*/
|
|
@@ -175,14 +255,12 @@ function gatherAncillaryAdvisories(db, stateDbPath, since, improveSummary, optio
|
|
|
175
255
|
// Non-fatal — a git/probe failure must not abort the health report.
|
|
176
256
|
}
|
|
177
257
|
// 08 surfaces: the remaining read-only advisory group (secret-file-perms,
|
|
178
|
-
// binary-config-skew,
|
|
258
|
+
// binary-config-skew, egress-endpoints). Best-effort — a
|
|
179
259
|
// filesystem probe failure must not abort the health report.
|
|
180
260
|
try {
|
|
181
261
|
advisories.push(...collectSurfacesAdvisories({
|
|
182
262
|
stashDir: options.stashDir ?? resolveStashDir(),
|
|
183
263
|
cacheDir: getCacheDir(),
|
|
184
|
-
dataDir: getDataDir(),
|
|
185
|
-
configDir: getConfigDir(),
|
|
186
264
|
configPath: getConfigPath(),
|
|
187
265
|
config: egressConfigView,
|
|
188
266
|
}));
|
|
@@ -209,11 +287,10 @@ function gatherSessionLogAdvisories(since, now, getExecutionLogCandidatesFn) {
|
|
|
209
287
|
}
|
|
210
288
|
/**
|
|
211
289
|
* Phase 3 — window-compare mode. Resolves `--window-compare`/`--windows` into
|
|
212
|
-
* per-window bundles
|
|
213
|
-
*
|
|
214
|
-
* shape) and computes deltas between the earliest and latest window.
|
|
290
|
+
* per-window bundles and computes deltas between the earliest and latest
|
|
291
|
+
* window. Top-level metrics retain the primary `--since` query.
|
|
215
292
|
*/
|
|
216
|
-
function resolveWindowComparePhase(options, db, stateDbPath, now, logsDb
|
|
293
|
+
function resolveWindowComparePhase(options, db, stateDbPath, now, logsDb) {
|
|
217
294
|
let windowSpecs;
|
|
218
295
|
if (options.windowCompare) {
|
|
219
296
|
windowSpecs = resolveWindowCompare(options.windowCompare, now);
|
|
@@ -223,9 +300,6 @@ function resolveWindowComparePhase(options, db, stateDbPath, now, logsDb, probe,
|
|
|
223
300
|
}
|
|
224
301
|
let windowResults;
|
|
225
302
|
let deltas;
|
|
226
|
-
let topLevelImprove = improveSummary;
|
|
227
|
-
let topLevelMetrics = metrics;
|
|
228
|
-
let topLevelSince = since;
|
|
229
303
|
if (windowSpecs) {
|
|
230
304
|
windowResults = windowSpecs.map((spec) => {
|
|
231
305
|
const winSince = parseHealthSince(spec.since);
|
|
@@ -240,13 +314,6 @@ function resolveWindowComparePhase(options, db, stateDbPath, now, logsDb, probe,
|
|
|
240
314
|
metrics: bundle.metrics,
|
|
241
315
|
};
|
|
242
316
|
});
|
|
243
|
-
// Preserve backward compat: top-level improve/metrics reflect window 0.
|
|
244
|
-
if (windowResults.length > 0) {
|
|
245
|
-
const firstWindow = windowResults[0];
|
|
246
|
-
topLevelImprove = firstWindow.improve;
|
|
247
|
-
topLevelMetrics = { ...firstWindow.metrics, probeRoundTripMs: probe.durationMs };
|
|
248
|
-
topLevelSince = firstWindow.since;
|
|
249
|
-
}
|
|
250
317
|
if (windowResults.length >= 2) {
|
|
251
318
|
// Deltas always read chronologically: `from` = earliest window,
|
|
252
319
|
// `to` = latest. Positive pctChange on a failure metric (e.g.
|
|
@@ -259,7 +326,7 @@ function resolveWindowComparePhase(options, db, stateDbPath, now, logsDb, probe,
|
|
|
259
326
|
deltas = computeDeltas(sorted[0], sorted[sorted.length - 1]);
|
|
260
327
|
}
|
|
261
328
|
}
|
|
262
|
-
return { windowResults, deltas
|
|
329
|
+
return { windowResults, deltas };
|
|
263
330
|
}
|
|
264
331
|
export function akmHealth(options = {}) {
|
|
265
332
|
validateAkmHealthOptions(options);
|
|
@@ -289,6 +356,7 @@ export function akmHealth(options = {}) {
|
|
|
289
356
|
try {
|
|
290
357
|
const taskHistory = gatherTaskHistoryPhase(db, logsDb, since, stateDbPath, now);
|
|
291
358
|
const { tableNames, missingTables, probe } = taskHistory;
|
|
359
|
+
const staleTxnJournals = gatherStaleTxnJournalsPhase(now);
|
|
292
360
|
const { semanticStatus, semanticSearchMode, embeddingEndpoint, egressConfigView } = gatherSemanticConfigPhase();
|
|
293
361
|
const { improveSummary } = gatherImproveSummaryPhase(db, stateDbPath, since, now);
|
|
294
362
|
advisories.push(...gatherAncillaryAdvisories(db, stateDbPath, since, improveSummary, options, egressConfigView));
|
|
@@ -309,6 +377,9 @@ export function akmHealth(options = {}) {
|
|
|
309
377
|
existingLogRowsCount: taskHistory.existingLogRowsCount,
|
|
310
378
|
logBackingRate: taskHistory.logBackingRate,
|
|
311
379
|
stuckActiveRuns: taskHistory.stuckActiveRuns,
|
|
380
|
+
stuckActiveTasks: taskHistory.stuckActiveTasks,
|
|
381
|
+
worstTaskFailRate: taskHistory.worstTaskFailRate,
|
|
382
|
+
staleTxnJournals,
|
|
312
383
|
semanticStatus,
|
|
313
384
|
semanticSearchMode,
|
|
314
385
|
embeddingEndpoint,
|
|
@@ -335,7 +406,7 @@ export function akmHealth(options = {}) {
|
|
|
335
406
|
const deterministicWarnings = [...hardChecks, ...advisories].some((check) => check.status === "warn" && check.kind === "deterministic");
|
|
336
407
|
const status = hardFailure ? "fail" : deterministicWarnings ? "warn" : "pass";
|
|
337
408
|
// ── Window-compare mode (Phase 3) ─────────────────────────────────────
|
|
338
|
-
const { windowResults, deltas
|
|
409
|
+
const { windowResults, deltas } = resolveWindowComparePhase(options, db, stateDbPath, now, logsDb);
|
|
339
410
|
// ── Per-run mode (Phase 2) ────────────────────────────────────────────
|
|
340
411
|
let runs;
|
|
341
412
|
if (options.groupBy === "run") {
|
|
@@ -345,11 +416,11 @@ export function akmHealth(options = {}) {
|
|
|
345
416
|
schemaVersion: 3,
|
|
346
417
|
ok: !hardFailure,
|
|
347
418
|
status,
|
|
348
|
-
since
|
|
419
|
+
since,
|
|
349
420
|
hardChecks,
|
|
350
421
|
advisories,
|
|
351
|
-
metrics
|
|
352
|
-
improve:
|
|
422
|
+
metrics,
|
|
423
|
+
improve: improveSummary,
|
|
353
424
|
sessionLogAdvisories: sessionLogEntries,
|
|
354
425
|
...(runs ? { runs } : {}),
|
|
355
426
|
...(windowResults ? { windows: windowResults } : {}),
|
|
@@ -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));
|
|
@@ -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
|
+
}
|