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
package/dist/core/errors.js
CHANGED
|
@@ -11,13 +11,13 @@ const CONFIG_HINTS = {
|
|
|
11
11
|
STASH_DIR_UNREADABLE: "Check the path exists and your user has read permission, or update the default bundle path.",
|
|
12
12
|
DATA_DIR_UNREADABLE: "The data directory is not readable by the user running akm. Check its owner and mode, or point AKM_DATA_DIR / XDG_DATA_HOME somewhere this user owns.",
|
|
13
13
|
INDEX_SCHEMA_INCOMPATIBLE: "Run `akm index --full` to rebuild the derived index from the currently materialized sources.",
|
|
14
|
-
EMBEDDING_NOT_CONFIGURED: 'Run `akm config set embedding \'{"endpoint":"...","model":"..."}\'` to enable embeddings.',
|
|
15
14
|
LLM_NOT_CONFIGURED: 'Run `akm setup` or configure an `engines` entry with `kind: "llm"`, then select it with `defaults.llmEngine`.',
|
|
16
15
|
TEST_ISOLATION_MISSING: "Under bun test, when AKM_BUNDLE_DIR is set you MUST also set XDG_DATA_HOME (or AKM_DATA_DIR) and XDG_STATE_HOME (or AKM_STATE_DIR) to temp directories so the test does not touch the developer's real ~/.local/share/akm or ~/.local/state/akm.",
|
|
17
16
|
UNSAFE_STASH_DIR: "Choose a path inside your home directory (e.g. ~/akm) or another empty workspace. The bundle directory cannot be the filesystem root, your home directory itself, or a sensitive system path like /etc, /var, ~/.config, or ~/.ssh.",
|
|
18
17
|
UNKNOWN_IMPROVE_STRATEGY: "Pass one of the listed strategy names to `--strategy`, or define it under `improve.strategies`. Names are case-sensitive.",
|
|
19
18
|
EXECUTION_NOT_AUTHORIZED: "Change the selected tools or update the machine/user execution policy, then retry.",
|
|
20
19
|
SECRET_REFERENCE_UNRESOLVED: "Check the secret exists (`akm secret list`) and the name after `secret://` matches, or run `akm secret set <name> <value>` to store it.",
|
|
20
|
+
REGISTRY_URL_INVALID: "Registry URLs must be credential-free http(s) URLs. Fix the entry with `akm registry list` / `akm registry add`, or the AKM_REGISTRY_URL / AKM_NPM_REGISTRY variable that supplied it.",
|
|
21
21
|
};
|
|
22
22
|
// Code-review finding: COMPOSITION_INVALID covers several unrelated causes
|
|
23
23
|
// (a rejected with:, a multi-job source, a composition cycle/depth/size
|
|
@@ -56,7 +56,7 @@ const USAGE_HINTS = {
|
|
|
56
56
|
//
|
|
57
57
|
// Code-review finding: this default is reached ONLY by with:-rejection
|
|
58
58
|
// throw sites (the ones above, plus task.ts's noDeclaredInputsError and
|
|
59
|
-
//
|
|
59
|
+
// freeze.ts's resolveStep) — every other
|
|
60
60
|
// COMPOSITION_INVALID throw site (multi-job source, composition
|
|
61
61
|
// cycle/depth/size, invalid child-output reference, an env: on a
|
|
62
62
|
// composing step) passes its own explicit constructor hint instead of
|
|
@@ -72,19 +72,17 @@ const USAGE_HINTS = {
|
|
|
72
72
|
WORKFLOW_SOURCE_INVALID: "Run `akm lint` to see the failing source location, or `akm workflow plan <ref>` to compile it without writing.",
|
|
73
73
|
INPUT_BINDING_INVALID: "Check the step's with: keys against the target's declared inputs.",
|
|
74
74
|
TASK_TARGET_UNSUPPORTED: "Task definitions support command, script, workflow, and shell (run:) targets; akm/command is layered by callers.",
|
|
75
|
-
// P3a (docs/plans/specs/p3a-plan-v5-child-freeze.md §3.2, A-N2): the
|
|
76
|
-
// complete-or-abandon policy for a stored pre-irVersion-5 run.
|
|
77
|
-
WORKFLOW_IR_VERSION_UNSUPPORTED: "Abandon the run with `akm workflow abandon <id>`, then start it again from the workflow source — a frozen plan this akm cannot execute is not re-executable in place.",
|
|
78
|
-
// P3b (docs/plans/specs/p3b-child-executor.md §4.3).
|
|
79
|
-
WORKFLOW_OUTPUT_INVALID: "Check each `outputs:` entry's `from:` against the step artifact it names, and its `schema:` against the value that step actually promotes.",
|
|
80
75
|
};
|
|
81
76
|
/** Default hint for each TransientErrorCode. */
|
|
82
77
|
const TRANSIENT_HINTS = {
|
|
83
|
-
RUN_LEASE_HELD: "Wait for the
|
|
78
|
+
RUN_LEASE_HELD: "Wait for the akm process driving this run (the named pid) to finish, then retry.",
|
|
84
79
|
STATE_DB_CONTENDED: "Another akm process is writing state.db right now. Wait a few seconds and retry; commands that support --skip-if-locked can skip instead of failing.",
|
|
85
80
|
INDEX_DB_CONTENDED: "Another akm process is writing index.db; retry shortly, or pass --skip-if-locked on scheduled runs.",
|
|
86
|
-
MAINTENANCE_BARRIER_BUSY: "Another akm process is registering a lock or lease right now. Retry shortly, or pass --skip-if-locked on scheduled index/improve/workflow runs.",
|
|
87
81
|
IMPROVE_LOCK_HELD: "Another akm improve run holds the whole-run lock right now. Wait for it to finish and retry, or pass --skip-if-locked on scheduled runs.",
|
|
82
|
+
LOCKFILE_CONTENDED: "Another akm process is updating its bundle lockfile right now. Wait a few seconds and retry.",
|
|
83
|
+
ASSET_MUTATION_LEASE_HELD: "Another akm process is writing bundle content right now. Wait for it to finish and retry.",
|
|
84
|
+
SCHEDULER_LOCK_HELD: "Another `akm task sync`, `add`, `enable`, `disable` or `prune` is writing the scheduler right now. Wait for it to finish and retry.",
|
|
85
|
+
REGISTRY_UNREACHABLE: "The registry did not answer in time. Check the network and the registry URL (`akm registry list`), then retry.",
|
|
88
86
|
};
|
|
89
87
|
/** Default hint for each NotFoundError code. */
|
|
90
88
|
const NOT_FOUND_HINTS = {
|
|
@@ -97,6 +95,7 @@ const NOT_FOUND_HINTS = {
|
|
|
97
95
|
PROPOSAL_NOT_FOUND: "Run `akm proposal list` to see pending proposals and their ids.",
|
|
98
96
|
FILE_NOT_FOUND: "Check the path exists and is readable.",
|
|
99
97
|
IMPROVE_RUN_NOT_FOUND: "Run `akm improve` first, or `akm improve report --since 30d` to see recent run ids in `runIds`.",
|
|
98
|
+
REGISTRY_NOT_FOUND: "Check the ref's spelling and version; `akm search <query> --from registry` lists installable refs.",
|
|
100
99
|
};
|
|
101
100
|
/**
|
|
102
101
|
* Base class for all akm-thrown, classified errors. Carries the `kind`
|
package/dist/core/file-change.js
CHANGED
|
@@ -4,13 +4,21 @@
|
|
|
4
4
|
/**
|
|
5
5
|
* The content of a proposal's PRIMARY change (WI-6.2 envelope read path).
|
|
6
6
|
*
|
|
7
|
-
* By construction `changes[0].after === payload.content
|
|
8
|
-
* through this accessor so the
|
|
9
|
-
*
|
|
10
|
-
*
|
|
7
|
+
* By construction `changes[0].after === payload.content` for a `create` or
|
|
8
|
+
* `update` change; consumers read through this accessor so the
|
|
9
|
+
* single-content assumption lives in ONE place. A `delete` primary change (a
|
|
10
|
+
* consolidate retire proposal, alpha.9) writes no content by definition, so
|
|
11
|
+
* it reads as `""` here rather than throwing — every generic proposal scan
|
|
12
|
+
* (dedup-by-body-hash, the triage drain's diff-size filter, the quality
|
|
13
|
+
* validators) can call this on ANY pending proposal, retire included,
|
|
14
|
+
* without special-casing the op first. Typed structurally (not against
|
|
15
|
+
* `Proposal`) so this module stays dependency-free.
|
|
11
16
|
*/
|
|
12
17
|
export function proposalContent(p) {
|
|
13
|
-
const
|
|
18
|
+
const primary = p.changes[0];
|
|
19
|
+
if (primary?.op === "delete")
|
|
20
|
+
return "";
|
|
21
|
+
const content = primary?.after;
|
|
14
22
|
if (content === undefined)
|
|
15
23
|
throw new Error("Proposal primary change has no content.");
|
|
16
24
|
return content;
|
package/dist/core/file-lock.js
CHANGED
|
@@ -1,11 +1,20 @@
|
|
|
1
1
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
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
|
+
/**
|
|
5
|
+
* PID-stamped exclusive lock files.
|
|
6
|
+
*
|
|
7
|
+
* A lock is one file created with `O_EXCL` (`wx`), which the filesystem
|
|
8
|
+
* makes atomic: exactly one creator wins, so no further mutex or barrier is
|
|
9
|
+
* needed around acquisition. The payload records the holder's PID (and the
|
|
10
|
+
* launcher PID under a scheduler) so a probe can tell a live holder from a
|
|
11
|
+
* dead one; only a verifiably dead holder — or, when the caller opts in via
|
|
12
|
+
* `staleAfterMs`, an over-age one — is ever reclaimed. Reclaim moves the
|
|
13
|
+
* stale file aside, re-verifies it is the very file that was probed, and only
|
|
14
|
+
* then unlinks it, so two reclaimers cannot both "win" the same stale lock.
|
|
15
|
+
*/
|
|
4
16
|
import { randomUUID } from "node:crypto";
|
|
5
17
|
import fs from "node:fs";
|
|
6
|
-
import path from "node:path";
|
|
7
|
-
import { sleepSync } from "../runtime.js";
|
|
8
|
-
import { openDatabase } from "../storage/database.js";
|
|
9
18
|
import { isProcessAlive, MAX_LOCK_METADATA_BYTES, readTextFileDescriptorWithLimit } from "./common.js";
|
|
10
19
|
function readLockSnapshot(lockPath) {
|
|
11
20
|
let fd;
|
|
@@ -32,51 +41,16 @@ function readLockSnapshot(lockPath) {
|
|
|
32
41
|
function sameIdentity(left, right) {
|
|
33
42
|
return left.dev === right.dev && left.ino === right.ino && left.size === right.size && left.mtimeMs === right.mtimeMs;
|
|
34
43
|
}
|
|
35
|
-
function
|
|
36
|
-
// `.sensitive` is an established non-asset suffix across stash walkers. The
|
|
37
|
-
// mutex may sit beside a secret/env lock and must never surface as an asset.
|
|
38
|
-
return path.join(path.dirname(lockPath), `.${path.basename(lockPath)}.operations.sensitive`);
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Serialize every mutation of one canonical lock path. SQLite's write lock is
|
|
42
|
-
* released by the OS when a process dies, so this mutex needs no stale-owner
|
|
43
|
-
* deletion protocol (which would reproduce the same check/rename race it is
|
|
44
|
-
* meant to prevent).
|
|
45
|
-
*/
|
|
46
|
-
function withLockOperationMutex(lockPath, run) {
|
|
47
|
-
const db = openDatabase(operationMutexPath(lockPath));
|
|
48
|
-
let began = false;
|
|
44
|
+
function releaseLockRaw(lockPath) {
|
|
49
45
|
try {
|
|
50
|
-
|
|
51
|
-
for (let attempt = 0; attempt < 5 && !began; attempt += 1) {
|
|
52
|
-
db.exec("BEGIN IMMEDIATE");
|
|
53
|
-
began = db.inTransaction;
|
|
54
|
-
if (!began)
|
|
55
|
-
sleepSync(2 ** attempt);
|
|
56
|
-
}
|
|
57
|
-
if (!began)
|
|
58
|
-
throw new Error(`Could not acquire lock operation mutex for ${lockPath}.`);
|
|
59
|
-
const result = run();
|
|
60
|
-
db.exec("COMMIT");
|
|
61
|
-
began = false;
|
|
62
|
-
return result;
|
|
63
|
-
}
|
|
64
|
-
catch (error) {
|
|
65
|
-
if (began && db.inTransaction) {
|
|
66
|
-
try {
|
|
67
|
-
db.exec("ROLLBACK");
|
|
68
|
-
}
|
|
69
|
-
catch {
|
|
70
|
-
// Preserve the operation failure.
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
throw error;
|
|
46
|
+
fs.unlinkSync(lockPath);
|
|
74
47
|
}
|
|
75
|
-
|
|
76
|
-
|
|
48
|
+
catch {
|
|
49
|
+
// Already gone.
|
|
77
50
|
}
|
|
78
51
|
}
|
|
79
|
-
|
|
52
|
+
/** Create the lock file atomically; `undefined` when another holder already has it. */
|
|
53
|
+
export function tryAcquireLockSync(lockPath, payload) {
|
|
80
54
|
try {
|
|
81
55
|
fs.writeFileSync(lockPath, payload, { flag: "wx" });
|
|
82
56
|
}
|
|
@@ -99,35 +73,6 @@ function tryAcquireLockRaw(lockPath, payload) {
|
|
|
99
73
|
}
|
|
100
74
|
return { lockPath, ...snapshot };
|
|
101
75
|
}
|
|
102
|
-
function releaseLockRaw(lockPath) {
|
|
103
|
-
try {
|
|
104
|
-
fs.unlinkSync(lockPath);
|
|
105
|
-
}
|
|
106
|
-
catch {
|
|
107
|
-
// Sentinel already gone — fine.
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
/**
|
|
111
|
-
* Atomically create a sentinel at `lockPath` with `payload` as the body.
|
|
112
|
-
* Returns an exact ownership handle if we now own the lock, or undefined if a sentinel already
|
|
113
|
-
* exists (EEXIST). Throws any other error (permissions, missing parent
|
|
114
|
-
* dir, etc.) — callers must ensure the parent directory exists.
|
|
115
|
-
*
|
|
116
|
-
* `payload` is typically `String(process.pid)` for the simple cases or
|
|
117
|
-
* a small JSON envelope for callers that want richer metadata
|
|
118
|
-
* (improve.ts records pid + startedAt so audit can correlate runs).
|
|
119
|
-
*/
|
|
120
|
-
export function tryAcquireLockSync(lockPath, payload) {
|
|
121
|
-
return withLockOperationMutex(lockPath, () => tryAcquireLockRaw(lockPath, payload));
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Best-effort launcher pid from `AKM_LAUNCHER_PID` (set by
|
|
125
|
-
* `scripts/node-runtime/akm`/`akm-migrate`, #956) — undefined when unset,
|
|
126
|
-
* empty, or not a positive integer (never trust an ambient env var blindly
|
|
127
|
-
* into a lock message). Also the gate the parent-death watchdog
|
|
128
|
-
* (`core/parent-watchdog.ts`) uses to stay inert outside a launcher-managed
|
|
129
|
-
* run.
|
|
130
|
-
*/
|
|
131
76
|
export function launcherPidFromEnv() {
|
|
132
77
|
const raw = process.env.AKM_LAUNCHER_PID;
|
|
133
78
|
if (!raw)
|
|
@@ -135,13 +80,6 @@ export function launcherPidFromEnv() {
|
|
|
135
80
|
const pid = Number.parseInt(raw, 10);
|
|
136
81
|
return Number.isInteger(pid) && pid > 0 ? pid : undefined;
|
|
137
82
|
}
|
|
138
|
-
/**
|
|
139
|
-
* Build a PID-bearing payload with a unique token for one acquisition attempt.
|
|
140
|
-
* Adds `launcherPid` (#956) whenever this process is running under the
|
|
141
|
-
* published launcher, so a lock's holder can be identified by the pid every
|
|
142
|
-
* process listing and task log actually shows (the launcher's) as well as
|
|
143
|
-
* the pid that holds the lock (the bun/node child).
|
|
144
|
-
*/
|
|
145
83
|
export function createLockPayload(metadata = {}) {
|
|
146
84
|
const launcherPid = launcherPidFromEnv();
|
|
147
85
|
return JSON.stringify({
|
|
@@ -151,26 +89,12 @@ export function createLockPayload(metadata = {}) {
|
|
|
151
89
|
lockId: randomUUID(),
|
|
152
90
|
});
|
|
153
91
|
}
|
|
154
|
-
/**
|
|
155
|
-
* Inspect an existing sentinel at `lockPath` without modifying it.
|
|
156
|
-
* Returns:
|
|
157
|
-
* - `absent` if the file does not exist.
|
|
158
|
-
* - `stale` if the file is present but should be reclaimed (the holding
|
|
159
|
-
* PID is dead, the content is unparseable, or the lock has exceeded
|
|
160
|
-
* `staleAfterMs`). Includes the failure reason so callers can log it.
|
|
161
|
-
* - `held` if the lock has a live holder and is not yet age-expired.
|
|
162
|
-
*
|
|
163
|
-
* Does NOT remove the file. Callers decide recovery policy.
|
|
164
|
-
*/
|
|
165
92
|
export function probeLock(lockPath, opts) {
|
|
166
93
|
let snapshot;
|
|
167
94
|
try {
|
|
168
95
|
snapshot = readLockSnapshot(lockPath);
|
|
169
96
|
}
|
|
170
97
|
catch (error) {
|
|
171
|
-
// A permission error means the lock may be genuinely HELD by someone we
|
|
172
|
-
// cannot see. Reporting it as stale would invite a caller to steal a live
|
|
173
|
-
// lease (#791) — `unreadable` stays for the corrupt/undecodable case.
|
|
174
98
|
const code = error?.code;
|
|
175
99
|
if (code === "EACCES" || code === "EPERM")
|
|
176
100
|
return { state: "inaccessible", code };
|
|
@@ -193,102 +117,81 @@ export function probeLock(lockPath, opts) {
|
|
|
193
117
|
return { state: "held", holderPid, launcherPid, ageMs, rawContent, identity };
|
|
194
118
|
}
|
|
195
119
|
/**
|
|
196
|
-
*
|
|
197
|
-
*
|
|
198
|
-
*
|
|
199
|
-
* has completed.
|
|
120
|
+
* Remove a lock that `probeLock` reported stale. Returns `false` when the file
|
|
121
|
+
* changed since the probe (someone else reclaimed or re-acquired it) so the
|
|
122
|
+
* caller re-probes instead of assuming the path is free.
|
|
200
123
|
*/
|
|
201
124
|
export function reclaimStaleLock(lockPath, probe, options) {
|
|
202
125
|
if (probe.rawContent === undefined || probe.identity === undefined)
|
|
203
126
|
return false;
|
|
204
127
|
const expectedContent = probe.rawContent;
|
|
205
128
|
const expectedIdentity = probe.identity;
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
129
|
+
let current;
|
|
130
|
+
try {
|
|
131
|
+
current = readLockSnapshot(lockPath);
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
return false;
|
|
135
|
+
}
|
|
136
|
+
if (!current || current.rawContent !== expectedContent || !sameIdentity(current.identity, expectedIdentity)) {
|
|
137
|
+
return false;
|
|
138
|
+
}
|
|
139
|
+
const quarantinePath = `${lockPath}.stale-${process.pid}-${randomUUID()}`;
|
|
140
|
+
try {
|
|
141
|
+
fs.renameSync(lockPath, quarantinePath);
|
|
142
|
+
}
|
|
143
|
+
catch (err) {
|
|
144
|
+
if (err.code === "ENOENT")
|
|
215
145
|
return false;
|
|
216
|
-
|
|
217
|
-
|
|
146
|
+
throw err;
|
|
147
|
+
}
|
|
148
|
+
let quarantined;
|
|
149
|
+
try {
|
|
150
|
+
quarantined = readLockSnapshot(quarantinePath);
|
|
151
|
+
}
|
|
152
|
+
catch {
|
|
153
|
+
quarantined = undefined;
|
|
154
|
+
}
|
|
155
|
+
if (!quarantined ||
|
|
156
|
+
quarantined.rawContent !== expectedContent ||
|
|
157
|
+
!sameIdentity(quarantined.identity, expectedIdentity)) {
|
|
158
|
+
// The file we moved aside is not the one we probed: a fresh holder took
|
|
159
|
+
// the path in between. Put it back and report no reclaim.
|
|
218
160
|
try {
|
|
219
|
-
fs.
|
|
161
|
+
fs.linkSync(quarantinePath, lockPath);
|
|
220
162
|
}
|
|
221
163
|
catch (err) {
|
|
222
|
-
if (err.code
|
|
223
|
-
|
|
224
|
-
throw err;
|
|
164
|
+
if (err.code !== "EEXIST")
|
|
165
|
+
throw err;
|
|
225
166
|
}
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
try {
|
|
237
|
-
// Restore without replacing a non-cooperating lock installed after quarantine.
|
|
238
|
-
fs.linkSync(quarantinePath, lockPath);
|
|
239
|
-
}
|
|
240
|
-
catch (err) {
|
|
241
|
-
if (err.code !== "EEXIST")
|
|
242
|
-
throw err;
|
|
243
|
-
}
|
|
244
|
-
releaseLockRaw(quarantinePath);
|
|
167
|
+
releaseLockRaw(quarantinePath);
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
options?.afterQuarantineVerified?.();
|
|
171
|
+
try {
|
|
172
|
+
fs.unlinkSync(quarantinePath);
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
catch (err) {
|
|
176
|
+
if (err.code === "ENOENT")
|
|
245
177
|
return false;
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
try {
|
|
249
|
-
fs.unlinkSync(quarantinePath);
|
|
250
|
-
return true;
|
|
251
|
-
}
|
|
252
|
-
catch (err) {
|
|
253
|
-
if (err.code === "ENOENT")
|
|
254
|
-
return false;
|
|
255
|
-
throw err;
|
|
256
|
-
}
|
|
257
|
-
});
|
|
178
|
+
throw err;
|
|
179
|
+
}
|
|
258
180
|
}
|
|
259
|
-
/**
|
|
260
|
-
* Release only the exact sentinel returned by `tryAcquireLockSync`. Content and
|
|
261
|
-
* file identity are revalidated while holding the acquisition operation mutex,
|
|
262
|
-
* so a stale holder cannot remove a successor. Synchronous and idempotent so it
|
|
263
|
-
* is safe in both `finally` blocks and process exit handlers.
|
|
264
|
-
*/
|
|
181
|
+
/** Unlink the lock only while it is still the exact file this owner created. */
|
|
265
182
|
export function releaseLock(ownership) {
|
|
266
183
|
const { lockPath } = ownership;
|
|
267
|
-
|
|
184
|
+
let current;
|
|
185
|
+
try {
|
|
186
|
+
current = readLockSnapshot(lockPath);
|
|
187
|
+
}
|
|
188
|
+
catch {
|
|
268
189
|
return;
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
}
|
|
274
|
-
catch {
|
|
275
|
-
// Absent or unreadable — nothing of ours to release.
|
|
276
|
-
return;
|
|
277
|
-
}
|
|
278
|
-
if (current && current.rawContent === ownership.rawContent && sameIdentity(current.identity, ownership.identity)) {
|
|
279
|
-
releaseLockRaw(lockPath);
|
|
280
|
-
}
|
|
281
|
-
});
|
|
190
|
+
}
|
|
191
|
+
if (current && current.rawContent === ownership.rawContent && sameIdentity(current.identity, ownership.identity)) {
|
|
192
|
+
releaseLockRaw(lockPath);
|
|
193
|
+
}
|
|
282
194
|
}
|
|
283
|
-
/**
|
|
284
|
-
* Extract a holder pid, and (#956) a launcher pid when the payload recorded
|
|
285
|
-
* one, from a sentinel body. Accepts the two shapes used across the
|
|
286
|
-
* codebase: a bare numeric string (config-io, vault, lockfile — never
|
|
287
|
-
* carries a `launcherPid`) and a JSON object with `pid`/`launcherPid` fields
|
|
288
|
-
* (`createLockPayload`). `holderPid` is undefined when the body is
|
|
289
|
-
* unparseable or yields a non-positive integer; `launcherPid` is undefined
|
|
290
|
-
* whenever the payload has none, independent of whether `holderPid` parsed.
|
|
291
|
-
*/
|
|
292
195
|
function extractLockIdentity(content) {
|
|
293
196
|
const trimmed = content.trim();
|
|
294
197
|
if (!trimmed)
|
|
@@ -19,6 +19,7 @@ const COMMON_FIELDS = [
|
|
|
19
19
|
"plan",
|
|
20
20
|
"actions",
|
|
21
21
|
"skippedProcesses",
|
|
22
|
+
"engineProbe",
|
|
22
23
|
"distillSkipped",
|
|
23
24
|
"validationFailures",
|
|
24
25
|
"schemaRepairs",
|
|
@@ -27,14 +28,22 @@ const COMMON_FIELDS = [
|
|
|
27
28
|
"lintSummary",
|
|
28
29
|
"memoryIndexHealth",
|
|
29
30
|
"coverageGaps",
|
|
31
|
+
// R10: no longer written (the write-only eval-cases path was removed),
|
|
32
|
+
// but kept in the allow-list so `decodeImproveResult` still reads
|
|
33
|
+
// improve-result envelopes a prior release wrote with this field —
|
|
34
|
+
// AGENTS.md "Reading persisted data".
|
|
30
35
|
"evalCasesWritten",
|
|
31
36
|
"deadUrls",
|
|
32
37
|
"deadUrlCoverage",
|
|
33
38
|
"reflectsWithErrorContext",
|
|
34
39
|
"memoryInference",
|
|
40
|
+
// 0.9.17-alpha.9: no longer written (the LLM entity-graph extraction that
|
|
41
|
+
// wrote these was retired), kept readable for the same reason as
|
|
42
|
+
// `evalCasesWritten` above.
|
|
35
43
|
"graphExtraction",
|
|
36
44
|
"memoryInferenceDurationMs",
|
|
37
45
|
"graphExtractionDurationMs",
|
|
46
|
+
"ensureIndexDurationMs",
|
|
38
47
|
"orphansPurged",
|
|
39
48
|
"proposalsExpired",
|
|
40
49
|
"reflectCooldownActions",
|
|
@@ -113,7 +122,7 @@ function validateConsolidationPlan(value) {
|
|
|
113
122
|
]));
|
|
114
123
|
if (!isRecord(value.configured))
|
|
115
124
|
fail("plan.consolidation.configured must be an object");
|
|
116
|
-
requireExactFields(value.configured, new Set(["enabled", "minPoolSize", "limit", "maxChunkSize"
|
|
125
|
+
requireExactFields(value.configured, new Set(["enabled", "minPoolSize", "limit", "maxChunkSize"]));
|
|
117
126
|
if (value.configured.enabled !== undefined && typeof value.configured.enabled !== "boolean") {
|
|
118
127
|
fail("plan.consolidation.configured.enabled must be a boolean");
|
|
119
128
|
}
|
|
@@ -122,9 +131,6 @@ function validateConsolidationPlan(value) {
|
|
|
122
131
|
fail(`plan.consolidation.configured.${field} must be a number`);
|
|
123
132
|
}
|
|
124
133
|
}
|
|
125
|
-
if (value.configured.incrementalSince !== undefined && typeof value.configured.incrementalSince !== "string") {
|
|
126
|
-
fail("plan.consolidation.configured.incrementalSince must be a string");
|
|
127
|
-
}
|
|
128
134
|
if (!isRecord(value.effective))
|
|
129
135
|
fail("plan.consolidation.effective must be an object");
|
|
130
136
|
requireExactFields(value.effective, new Set(["enabled", "minPoolSize", "limit", "chunkSize"]));
|
|
@@ -194,7 +200,15 @@ function validateProcessRoutingRows(value) {
|
|
|
194
200
|
fail("plan.processes entries must be objects");
|
|
195
201
|
requireExactFields(row, new Set(["process", "enabled", "engine", "model", "engineKind", "notices", "unavailable", "eligibleRefs"]));
|
|
196
202
|
if (typeof row.process !== "string" ||
|
|
197
|
-
!(canonicalNames.includes(row.process) ||
|
|
203
|
+
!(canonicalNames.includes(row.process) ||
|
|
204
|
+
row.process === "triage.judgment" ||
|
|
205
|
+
// 0.9.17-alpha.9: "graphExtraction" is no longer a process a fresh
|
|
206
|
+
// plan can route (the LLM entity-graph extraction it named was
|
|
207
|
+
// retired), but every pre-alpha.9 run recorded one here — kept
|
|
208
|
+
// readable, same as `stageNames`' "graph-extraction" above and
|
|
209
|
+
// `graphExtraction` in COMMON_FIELDS, so a historical run still
|
|
210
|
+
// decodes for `akm health` instead of failing this row outright.
|
|
211
|
+
row.process === "graphExtraction")) {
|
|
198
212
|
fail("plan.processes.process is invalid");
|
|
199
213
|
}
|
|
200
214
|
if (seen.has(row.process))
|
|
@@ -300,6 +314,8 @@ function validateImprovePlan(value, dryRun, plannedRefNames) {
|
|
|
300
314
|
fail("plan.limits.totalCeiling must equal plan.limits.effective + plan.limits.additiveReplayAllowance");
|
|
301
315
|
}
|
|
302
316
|
const gateNames = new Set(["profile", "cleanup", "validation", "signal", "disk", "limit"]);
|
|
317
|
+
// Plans stored before 0.9.17-alpha.7 (#986) have no retrieval gate.
|
|
318
|
+
const optionalGateNames = new Set(["retrieval"]);
|
|
303
319
|
if (!Array.isArray(value.gates))
|
|
304
320
|
fail("plan.gates must be an array");
|
|
305
321
|
const gateRemovedByName = new Map();
|
|
@@ -307,8 +323,9 @@ function validateImprovePlan(value, dryRun, plannedRefNames) {
|
|
|
307
323
|
if (!isRecord(gate))
|
|
308
324
|
fail("plan.gates entries must be objects");
|
|
309
325
|
requireExactFields(gate, new Set(["name", "removed", "reason"]));
|
|
310
|
-
if (typeof gate.name !== "string" || !gateNames.has(gate.name))
|
|
326
|
+
if (typeof gate.name !== "string" || !(gateNames.has(gate.name) || optionalGateNames.has(gate.name))) {
|
|
311
327
|
fail("plan.gates.name is invalid");
|
|
328
|
+
}
|
|
312
329
|
requireCount(gate, "removed", "plan.gates entry");
|
|
313
330
|
if (typeof gate.reason !== "string")
|
|
314
331
|
fail("plan.gates.reason must be a string");
|
|
@@ -376,10 +393,18 @@ function validateImprovePlan(value, dryRun, plannedRefNames) {
|
|
|
376
393
|
if (value.limits.totalCeiling !== undefined && value.effectiveRefs.length > value.limits.totalCeiling) {
|
|
377
394
|
fail("plan.effectiveRefs cannot exceed plan.limits.totalCeiling");
|
|
378
395
|
}
|
|
379
|
-
|
|
396
|
+
// #947 added plan.processes (2026-09-09T09:03:19Z); every run recorded
|
|
397
|
+
// before it legitimately stored `plan` with no `processes` key at all —
|
|
398
|
+
// validate the rows only when present, same as `proactive` below, so a
|
|
399
|
+
// pre-#947 envelope still decodes (AGENTS.md "Reading persisted data").
|
|
400
|
+
if (value.processes !== undefined)
|
|
401
|
+
validateProcessRoutingRows(value.processes);
|
|
380
402
|
if (value.proactive !== undefined)
|
|
381
403
|
validateProactivePlan(value.proactive);
|
|
382
404
|
validateConsolidationPlan(value.consolidation);
|
|
405
|
+
// "graph-extraction" is no longer a stage a fresh plan can name — retired
|
|
406
|
+
// 0.9.17-alpha.9 — but stays here so a historical envelope that captured a
|
|
407
|
+
// dry-run plan before the retirement still decodes.
|
|
383
408
|
const stageNames = new Set(["consolidation", "extract", "graph-extraction", "memory-inference"]);
|
|
384
409
|
if (!Array.isArray(value.stages))
|
|
385
410
|
fail("plan.stages must be an array");
|
|
@@ -442,6 +467,7 @@ function validateCommon(value) {
|
|
|
442
467
|
for (const field of [
|
|
443
468
|
"actions",
|
|
444
469
|
"skippedProcesses",
|
|
470
|
+
"engineProbe",
|
|
445
471
|
"validationFailures",
|
|
446
472
|
"schemaRepairs",
|
|
447
473
|
"extract",
|
|
@@ -457,10 +483,12 @@ function validateCommon(value) {
|
|
|
457
483
|
}
|
|
458
484
|
for (const field of [
|
|
459
485
|
"cyclesRun",
|
|
486
|
+
// R10: retired write, kept readable — see the COMMON_FIELDS comment above.
|
|
460
487
|
"evalCasesWritten",
|
|
461
488
|
"reflectsWithErrorContext",
|
|
462
489
|
"memoryInferenceDurationMs",
|
|
463
490
|
"graphExtractionDurationMs",
|
|
491
|
+
"ensureIndexDurationMs",
|
|
464
492
|
"orphansPurged",
|
|
465
493
|
"proposalsExpired",
|
|
466
494
|
"reflectCooldownActions",
|
package/dist/core/logs-db.js
CHANGED
|
@@ -33,13 +33,13 @@
|
|
|
33
33
|
* ## Schema evolution
|
|
34
34
|
*
|
|
35
35
|
* Same migration-safety contract as state.db: append-only `MIGRATIONS` applied
|
|
36
|
-
* through the shared runner in src/storage/
|
|
36
|
+
* through the shared runner in src/storage/sqlite-migrations.ts.
|
|
37
37
|
*
|
|
38
38
|
* @module logs-db
|
|
39
39
|
*/
|
|
40
40
|
import path from "node:path";
|
|
41
|
-
import { assertMigrationRegistry, runMigrations as runSqliteMigrations, } from "../storage/engines/sqlite-migrations.js";
|
|
42
41
|
import { openManagedDatabase } from "../storage/managed-db.js";
|
|
42
|
+
import { assertMigrationRegistry, runMigrations as runSqliteMigrations, } from "../storage/sqlite-migrations.js";
|
|
43
43
|
import { getDataDir } from "./paths.js";
|
|
44
44
|
// ── Path helper ──────────────────────────────────────────────────────────────
|
|
45
45
|
/**
|
package/dist/core/loopback.js
CHANGED
|
@@ -20,10 +20,11 @@
|
|
|
20
20
|
*
|
|
21
21
|
* The ONE local-vs-remote answer for concurrency defaults — the workflow
|
|
22
22
|
* engine's frozen engine concurrency (`workflows/concurrency-policy.ts`) and
|
|
23
|
-
* the
|
|
24
|
-
* both classify through here. NOT shared with
|
|
25
|
-
*
|
|
26
|
-
*
|
|
23
|
+
* the embedding pool (`resolveEmbeddingConcurrency`,
|
|
24
|
+
* `src/llm/embedders/remote.ts`) both classify through here. NOT shared with
|
|
25
|
+
* the website snapshot fetcher's SSRF policy
|
|
26
|
+
* (`sources/snapshot-fetchers/host-guard.ts`), which deliberately draws
|
|
27
|
+
* different lines for a different threat model.
|
|
27
28
|
*
|
|
28
29
|
* @module core/loopback
|
|
29
30
|
*/
|
|
@@ -92,14 +93,8 @@ export function isLoopbackEndpoint(endpoint) {
|
|
|
92
93
|
* endpoint: 1 for a loopback endpoint (a local model server serves one
|
|
93
94
|
* inference at a time; concurrent requests thrash it — reload thrash, HTTP
|
|
94
95
|
* 500 "Model reloaded"), 2 for a remote one (enough to overlap request
|
|
95
|
-
* latency without hammering a rate-limited API).
|
|
96
|
-
*
|
|
97
|
-
* `src/indexer/indexer.ts`) and the embedding pool
|
|
98
|
-
* (`resolveEmbeddingConcurrency`, `src/llm/embedders/remote.ts`) — share one
|
|
99
|
-
* definition instead of mirroring it; `src/llm/embedders/remote.ts` cannot
|
|
100
|
-
* import `getDefaultLlmConcurrency` directly (`src/indexer/indexer.ts`
|
|
101
|
-
* already depends on this module transitively through
|
|
102
|
-
* materialize-embeddings.ts).
|
|
96
|
+
* latency without hammering a rate-limited API). Used by the embedding pool
|
|
97
|
+
* (`resolveEmbeddingConcurrency`, `src/llm/embedders/remote.ts`).
|
|
103
98
|
*/
|
|
104
99
|
export function defaultConcurrencyForEndpoint(endpoint) {
|
|
105
100
|
return isLoopbackEndpoint(endpoint) ? 1 : 2;
|
|
@@ -0,0 +1,20 @@
|
|
|
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
|
+
/** The line of `src/assets/stash-skeleton/README.md` that reaches curate verbatim as a query. */
|
|
5
|
+
const STASH_README_LINE = "This is an **AKM stash** — a structured knowledge repository that stores reusable";
|
|
6
|
+
/**
|
|
7
|
+
* What the (trimmed) curate input is when it is not a task, else undefined.
|
|
8
|
+
* Harness and tool envelopes (`<task-notification>…`, `<system-reminder>…`,
|
|
9
|
+
* `<cross-session-message …>…`) start with a tag and close one, and the stash
|
|
10
|
+
* README line arrives verbatim; on the retrieval suite neither shape occurs in
|
|
11
|
+
* a real query. Length is not a signal: prompts over 2,000 characters found
|
|
12
|
+
* relevant assets at about the rate of shorter long prompts.
|
|
13
|
+
*/
|
|
14
|
+
export function nonTaskInput(query) {
|
|
15
|
+
if (query.startsWith("<") && query.includes("</"))
|
|
16
|
+
return "a harness or tool envelope";
|
|
17
|
+
if (query === STASH_README_LINE)
|
|
18
|
+
return "the akm stash README boilerplate";
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|