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
|
@@ -2,50 +2,78 @@
|
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
4
|
/**
|
|
5
|
-
* Observability command cluster — `akm log` (events
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* subcommand's args/output shape are byte-identical.
|
|
5
|
+
* Observability command cluster — `akm log` (append-only events stream).
|
|
6
|
+
* Extracted verbatim from src/cli.ts (WS6) so the God Module shrinks; the
|
|
7
|
+
* `main.subCommands.log` key and its args/output shape are byte-identical.
|
|
9
8
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* coverage` reports tag-coverage gaps from the index, and `hints` prints the
|
|
13
|
-
* embedded AGENTS.md guidance. They share no helpers with any command still
|
|
14
|
-
* inline in cli.ts, so the `loadHints` private helper and the
|
|
15
|
-
* `formatEventLine` / `EMBEDDED_HINTS*` / db-tag-set imports move with them.
|
|
9
|
+
* `log` reads the append-only state.db events stream. It shares no helpers
|
|
10
|
+
* with any command still inline in cli.ts.
|
|
16
11
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
* (
|
|
22
|
-
* `
|
|
12
|
+
* 0.9.0 CLI overhaul (S3): `log` was a group with `list`/`tail` subcommands;
|
|
13
|
+
* `tail` (a foreground polling daemon) is dropped and `log` becomes a LEAF
|
|
14
|
+
* command that is today's `list` surface, unchanged (including the
|
|
15
|
+
* `--since @offset:<id>` durable cursor and --ref/--type filters). The
|
|
16
|
+
* `lessons`/`lesson` group (`coverage`, `strength`) is dropped entirely —
|
|
17
|
+
* ranking's `lessonStrength` contributor is untouched, only the CLI read
|
|
18
|
+
* surface for it goes away.
|
|
19
|
+
*
|
|
20
|
+
* The embedded agent-guide surfaces (`akm hints` and `akm help agents`) live
|
|
21
|
+
* in src/cli.ts, so their loading code is intentionally outside this module.
|
|
22
|
+
*
|
|
23
|
+
* The leaf handler's body is a plain `runWithJsonErrors(...) + output(...)`,
|
|
24
|
+
* migrated onto `defineJsonCommand`, which emits the same JSON envelope
|
|
25
|
+
* (stdout/stderr/exit-code) as the inline form.
|
|
23
26
|
*/
|
|
24
|
-
import fs from "node:fs";
|
|
25
|
-
import path from "node:path";
|
|
26
|
-
import { defineCommand } from "citty";
|
|
27
27
|
import { parsePositiveIntFlag } from "../cli/parse-args.js";
|
|
28
|
-
import {
|
|
29
|
-
import {
|
|
30
|
-
import {
|
|
31
|
-
import {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
28
|
+
import { retiredCommandHint } from "../cli/retired-commands.js";
|
|
29
|
+
import { defineJsonCommand, output, parseAllFlagValues } from "../cli/shared.js";
|
|
30
|
+
import { UsageError } from "../core/errors.js";
|
|
31
|
+
import { akmEventsList } from "./log.js";
|
|
32
|
+
/**
|
|
33
|
+
* `log` flattened from a group (`log list`/`log tail`) to a leaf in 0.9 (S3).
|
|
34
|
+
* `log` declares no positional args, so citty leaves any leftover positional
|
|
35
|
+
* token in `args._` uninterpreted rather than rejecting it — meaning
|
|
36
|
+
* `akm log tail` and `akm log list` silently ran today's `log` surface
|
|
37
|
+
* instead of failing like the other removed spellings (`log tail` is the
|
|
38
|
+
* dangerous one: it used to stream/follow, so an unmigrated caller got a
|
|
39
|
+
* silent one-shot snapshot instead of an error).
|
|
40
|
+
*/
|
|
41
|
+
function rejectExtraLogPositionals(positionals) {
|
|
42
|
+
const extra = Array.isArray(positionals) ? positionals.map(String) : [];
|
|
43
|
+
if (extra.length === 0)
|
|
44
|
+
return;
|
|
45
|
+
// A retired subcommand spelling gets its replacement hint (same table the
|
|
46
|
+
// unknown-command path uses), so `akm log tail` teaches the durable-cursor
|
|
47
|
+
// polling pattern instead of a bare "takes no positional arguments".
|
|
48
|
+
const retired = extra[0] === undefined ? undefined : retiredCommandHint(["log"], extra[0]);
|
|
49
|
+
throw new UsageError(`akm log takes no positional arguments, but got ${extra.map((token) => `"${token}"`).join(" ")}. ` +
|
|
50
|
+
'"log list"/"log tail" were removed in 0.9.0 — `akm log` alone is today\'s `log list` surface.', "INVALID_FLAG_VALUE", retired);
|
|
51
|
+
}
|
|
36
52
|
// ── `akm log` ────────────────────────────────────────────────────────────────
|
|
37
|
-
// Append-only events stream surface (#204).
|
|
38
|
-
//
|
|
39
|
-
//
|
|
40
|
-
|
|
41
|
-
|
|
53
|
+
// Append-only events stream surface (#204). Reads state.db events with
|
|
54
|
+
// optional --since/--type/--ref filters.
|
|
55
|
+
//
|
|
56
|
+
// R-060: the internal output()/shape-registry command name is `log-list`
|
|
57
|
+
// (renamed from the pre-rename `events-list`, back when the command group was
|
|
58
|
+
// still called `akm events`). This string never reaches the wire —
|
|
59
|
+
// `shapeEventsOutput` (src/output/shapes/helpers.ts) builds its own envelope
|
|
60
|
+
// and never stamps a `shape` field — so the rename is a coherence-only
|
|
61
|
+
// change, not a schemaVersion bump. Kept as `log-list` (not renamed to `log`)
|
|
62
|
+
// even though the group flattened to a leaf, to avoid unrelated churn on the
|
|
63
|
+
// internal registry key.
|
|
64
|
+
export const logCommand = defineJsonCommand({
|
|
65
|
+
meta: { name: "log", description: "List events from the append-only state.db events stream" },
|
|
42
66
|
args: {
|
|
43
67
|
since: {
|
|
44
68
|
type: "string",
|
|
45
69
|
description: "ISO timestamp / epoch ms, OR `@offset:<id>` for a durable row-id cursor (resume across processes)",
|
|
46
70
|
},
|
|
47
71
|
type: { type: "string", description: "Filter by event type (add, remove, remember, feedback, ...)" },
|
|
48
|
-
ref: { type: "string", description: "Filter by asset ref (
|
|
72
|
+
ref: { type: "string", description: "Filter by asset ref ([bundle//]conceptId)" },
|
|
73
|
+
run: {
|
|
74
|
+
type: "string",
|
|
75
|
+
description: "Filter to a workflow run's events (metadata.runId), e.g. the id from `akm workflow run`",
|
|
76
|
+
},
|
|
49
77
|
"exclude-tags": {
|
|
50
78
|
type: "string",
|
|
51
79
|
description: "Exclude events matching these tags (repeatable)",
|
|
@@ -54,192 +82,25 @@ const eventsListCommand = defineJsonCommand({
|
|
|
54
82
|
type: "string",
|
|
55
83
|
description: "Only include events with ALL these tags (repeatable)",
|
|
56
84
|
},
|
|
85
|
+
limit: {
|
|
86
|
+
type: "string",
|
|
87
|
+
description: "Return only the most recent N events matching every other filter (default: unlimited)",
|
|
88
|
+
},
|
|
57
89
|
},
|
|
58
90
|
run({ args }) {
|
|
91
|
+
rejectExtraLogPositionals(args._);
|
|
59
92
|
const excludeTags = parseAllFlagValues("--exclude-tags");
|
|
60
93
|
const includeTags = parseAllFlagValues("--include-tags");
|
|
94
|
+
const limit = parsePositiveIntFlag(args.limit);
|
|
61
95
|
const result = akmEventsList({
|
|
62
96
|
since: args.since,
|
|
63
97
|
type: args.type,
|
|
64
98
|
ref: args.ref,
|
|
99
|
+
run: args.run,
|
|
65
100
|
...(excludeTags.length > 0 ? { excludeTags } : {}),
|
|
66
101
|
...(includeTags.length > 0 ? { includeTags } : {}),
|
|
102
|
+
...(limit !== undefined ? { limit } : {}),
|
|
67
103
|
});
|
|
68
|
-
output("
|
|
104
|
+
output("log-list", result);
|
|
69
105
|
},
|
|
70
106
|
});
|
|
71
|
-
const eventsTailCommand = defineCommand({
|
|
72
|
-
meta: { name: "tail", description: "Follow the append-only state.db events stream (polling)" },
|
|
73
|
-
args: {
|
|
74
|
-
since: {
|
|
75
|
-
type: "string",
|
|
76
|
-
description: "ISO timestamp / epoch ms, OR `@offset:<id>` for a durable row-id cursor (resume across processes)",
|
|
77
|
-
},
|
|
78
|
-
type: { type: "string", description: "Filter by event type" },
|
|
79
|
-
ref: { type: "string", description: "Filter by asset ref (type:name)" },
|
|
80
|
-
"interval-ms": { type: "string", description: "Polling interval in ms (default: 75)" },
|
|
81
|
-
"max-duration-ms": { type: "string", description: "Stop after this many ms (default: never)" },
|
|
82
|
-
"max-events": { type: "string", description: "Stop after observing this many events" },
|
|
83
|
-
"exclude-tags": {
|
|
84
|
-
type: "string",
|
|
85
|
-
description: "Exclude events matching these tags (repeatable)",
|
|
86
|
-
},
|
|
87
|
-
"include-tags": {
|
|
88
|
-
type: "string",
|
|
89
|
-
description: "Only include events with ALL these tags (repeatable)",
|
|
90
|
-
},
|
|
91
|
-
},
|
|
92
|
-
async run({ args }) {
|
|
93
|
-
await runWithJsonErrors(async () => {
|
|
94
|
-
const intervalMs = parsePositiveIntFlag(args["interval-ms"], "--interval-ms");
|
|
95
|
-
const maxDurationMs = parsePositiveIntFlag(args["max-duration-ms"], "--max-duration-ms");
|
|
96
|
-
const maxEvents = parsePositiveIntFlag(args["max-events"], "--max-events");
|
|
97
|
-
const mode = getOutputMode();
|
|
98
|
-
// In streaming text mode we want each event to print as soon as it
|
|
99
|
-
// arrives. The polling loop emits via `onEvent`; the final result is
|
|
100
|
-
// also rendered through the standard output() pipeline so JSON
|
|
101
|
-
// consumers always get the canonical envelope.
|
|
102
|
-
const stream = mode.format === "text" || mode.format === "jsonl";
|
|
103
|
-
const excludeTags = parseAllFlagValues("--exclude-tags");
|
|
104
|
-
const includeTags = parseAllFlagValues("--include-tags");
|
|
105
|
-
const result = await akmEventsTail({
|
|
106
|
-
since: args.since,
|
|
107
|
-
type: args.type,
|
|
108
|
-
ref: args.ref,
|
|
109
|
-
intervalMs,
|
|
110
|
-
maxDurationMs,
|
|
111
|
-
maxEvents,
|
|
112
|
-
...(excludeTags.length > 0 ? { excludeTags } : {}),
|
|
113
|
-
...(includeTags.length > 0 ? { includeTags } : {}),
|
|
114
|
-
onEvent: stream
|
|
115
|
-
? (event) => {
|
|
116
|
-
if (mode.format === "jsonl") {
|
|
117
|
-
console.log(JSON.stringify(event));
|
|
118
|
-
}
|
|
119
|
-
else {
|
|
120
|
-
console.log(formatEventLine(event));
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
: undefined,
|
|
124
|
-
});
|
|
125
|
-
// Emit the canonical envelope last (JSON/YAML modes rely on this;
|
|
126
|
-
// streaming modes already printed each event but we still emit a
|
|
127
|
-
// trailer so callers can persist the resumable cursor).
|
|
128
|
-
if (!stream) {
|
|
129
|
-
output("events-tail", result);
|
|
130
|
-
}
|
|
131
|
-
else if (mode.format === "jsonl") {
|
|
132
|
-
// Final discriminated trailer row so jsonl consumers can resume.
|
|
133
|
-
const trailer = {
|
|
134
|
-
_kind: "trailer",
|
|
135
|
-
schemaVersion: 1,
|
|
136
|
-
nextOffset: result.nextOffset,
|
|
137
|
-
totalCount: result.totalCount,
|
|
138
|
-
reason: result.reason,
|
|
139
|
-
};
|
|
140
|
-
console.log(JSON.stringify(trailer));
|
|
141
|
-
}
|
|
142
|
-
else {
|
|
143
|
-
// text mode: keep stdout pristine for line-oriented parsers and
|
|
144
|
-
// emit the trailer on stderr.
|
|
145
|
-
process.stderr.write(`[events-tail] reason=${result.reason} nextOffset=${result.nextOffset} total=${result.totalCount}\n`);
|
|
146
|
-
}
|
|
147
|
-
});
|
|
148
|
-
},
|
|
149
|
-
});
|
|
150
|
-
export const logCommand = defineCommand({
|
|
151
|
-
meta: {
|
|
152
|
-
name: "log",
|
|
153
|
-
description: "Read or follow the append-only state.db events stream (mutations, feedback, indexing)",
|
|
154
|
-
},
|
|
155
|
-
subCommands: {
|
|
156
|
-
list: eventsListCommand,
|
|
157
|
-
tail: eventsTailCommand,
|
|
158
|
-
},
|
|
159
|
-
});
|
|
160
|
-
// ── lessons subcommands (Phase 7A / Advantage D4c) ──────────────────────────
|
|
161
|
-
const lessonsCoverageCommand = defineJsonCommand({
|
|
162
|
-
meta: {
|
|
163
|
-
name: "coverage",
|
|
164
|
-
description: "Report tags that exist on indexed assets but are NOT yet covered by any lesson.\n\n" +
|
|
165
|
-
"Useful for spotting topics where the stash has skills/commands/scripts but no\n" +
|
|
166
|
-
"crystallized lesson — a signal that the team has tacit knowledge worth distilling.\n\n" +
|
|
167
|
-
"Default output is JSON: { uncoveredTags: string[], lessonTagCount: number, totalTagCount: number }.\n" +
|
|
168
|
-
"Pass --format text for a plain-text bulleted list.",
|
|
169
|
-
},
|
|
170
|
-
args: {},
|
|
171
|
-
run() {
|
|
172
|
-
const db = openExistingDatabase();
|
|
173
|
-
try {
|
|
174
|
-
const allTagSet = collectTagSetFromEntries(db, undefined);
|
|
175
|
-
const lessonTagSet = collectTagSetFromEntries(db, "lesson");
|
|
176
|
-
const uncovered = [];
|
|
177
|
-
for (const tag of allTagSet) {
|
|
178
|
-
if (!lessonTagSet.has(tag))
|
|
179
|
-
uncovered.push(tag);
|
|
180
|
-
}
|
|
181
|
-
uncovered.sort((a, b) => a.localeCompare(b));
|
|
182
|
-
output("lessons-coverage", {
|
|
183
|
-
ok: true,
|
|
184
|
-
uncoveredTags: uncovered,
|
|
185
|
-
lessonTagCount: lessonTagSet.size,
|
|
186
|
-
totalTagCount: allTagSet.size,
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
finally {
|
|
190
|
-
closeDatabase(db);
|
|
191
|
-
}
|
|
192
|
-
},
|
|
193
|
-
});
|
|
194
|
-
export const lessonsCommand = defineCommand({
|
|
195
|
-
meta: {
|
|
196
|
-
name: "lessons",
|
|
197
|
-
alias: "lesson",
|
|
198
|
-
description: "Lesson-asset tooling: tag-coverage gaps, strength queries.",
|
|
199
|
-
},
|
|
200
|
-
subCommands: {
|
|
201
|
-
coverage: lessonsCoverageCommand,
|
|
202
|
-
},
|
|
203
|
-
});
|
|
204
|
-
// ── `akm hints` ──────────────────────────────────────────────────────────────
|
|
205
|
-
export const hintsCommand = defineCommand({
|
|
206
|
-
meta: {
|
|
207
|
-
name: "hints",
|
|
208
|
-
description: "Print agent instructions on how to use akm, use --detail full for a complete guide",
|
|
209
|
-
},
|
|
210
|
-
args: {
|
|
211
|
-
detail: {
|
|
212
|
-
type: "string",
|
|
213
|
-
description: "Hints detail level (brief|normal|full). `brief` prints the short guide; `normal`/`full` print the complete guide.",
|
|
214
|
-
default: "normal",
|
|
215
|
-
},
|
|
216
|
-
},
|
|
217
|
-
run({ args }) {
|
|
218
|
-
return runWithJsonErrors(() => {
|
|
219
|
-
// Let the global parser validate the value so an invalid `--detail`
|
|
220
|
-
// returns the standard JSON error envelope (exit 2) rather than a raw
|
|
221
|
-
// stack trace + exit 1. `brief` → short doc; `normal`/`full` → full doc.
|
|
222
|
-
const detail = parseDetailLevel(args.detail) ?? "normal";
|
|
223
|
-
process.stdout.write(loadHints(detail === "brief" ? "brief" : "full"));
|
|
224
|
-
});
|
|
225
|
-
},
|
|
226
|
-
});
|
|
227
|
-
// ── Hints (embedded AGENTS.md) ──────────────────────────────────────────────
|
|
228
|
-
function loadHints(detail = "normal") {
|
|
229
|
-
// `brief` → the short AGENTS.md guide; `normal`/`full` → the complete guide.
|
|
230
|
-
const wantFull = detail !== "brief";
|
|
231
|
-
const filename = wantFull ? "AGENTS.full.md" : "AGENTS.md";
|
|
232
|
-
const fallback = wantFull ? EMBEDDED_HINTS_FULL : EMBEDDED_HINTS;
|
|
233
|
-
// Try reading from the docs/ directory (works in dev and when installed via npm)
|
|
234
|
-
try {
|
|
235
|
-
const docsPath = path.resolve(getDirname(import.meta.url), `../../docs/agents/${filename}`);
|
|
236
|
-
if (fs.existsSync(docsPath)) {
|
|
237
|
-
return fs.readFileSync(docsPath, "utf8");
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
|
-
catch {
|
|
241
|
-
// fall through
|
|
242
|
-
}
|
|
243
|
-
// Fallback for compiled binary — inline content
|
|
244
|
-
return fallback;
|
|
245
|
-
}
|
|
@@ -13,8 +13,7 @@
|
|
|
13
13
|
* - Reuses `listProposals` (no source filter — generator filtering is
|
|
14
14
|
* in-memory) and the `akmProposalAccept` / `akmProposalReject` wrappers from
|
|
15
15
|
* `proposal.ts` so the standard `promoted` / `rejected` events are emitted.
|
|
16
|
-
* Deterministic by design
|
|
17
|
-
* gate that once ran alongside this engine died in 0.9.0).
|
|
16
|
+
* Deterministic by design; only the configured drain policy decides.
|
|
18
17
|
* - Backlog-only: `excludeIds` removes this-run's fresh proposals so triage
|
|
19
18
|
* never re-adjudicates a current run's output (decision #2).
|
|
20
19
|
* - Hard guardrails enforced in code: a `maxAccepts` ceiling checked *before*
|
|
@@ -35,17 +34,19 @@
|
|
|
35
34
|
* (mirrors reflect's dual test seams) so tests can run the full engine without
|
|
36
35
|
* touching the filesystem or spawning a process.
|
|
37
36
|
*/
|
|
37
|
+
import { createHash } from "node:crypto";
|
|
38
38
|
import fs from "node:fs";
|
|
39
39
|
import path from "node:path";
|
|
40
40
|
import { assetPathForName, stashDirFor } from "../../core/asset/asset-placement.js";
|
|
41
41
|
import { parseFrontmatter } from "../../core/asset/frontmatter.js";
|
|
42
42
|
import { parseRefInput } from "../../core/asset/resolve-ref.js";
|
|
43
43
|
import { appendEvent } from "../../core/events.js";
|
|
44
|
+
import { escapeJsonStringControls, stripCodeFences, stripThinkBlocks } from "../../core/parse.js";
|
|
44
45
|
import { info, warn } from "../../core/warn.js";
|
|
45
46
|
import { executeRunner } from "../../integrations/agent/runner-dispatch.js";
|
|
46
|
-
import { chatCompletion
|
|
47
|
+
import { chatCompletion } from "../../llm/client.js";
|
|
47
48
|
import { akmProposalAccept, akmProposalReject } from "./proposal.js";
|
|
48
|
-
import { listProposals, proposalContent, recordGateDecision, } from "./repository.js";
|
|
49
|
+
import { listProposals, preflightProposalPromotion, proposalContent, recordGateDecision, } from "./repository.js";
|
|
49
50
|
// ---------------------------------------------------------------------------
|
|
50
51
|
// Content helpers
|
|
51
52
|
// ---------------------------------------------------------------------------
|
|
@@ -184,7 +185,7 @@ export function buildJudgmentPrompt(proposal, reason, ctx) {
|
|
|
184
185
|
}
|
|
185
186
|
/** Parse a {@link JudgmentVerdict} from raw runner output. Lenient. */
|
|
186
187
|
export function parseJudgmentVerdict(raw) {
|
|
187
|
-
const cleaned =
|
|
188
|
+
const cleaned = escapeJsonStringControls(stripCodeFences(stripThinkBlocks(raw))).trim();
|
|
188
189
|
if (!cleaned)
|
|
189
190
|
return null;
|
|
190
191
|
// Find the first balanced-looking JSON object in the output.
|
|
@@ -241,6 +242,9 @@ async function dispatchJudgment(runner, prompt, seams) {
|
|
|
241
242
|
}
|
|
242
243
|
return parseJudgmentVerdict(result.stdout);
|
|
243
244
|
}
|
|
245
|
+
function judgedContentHash(proposal) {
|
|
246
|
+
return createHash("sha256").update(proposalContent(proposal), "utf8").digest("hex");
|
|
247
|
+
}
|
|
244
248
|
/**
|
|
245
249
|
* Run the judgment tier over the deferred items. The runner only *judges*; the
|
|
246
250
|
* engine performs the resulting accept (respecting `applyMode`) / reject write.
|
|
@@ -285,7 +289,12 @@ async function runJudgmentTier(input) {
|
|
|
285
289
|
continue;
|
|
286
290
|
}
|
|
287
291
|
try {
|
|
288
|
-
await input.rejectFn({
|
|
292
|
+
await input.rejectFn({
|
|
293
|
+
stashDir: input.stashDir,
|
|
294
|
+
id: item.id,
|
|
295
|
+
reason: verdict.reason || "judgment: reject",
|
|
296
|
+
gateDecision: { outcome: "auto-rejected", reason: "judgment-reject", gate: input.gateLabel },
|
|
297
|
+
});
|
|
289
298
|
rejected.push(item.id);
|
|
290
299
|
}
|
|
291
300
|
catch (err) {
|
|
@@ -301,6 +310,21 @@ async function runJudgmentTier(input) {
|
|
|
301
310
|
// is RESOLVED (the runner judged it). Track separately so it is NOT
|
|
302
311
|
// reported as "left unresolved" and a follow-up promote run picks it up.
|
|
303
312
|
staged.push(item.id);
|
|
313
|
+
if (!input.dryRun) {
|
|
314
|
+
try {
|
|
315
|
+
recordGateDecision(input.stashDir, item.id, {
|
|
316
|
+
outcome: "staged",
|
|
317
|
+
reason: "judgment-accept",
|
|
318
|
+
contentHash: judgedContentHash(proposal),
|
|
319
|
+
gate: input.gateLabel,
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
catch (err) {
|
|
323
|
+
warn(`[triage] failed to stage judgment for ${item.id}: ${err instanceof Error ? err.message : String(err)}`);
|
|
324
|
+
staged.pop();
|
|
325
|
+
stillDeferred.push(item);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
304
328
|
continue;
|
|
305
329
|
}
|
|
306
330
|
// Accept cap: once the shared budget is exhausted, route further accepts to
|
|
@@ -310,6 +334,19 @@ async function runJudgmentTier(input) {
|
|
|
310
334
|
continue;
|
|
311
335
|
}
|
|
312
336
|
if (input.dryRun) {
|
|
337
|
+
try {
|
|
338
|
+
if (input.config) {
|
|
339
|
+
preflightProposalPromotion(input.config, proposal, {
|
|
340
|
+
...(input.target ? { target: input.target } : {}),
|
|
341
|
+
gateDecision: { outcome: "auto-accepted", reason: "judgment-accept", gate: input.gateLabel },
|
|
342
|
+
});
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
catch (err) {
|
|
346
|
+
warn(`[triage] judgment preflight failed for ${item.id}: ${err instanceof Error ? err.message : String(err)}`);
|
|
347
|
+
stillDeferred.push(item);
|
|
348
|
+
continue;
|
|
349
|
+
}
|
|
313
350
|
promoted.push(item.id);
|
|
314
351
|
acceptBudget -= 1;
|
|
315
352
|
continue;
|
|
@@ -320,6 +357,7 @@ async function runJudgmentTier(input) {
|
|
|
320
357
|
id: item.id,
|
|
321
358
|
...(input.target ? { target: input.target } : {}),
|
|
322
359
|
...(input.config ? { config: input.config } : {}),
|
|
360
|
+
gateDecision: { outcome: "auto-accepted", reason: "judgment-accept", gate: input.gateLabel },
|
|
323
361
|
});
|
|
324
362
|
promoted.push(item.id);
|
|
325
363
|
acceptBudget -= 1;
|
|
@@ -347,6 +385,7 @@ export async function drainProposals(opts, promoteFn = akmProposalAccept, reject
|
|
|
347
385
|
const pending = listProposals(opts.stashDir, { status: "pending" }).filter((p) => !exclude.has(p.id));
|
|
348
386
|
// First, classify every proposal deterministically.
|
|
349
387
|
const acceptIds = [];
|
|
388
|
+
const acceptGateReasons = new Map();
|
|
350
389
|
const rejectTargets = [];
|
|
351
390
|
const gateLabel = `triage:${opts.policy.name}`;
|
|
352
391
|
// Items deferred purely because they need a judge (no threshold-based reason)
|
|
@@ -359,22 +398,31 @@ export async function drainProposals(opts, promoteFn = akmProposalAccept, reject
|
|
|
359
398
|
// the audit trail and silently promote content the gate explicitly rejected.
|
|
360
399
|
// Such proposals remain pending until the TTL expires them — the queue is
|
|
361
400
|
// audited-autonomous; no manual-review rung exists (06-M3).
|
|
362
|
-
if (proposal.gateDecision?.outcome === "auto-rejected")
|
|
401
|
+
if (proposal.gateDecision?.outcome === "auto-rejected" && !proposal.gateDecision.gate?.startsWith("triage:")) {
|
|
363
402
|
continue;
|
|
403
|
+
}
|
|
404
|
+
if (proposal.gateDecision?.outcome === "staged" &&
|
|
405
|
+
proposal.gateDecision.gate === gateLabel &&
|
|
406
|
+
proposal.gateDecision.contentHash === judgedContentHash(proposal)) {
|
|
407
|
+
acceptIds.push(proposal.id);
|
|
408
|
+
acceptGateReasons.set(proposal.id, "judgment-accept");
|
|
409
|
+
continue;
|
|
410
|
+
}
|
|
364
411
|
const decision = classifyProposal(proposal, opts.policy, opts.maxDiffLines);
|
|
365
412
|
if (decision === null)
|
|
366
413
|
continue;
|
|
367
414
|
// #577: stamp the gate's verdict onto the proposal so `akm proposal show`
|
|
368
415
|
// can explain WHY it landed here. A dry-run performs zero writes, so it
|
|
369
416
|
// records nothing.
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
417
|
+
if (decision.verdict === "defer") {
|
|
418
|
+
stampGateDecision(opts, proposal.id, {
|
|
419
|
+
outcome: "deferred",
|
|
420
|
+
reason: decision.gate.reason,
|
|
421
|
+
...(decision.gate.measured !== undefined ? { measured: decision.gate.measured } : {}),
|
|
422
|
+
...(decision.gate.thresholds ? { thresholds: decision.gate.thresholds } : {}),
|
|
423
|
+
gate: gateLabel,
|
|
424
|
+
});
|
|
425
|
+
}
|
|
378
426
|
// A defer with no threshold (mid-band / possible-dup from the defer list) is
|
|
379
427
|
// pending only because it needs adjudication — re-stampable to
|
|
380
428
|
// `no-judge-configured`. A band-based defer keeps its specific reason.
|
|
@@ -383,6 +431,7 @@ export async function drainProposals(opts, promoteFn = akmProposalAccept, reject
|
|
|
383
431
|
}
|
|
384
432
|
if (decision.verdict === "accept") {
|
|
385
433
|
acceptIds.push(proposal.id);
|
|
434
|
+
acceptGateReasons.set(proposal.id, "policy-accept");
|
|
386
435
|
}
|
|
387
436
|
else if (decision.verdict === "reject") {
|
|
388
437
|
rejectTargets.push({ id: proposal.id, reason: decision.reason });
|
|
@@ -398,7 +447,12 @@ export async function drainProposals(opts, promoteFn = akmProposalAccept, reject
|
|
|
398
447
|
continue;
|
|
399
448
|
}
|
|
400
449
|
try {
|
|
401
|
-
await rejectFn({
|
|
450
|
+
await rejectFn({
|
|
451
|
+
stashDir: opts.stashDir,
|
|
452
|
+
id: target.id,
|
|
453
|
+
reason: target.reason,
|
|
454
|
+
gateDecision: { outcome: "auto-rejected", reason: "empty-diff", gate: gateLabel },
|
|
455
|
+
});
|
|
402
456
|
result.rejected.push(target.id);
|
|
403
457
|
}
|
|
404
458
|
catch (err) {
|
|
@@ -424,6 +478,11 @@ export async function drainProposals(opts, promoteFn = akmProposalAccept, reject
|
|
|
424
478
|
id,
|
|
425
479
|
...(opts.target ? { target: opts.target } : {}),
|
|
426
480
|
...(opts.config ? { config: opts.config } : {}),
|
|
481
|
+
gateDecision: {
|
|
482
|
+
outcome: "auto-accepted",
|
|
483
|
+
reason: acceptGateReasons.get(id) ?? "policy-accept",
|
|
484
|
+
gate: gateLabel,
|
|
485
|
+
},
|
|
427
486
|
});
|
|
428
487
|
result.promoted.push(id);
|
|
429
488
|
deterministicPromoted += 1;
|
|
@@ -434,10 +493,31 @@ export async function drainProposals(opts, promoteFn = akmProposalAccept, reject
|
|
|
434
493
|
}
|
|
435
494
|
}
|
|
436
495
|
else if (opts.applyMode === "promote" && opts.dryRun) {
|
|
437
|
-
//
|
|
438
|
-
//
|
|
439
|
-
|
|
440
|
-
|
|
496
|
+
// Exercise the same stamped candidate and lint boundary as real promotion.
|
|
497
|
+
// Tests that omit config retain the classification-only seam.
|
|
498
|
+
const byId = new Map(pending.map((proposal) => [proposal.id, proposal]));
|
|
499
|
+
for (const id of withinCap) {
|
|
500
|
+
try {
|
|
501
|
+
if (opts.config) {
|
|
502
|
+
const proposal = byId.get(id);
|
|
503
|
+
if (!proposal)
|
|
504
|
+
throw new Error(`Proposal ${id} disappeared during drain preflight.`);
|
|
505
|
+
preflightProposalPromotion(opts.config, proposal, {
|
|
506
|
+
...(opts.target ? { target: opts.target } : {}),
|
|
507
|
+
gateDecision: {
|
|
508
|
+
outcome: "auto-accepted",
|
|
509
|
+
reason: acceptGateReasons.get(id) ?? "policy-accept",
|
|
510
|
+
gate: gateLabel,
|
|
511
|
+
},
|
|
512
|
+
});
|
|
513
|
+
}
|
|
514
|
+
result.promoted.push(id);
|
|
515
|
+
deterministicPromoted += 1;
|
|
516
|
+
}
|
|
517
|
+
catch (err) {
|
|
518
|
+
warn(`[triage] preflight failed for ${id}: ${err instanceof Error ? err.message : String(err)}`);
|
|
519
|
+
}
|
|
520
|
+
}
|
|
441
521
|
}
|
|
442
522
|
// applyMode "queue": leave accept candidates pending (staged). No promotion.
|
|
443
523
|
// Remaining accept budget for the judgment tier: maxAccepts minus what was
|
|
@@ -461,6 +541,7 @@ export async function drainProposals(opts, promoteFn = akmProposalAccept, reject
|
|
|
461
541
|
...(opts.target ? { target: opts.target } : {}),
|
|
462
542
|
...(opts.config ? { config: opts.config } : {}),
|
|
463
543
|
remainingAcceptBudget,
|
|
544
|
+
gateLabel,
|
|
464
545
|
});
|
|
465
546
|
result.promoted.push(...tier.promoted);
|
|
466
547
|
result.rejected.push(...tier.rejected);
|
|
@@ -471,15 +552,6 @@ export async function drainProposals(opts, promoteFn = akmProposalAccept, reject
|
|
|
471
552
|
if (tier.skippedByCap.length > 0) {
|
|
472
553
|
info(`[triage] accept ceiling reached in judgment tier: ${tier.skippedByCap.length} judged-accept items skipped by cap (maxAccepts=${opts.maxAccepts})`);
|
|
473
554
|
}
|
|
474
|
-
// #577: re-stamp the gate decision for items the judgment tier resolved so
|
|
475
|
-
// `akm proposal show` reflects the judge's verdict, not the earlier
|
|
476
|
-
// deterministic defer.
|
|
477
|
-
for (const id of tier.promoted) {
|
|
478
|
-
stampGateDecision(opts, id, { outcome: "auto-accepted", reason: "judgment-accept", gate: gateLabel });
|
|
479
|
-
}
|
|
480
|
-
for (const id of tier.rejected) {
|
|
481
|
-
stampGateDecision(opts, id, { outcome: "auto-rejected", reason: "judgment-reject", gate: gateLabel });
|
|
482
|
-
}
|
|
483
555
|
// Replace the deferred list with only the items the judgment tier could NOT
|
|
484
556
|
// resolve (verdict "defer", parse failure, or runner error). Staged
|
|
485
557
|
// queue-mode accepts are RESOLVED and tracked in result.staged instead.
|