akm-cli 0.9.30 → 0.10.261001-beta
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 +438 -0
- package/README.md +10 -10
- package/ROADMAP.md +112 -0
- package/STABILITY.md +99 -57
- package/dist/api-node.mjs +20 -0
- package/dist/api.d.ts +23 -0
- package/dist/api.js +45 -0
- package/dist/assets/hints/cli-hints-full.md +15 -29
- package/dist/assets/hints/cli-hints-short.md +2 -2
- package/dist/assets/improve-strategies/default.json +3 -3
- package/dist/assets/prompts/consolidate-pair.md +9 -7
- package/dist/assets/stash-skeleton/README.md +1 -1
- package/dist/assets/tasks/improve/akm-improve-consolidate.yml +1 -1
- package/dist/cli/shared.js +31 -48
- package/dist/cli/unknown-flags.js +6 -43
- package/dist/cli.js +8 -34
- package/dist/commands/agent/contribute-cli.js +1 -1
- package/dist/commands/completions.js +1 -2
- package/dist/commands/config-cli.js +5 -28
- package/dist/commands/env/env-cli.js +5 -5
- package/dist/commands/env/secret-cli.js +2 -2
- package/dist/commands/feedback-cli.js +75 -49
- package/dist/commands/health/checks.js +41 -16
- package/dist/commands/health/plugin-staleness.js +52 -22
- package/dist/commands/improve/autonomy-gate.js +5 -3
- package/dist/commands/improve/consolidate/chunking.js +3 -10
- package/dist/commands/improve/consolidate/continuity-check.js +4 -4
- package/dist/commands/improve/consolidate/pair-pass.js +29 -10
- package/dist/commands/improve/consolidate.js +10 -65
- package/dist/commands/improve/distill/lesson-update.js +91 -0
- package/dist/commands/improve/distill-guards.js +1 -43
- package/dist/commands/improve/distill.js +148 -21
- package/dist/commands/improve/eligibility.js +14 -1
- package/dist/commands/improve/extract-cli.js +1 -1
- package/dist/commands/improve/extract-prompt.js +17 -7
- package/dist/commands/improve/extract.js +5 -7
- package/dist/commands/improve/improve-cli.js +125 -118
- package/dist/commands/improve/improve-strategies.js +8 -12
- package/dist/commands/improve/improve.js +134 -52
- package/dist/commands/improve/loop-stages.js +18 -5
- package/dist/commands/improve/planner.js +0 -1
- package/dist/commands/improve/preparation.js +40 -99
- package/dist/commands/improve/proactive-maintenance.js +2 -2
- package/dist/commands/improve/reflect-noise.js +3 -55
- package/dist/commands/improve/reflect.js +29 -34
- package/dist/commands/improve/retrieval-queries.js +37 -0
- package/dist/commands/improve/retrieval-scope.js +2 -2
- package/dist/commands/improve/salience.js +2 -9
- package/dist/commands/improve/session-asset.js +4 -1
- package/dist/commands/improve/stage.js +23 -12
- package/dist/commands/lint/index.js +5 -20
- package/dist/commands/observability-cli.js +3 -9
- package/dist/commands/proposal/drain.js +43 -6
- package/dist/commands/proposal/proposal-cli.js +11 -31
- package/dist/commands/proposal/repository.js +20 -14
- package/dist/commands/proposal/validators/proposal-quality-validators.js +0 -3
- package/dist/commands/read/knowledge.js +3 -3
- package/dist/commands/read/remember-cli.js +0 -13
- package/dist/commands/read/search-cli.js +29 -97
- package/dist/commands/read/search.js +0 -11
- package/dist/commands/read/show.js +0 -19
- package/dist/commands/sources/plugin-upgrade.js +164 -101
- package/dist/commands/sources/sources-cli.js +1 -15
- package/dist/commands/sources/stash-cli.js +6 -14
- package/dist/commands/tasks/tasks-cli.js +4 -115
- package/dist/commands/workflow/plan.js +11 -33
- package/dist/commands/workflow-cli.js +2 -7
- package/dist/core/adapter/adapter-ids.js +1 -2
- package/dist/core/adapter/adapters/agent-skills-adapter.js +0 -4
- package/dist/core/adapter/adapters/akm-adapter.js +9 -48
- package/dist/core/adapter/adapters/akm-lint.js +10 -26
- package/dist/core/adapter/adapters/akm-metadata.js +2 -72
- package/dist/core/adapter/adapters/akm-task-adapter.js +0 -5
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +9 -28
- package/dist/core/adapter/adapters/dotenv-adapter.js +1 -20
- package/dist/core/adapter/adapters/generic-files-adapter.js +0 -10
- package/dist/core/adapter/adapters/llm-wiki-adapter.js +0 -4
- package/dist/core/adapter/adapters/tool-dir-shared.js +0 -24
- package/dist/core/adapter/adapters/website-snapshot-adapter.js +4 -4
- package/dist/core/adapter/recognize-match.js +3 -4
- package/dist/core/common.js +18 -2
- package/dist/core/config/config-schema.js +12 -15
- package/dist/core/config/config-types.js +6 -15
- package/dist/core/config/config-walker.js +6 -23
- package/dist/core/config/config.js +17 -80
- package/dist/core/config/engine-semantics.js +7 -3
- package/dist/core/config/schema/engines.js +7 -7
- package/dist/core/config/schema/improve-processes.js +10 -63
- package/dist/core/config/schema/improve.js +2 -21
- package/dist/core/config/schema/index-config.js +6 -39
- package/dist/core/env-secret-ref.js +2 -45
- package/dist/core/errors.js +1 -2
- package/dist/core/extra-params.js +2 -86
- package/dist/core/file-lock.js +12 -7
- package/dist/core/improve-result.js +13 -1
- package/dist/core/mutation-target.js +2 -2
- package/dist/core/paths.js +4 -0
- package/dist/core/recognition-util.js +4 -5
- package/dist/core/run-lock.js +1 -1
- package/dist/core/subprocess.js +49 -0
- package/dist/core/warn.js +21 -4
- package/dist/core/write-source.js +3 -3
- package/dist/execution/target-ref.js +1 -2
- package/dist/indexer/indexer.js +15 -6
- package/dist/indexer/passes/memory-inference.js +15 -6
- package/dist/indexer/search/db-search.js +49 -36
- package/dist/indexer/search/fts-query.js +0 -19
- package/dist/indexer/search/ranking.js +29 -1
- package/dist/indexer/usage/usage-events.js +21 -16
- package/dist/integrations/agent/engine-resolution.js +5 -2
- package/dist/integrations/agent/index.js +1 -1
- package/dist/integrations/agent/profiles.js +41 -98
- package/dist/integrations/agent/request-lowering.js +3 -3
- package/dist/integrations/harnesses/aider/index.js +5 -0
- package/dist/integrations/harnesses/amazonq/index.js +1 -0
- package/dist/integrations/harnesses/claude/config-import.js +2 -3
- package/dist/integrations/harnesses/claude/index.js +5 -0
- package/dist/integrations/harnesses/codex/index.js +1 -0
- package/dist/integrations/harnesses/copilot/index.js +1 -0
- package/dist/integrations/harnesses/gemini/index.js +1 -0
- package/dist/integrations/harnesses/index.js +18 -39
- package/dist/integrations/harnesses/opencode/agent-builder.js +60 -35
- package/dist/integrations/harnesses/opencode/config-import.js +121 -52
- package/dist/integrations/harnesses/opencode/index.js +22 -0
- package/dist/integrations/harnesses/opencode/plugin-layout.js +68 -0
- package/dist/integrations/harnesses/opencode/session-log-types.js +12 -0
- package/dist/integrations/harnesses/opencode/session-log-v1.js +72 -0
- package/dist/integrations/harnesses/opencode/session-log-v2.js +140 -0
- package/dist/integrations/harnesses/opencode/session-log.js +104 -115
- package/dist/integrations/harnesses/opencode/version.js +98 -0
- package/dist/integrations/harnesses/opencode-sdk/{harness.js → index.js} +5 -17
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +105 -206
- package/dist/integrations/harnesses/opencode-sdk/v1-adapter.js +199 -0
- package/dist/integrations/harnesses/opencode-sdk/v2-adapter.js +254 -0
- package/dist/integrations/harnesses/opencode-sdk/wire.js +66 -0
- package/dist/integrations/harnesses/openhands/index.js +1 -0
- package/dist/integrations/harnesses/pi/index.js +1 -0
- package/dist/integrations/harnesses/shared.js +2 -0
- package/dist/integrations/harnesses/types.js +2 -0
- package/dist/llm/client.js +74 -14
- package/dist/output/cli-hints.js +1 -1
- package/dist/output/context.js +10 -19
- package/dist/output/format-exempt.js +5 -8
- package/dist/output/shapes/helpers.js +1 -22
- package/dist/output/shapes/passthrough.js +0 -1
- package/dist/output/shapes.js +3 -31
- package/dist/output/stdout.js +5 -1
- package/dist/output/text/command-format.js +6 -1
- package/dist/output/text/workflow-format.js +4 -22
- package/dist/scripts/akm-migrate-node.js +15769 -16731
- package/dist/scripts/akm-migrate.js +16339 -17297
- package/dist/setup/detect.js +10 -4
- package/dist/setup/harness-config-import.js +5 -14
- package/dist/setup/setup.js +1 -1
- package/dist/setup/steps/tasks.js +12 -13
- package/dist/sources/providers/git-stash.js +94 -13
- package/dist/storage/repositories/index-utility-repository.js +2 -32
- package/dist/storage/repositories/index-vec-repository.js +4 -0
- package/dist/storage/repositories/task-history-repository.js +0 -5
- package/dist/storage/repositories/workflow-runs-repository.js +5 -15
- package/dist/tasks/embedded.js +2 -1
- package/dist/tasks/run/run-command-task.js +9 -1
- package/dist/tasks/run/run-workflow-task.js +4 -3
- package/dist/tasks/run/task-history.js +0 -2
- package/dist/tasks/run/task-log.js +38 -1
- package/dist/tasks/schedule-gates.js +39 -0
- package/dist/tasks/scheduler-binding.js +0 -16
- package/dist/tasks/scheduler-sync.js +3 -97
- package/dist/tasks/source/bounded-document.js +1 -1
- package/dist/tasks/source/task-source-v4.js +2 -12
- package/dist/tasks/task-run-reserved-flags.js +2 -31
- package/dist/workflows/authoring/authoring.js +6 -6
- package/dist/workflows/compile.js +8 -65
- package/dist/workflows/exec/child-workflow.js +22 -3
- package/dist/workflows/exec/native-executor.js +12 -147
- package/dist/workflows/exec/run-workflow.js +31 -103
- package/dist/workflows/exec/step-work.js +9 -178
- package/dist/workflows/exec/unit-dispatch.js +0 -10
- package/dist/workflows/freeze/environment.js +3 -44
- package/dist/workflows/freeze/freeze.js +8 -41
- package/dist/workflows/freeze/targets/child-workflow.js +27 -63
- package/dist/workflows/freeze/targets/command.js +2 -16
- package/dist/workflows/freeze/targets/shell.js +0 -2
- package/dist/workflows/freeze/task-bindings.js +2 -28
- package/dist/workflows/ir/params.js +12 -2
- package/dist/workflows/parser.js +82 -232
- package/dist/workflows/plan.js +1 -1
- package/dist/workflows/renderer.js +10 -19
- package/dist/workflows/runtime/run-plan.js +11 -53
- package/dist/workflows/runtime/runs.js +4 -27
- package/dist/workflows/source-files.js +12 -16
- package/dist/workflows/source-semantics.js +1 -93
- package/docs/README.md +43 -42
- package/docs/agents/README.md +15 -0
- package/docs/agents/agent-install.md +14 -0
- package/docs/architecture/0.10-process-rules.md +827 -0
- package/docs/architecture/README.md +67 -0
- package/docs/architecture/adapters.md +258 -0
- package/docs/architecture/akm-architecture-decision-history.md +2055 -0
- package/docs/architecture/akm-core-principles.md +126 -0
- package/docs/architecture/architecture.md +578 -0
- package/docs/architecture/comparisons/claude-code-vs-akm-workflows-full.md +550 -0
- package/docs/architecture/decisions/0001-no-interpolation-attached-structured-context.md +72 -0
- package/docs/architecture/decisions/0002-unit-reuse-and-input-hash-scope.md +142 -0
- package/docs/architecture/decisions/0003-child-env-allowlist-and-provenance.md +189 -0
- package/docs/architecture/decisions/0004-task-input-contract-and-flag-coercion.md +97 -0
- package/docs/architecture/decisions/0005-task-result-vocabulary-and-legacy-read-mapping.md +108 -0
- package/docs/architecture/decisions/0006-task-source-version-routing.md +124 -0
- package/docs/architecture/decisions/0007-workflow-composition-bounds.md +83 -0
- package/docs/architecture/decisions/0008-task-binding-normalization.md +88 -0
- package/docs/architecture/decisions/0009-child-run-publication-column-parity.md +80 -0
- package/docs/architecture/decisions/0010-driver-protocol-cut.md +36 -0
- package/docs/architecture/decisions/0011-engine-run-loop-invariants.md +125 -0
- package/docs/architecture/decisions/README.md +62 -0
- package/docs/architecture/improvement.md +479 -0
- package/docs/architecture/internals/classification.md +154 -0
- package/docs/architecture/internals/fresh-host-rebuild-runbook.md +40 -0
- package/docs/architecture/internals/functional-contract-patterns.md +340 -0
- package/docs/architecture/internals/health-advisories.md +110 -0
- package/docs/architecture/internals/improve-workflow.md +719 -0
- package/docs/architecture/internals/indexing.md +498 -0
- package/docs/architecture/internals/registry-network-boundary.md +57 -0
- package/docs/architecture/internals/search.md +248 -0
- package/docs/architecture/internals/storage-locations.md +943 -0
- package/docs/architecture/persisted-data-compat.md +68 -0
- package/docs/architecture/reviews/env-secret-access.md +319 -0
- package/docs/architecture/runtime-boundary-design.md +153 -0
- package/docs/architecture/specs/0.9.0-close-out-plan.md +361 -0
- package/docs/architecture/specs/0.9.0-decisions.md +532 -0
- package/docs/architecture/specs/0.9.0-docs-code-drift-register.md +745 -0
- package/docs/architecture/specs/0.9.0-open-items-register.md +135 -0
- package/docs/architecture/specs/0.9.0-public-api-issue-backlog.md +740 -0
- package/docs/architecture/specs/0.9.0-release-surface-review.md +636 -0
- package/docs/architecture/specs/agent-command-engine-model-design.md +513 -0
- package/docs/architecture/specs/akm-0.9.0-bundle-adapter-spec.md +501 -0
- package/docs/architecture/specs/akm-0.9.0-ref-grammar-decision.md +291 -0
- package/docs/architecture/specs/akm-format-neutral-bundle-workspace-spec.md +2059 -0
- package/docs/architecture/specs/di-seams-plan.md +539 -0
- package/docs/architecture/specs/driver-protocol-keep-or-cut.md +275 -0
- package/docs/architecture/specs/fact-asset-type.md +142 -0
- package/docs/architecture/specs/improve-collapse-churn-detector-design.md +634 -0
- package/docs/architecture/specs/okf-support.md +148 -0
- package/docs/architecture/specs/ref.md +329 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/README.md +72 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/findings-consolidated.md +152 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-alternatives.md +352 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-bunqueue.md +300 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-openworkflow.md +402 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-1.md +758 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-2.md +645 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-3.md +602 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-adversarial.md +27 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-architecture.md +27 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-coverage.md +74 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-security.md +15 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r2-adversarial.md +132 -0
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r2-verification.md +147 -0
- package/docs/architecture/specs/stash-conventions-code-spec.md +275 -0
- package/docs/architecture/specs/stash-organization-conventions.md +377 -0
- package/docs/architecture/specs/task-workflow-format-unification.md +721 -0
- package/docs/architecture/specs/workflow-engine-buy-vs-build.md +231 -0
- package/docs/architecture/specs/workflow-format-unification.md +432 -0
- package/docs/architecture/testing/manual-testing-checklist.md +3411 -0
- package/docs/architecture/testing/okf-v0.2-conformance-runbook.md +924 -0
- package/docs/architecture/testing/task-workflow-manual-tests.md +1720 -0
- package/docs/architecture/testing/testing-workflow.md +446 -0
- package/docs/architecture/workflow-engine.md +223 -0
- package/docs/guides/README.md +33 -0
- package/docs/guides/author-bundles.md +310 -0
- package/docs/guides/author-workflows.md +490 -0
- package/docs/guides/bundles.md +323 -0
- package/docs/guides/capture-knowledge.md +136 -0
- package/docs/guides/claude-code-vs-akm-workflows.md +29 -0
- package/docs/guides/concepts.md +93 -0
- package/docs/guides/discover-and-load.md +158 -0
- package/docs/guides/getting-started.md +240 -0
- package/docs/guides/improve-the-library.md +247 -0
- package/docs/guides/knowledge-management.md +18 -0
- package/docs/guides/recipes/headless-install.md +97 -0
- package/docs/guides/recipes/website-source.md +28 -0
- package/docs/guides/run-workflows.md +279 -0
- package/docs/guides/scheduling.md +131 -0
- package/docs/guides/use-with-any-agent.md +174 -0
- package/docs/guides/wikis.md +81 -0
- package/docs/integration/bundling-akm.md +7 -6
- package/docs/maintainers/README.md +19 -0
- package/docs/maintainers/curate-workmap.md +335 -0
- package/docs/maintainers/eval.md +3 -0
- package/docs/maintainers/local-development.md +108 -0
- package/docs/maintainers/release-checklist.md +135 -0
- package/docs/migration/README.md +4 -2
- package/docs/migration/release-notes/0.0.13.md +1 -1
- package/docs/migration/release-notes/0.1.0.md +1 -1
- package/docs/migration/release-notes/0.10.0.md +201 -0
- package/docs/migration/release-notes/0.2.0.md +1 -1
- package/docs/migration/release-notes/0.3.0.md +1 -1
- package/docs/migration/release-notes/0.5.0.md +1 -1
- package/docs/migration/release-notes/0.6.0.md +1 -1
- package/docs/migration/release-notes/0.7.0.md +1 -1
- package/docs/migration/release-notes/0.7.3.md +2 -2
- package/docs/migration/release-notes/0.7.4.md +1 -1
- package/docs/migration/release-notes/0.7.5.md +1 -1
- package/docs/migration/release-notes/0.8.0.md +1 -1
- package/docs/migration/release-notes/0.9.0.md +1 -1
- package/docs/migration/release-notes/0.9.14.md +1 -1
- package/docs/migration/release-notes/0.9.15.md +1 -1
- package/docs/migration/release-notes/0.9.16.md +1 -1
- package/docs/migration/release-notes/0.9.17.md +1 -1
- package/docs/migration/release-notes/0.9.19.md +1 -1
- package/docs/migration/release-notes/0.9.2.md +1 -1
- package/docs/migration/release-notes/README.md +28 -31
- package/docs/migration/v0.5-to-v0.6.md +759 -0
- package/docs/migration/v0.8-to-v0.9.md +1 -1
- package/docs/migration/v0.9-to-v0.10.md +507 -0
- package/docs/plans/0.9.2-agent-command-workflow-plan.md +423 -0
- package/docs/posts/README.md +30 -0
- package/docs/posts/akm-command-tour.md +495 -0
- package/docs/posts/akm-logo-sized.webp +0 -0
- package/docs/posts/belief-aware-memory-12.md +139 -0
- package/docs/posts/config-v2-lessons-16.md +191 -0
- package/docs/posts/improve-loop-autonomous-10.md +225 -0
- package/docs/posts/improve-pipeline-debugging-0803.md +179 -0
- package/docs/posts/intro-part-01.md +76 -0
- package/docs/posts/intro-part-02.md +221 -0
- package/docs/posts/intro-part-03.md +190 -0
- package/docs/posts/intro-part-04.md +221 -0
- package/docs/posts/llm-mode-reflect-13.md +166 -0
- package/docs/posts/openpalm-built-on-akm.md +86 -0
- package/docs/posts/progressive-disclosure-06.md +129 -0
- package/docs/posts/proposal-safety-net-15.md +112 -0
- package/docs/posts/release-0.5.0.md +247 -0
- package/docs/posts/release-0.6.0.md +117 -0
- package/docs/posts/release-0.7.0.md +159 -0
- package/docs/posts/release-0.8.0.md +332 -0
- package/docs/posts/scattered-skills-05.md +100 -0
- package/docs/posts/task-assets-persistent-workflows-11.md +222 -0
- package/docs/posts/team-skills-07.md +198 -0
- package/docs/posts/wiki-agent-knowledge-08.md +223 -0
- package/docs/posts/workflows-vaults-09.md +321 -0
- package/docs/product-surface.md +54 -0
- package/docs/reference/README.md +2 -2
- package/docs/reference/api.md +65 -0
- package/docs/reference/asset-types.md +166 -0
- package/docs/reference/bundle-types.md +2 -4
- package/docs/reference/cli.md +163 -192
- package/docs/reference/configuration.md +101 -20
- package/docs/reference/data-and-telemetry.md +2 -2
- package/docs/reference/env-and-secrets.md +126 -0
- package/docs/reference/memory.md +124 -0
- package/docs/reference/refs.md +156 -0
- package/docs/reference/registry.md +489 -0
- package/docs/reference/supported-formats.md +3 -4
- package/docs/reference/tasks.md +12 -19
- package/docs/reference/website-sources.md +141 -0
- package/docs/reference/workflow-schema.md +89 -317
- package/docs/reference/workflows.md +20 -48
- package/package.json +23 -16
- package/schemas/akm-config.json +2 -243
- package/schemas/akm-task.json +2 -3
- package/schemas/akm-workflow.json +47 -84
- package/dist/assets/improve-strategies/catchup.json +0 -41
- package/dist/assets/improve-strategies/proactive-maintenance.json +0 -24
- package/dist/assets/improve-strategies/quick.json +0 -17
- package/dist/assets/improve-strategies/reflect-distill.json +0 -29
- package/dist/assets/improve-strategies/thorough.json +0 -49
- package/dist/assets/prompts/retrieval-relevance-judge.md +0 -6
- package/dist/assets/tasks/improve/akm-improve-catchup.yml +0 -6
- package/dist/assets/tasks/improve/akm-improve-frequent.yml +0 -4
- package/dist/assets/tasks/improve/akm-improve-nightly.yml +0 -4
- package/dist/cli/retired-commands.js +0 -118
- package/dist/commands/improve/retrieval-gate.js +0 -132
- package/dist/commands/tasks/validate.js +0 -176
- package/dist/core/config/legacy-source-shape-shim.js +0 -117
- package/dist/indexer/feedback/utility-policy.js +0 -75
- package/dist/integrations/harnesses/ids.js +0 -28
- package/dist/tasks/source/task-source-v3-frozen.js +0 -424
- package/dist/tasks/source/task-to-v4.js +0 -863
- package/dist/workflows/exec/worktree.js +0 -372
- package/dist/workflows/freeze/child-output-references.js +0 -83
- package/dist/workflows/freeze/identity.js +0 -22
- package/dist/workflows/freeze/targets/script.js +0 -50
- package/dist/workflows/freeze/targets/task.js +0 -124
- package/dist/workflows/github-yaml.js +0 -506
- package/dist/workflows/runtime/run-outputs.js +0 -80
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
# Testing Workflow
|
|
2
|
+
|
|
3
|
+
This project is a CLI with three risk-heavy areas:
|
|
4
|
+
|
|
5
|
+
- command behavior across real files, config, and cache directories
|
|
6
|
+
- managed-source install/update flows
|
|
7
|
+
- binary deployment and self-upgrade behavior
|
|
8
|
+
|
|
9
|
+
The safest way to test it is in layers: fast local checks first, then end-to-end
|
|
10
|
+
CLI coverage, then Docker-based deployment and upgrade validation. This document
|
|
11
|
+
owns automated test workflow and test-authoring guidance only. The authoritative
|
|
12
|
+
manual setup, command matrix, expected behavior, release gates, evidence, and
|
|
13
|
+
cleanup live in [AKM Manual Testing Runbook](./manual-testing-checklist.md).
|
|
14
|
+
|
|
15
|
+
## What To Validate
|
|
16
|
+
|
|
17
|
+
- core CLI flows: `setup`, `index`, `search`, `show`, `info`, `bundle list`, `config`
|
|
18
|
+
- asset lifecycle: add assets, re-index, search, show, and incremental refresh
|
|
19
|
+
- managed-source lifecycle: `akm bundle add`, `akm bundle list`, `akm bundle update`, `akm bundle remove`
|
|
20
|
+
- binary lifecycle: install, run, `akm upgrade --check`, `akm upgrade`
|
|
21
|
+
- cross-environment behavior on Ubuntu, Debian, Alpine, and Fedora containers
|
|
22
|
+
|
|
23
|
+
## Test Layers In This Repo
|
|
24
|
+
|
|
25
|
+
### 1. Fast local correctness
|
|
26
|
+
|
|
27
|
+
Run these before any release candidate or merge:
|
|
28
|
+
|
|
29
|
+
```sh
|
|
30
|
+
bun run test:unit
|
|
31
|
+
bunx biome check --write src/ tests/
|
|
32
|
+
bunx tsc --noEmit
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Use this when you want the shortest full-project signal:
|
|
36
|
+
|
|
37
|
+
```sh
|
|
38
|
+
bun run check
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Relevant coverage:
|
|
42
|
+
|
|
43
|
+
- `tests/integration/self-update.test.ts` - self-upgrade detection and checksum enforcement
|
|
44
|
+
- `tests/integration/registry-*.test.ts`, `tests/provider-registry.test.ts` - `list`, `remove`, `update`, cache cleanup, install resolution, tar safety, local/git/npm paths
|
|
45
|
+
- `tests/integration/setup-run.test.ts` - full setup wizard orchestration and failure handling
|
|
46
|
+
- `tests/integration/install-script.test.ts` - repeatable `install.sh` edge cases and permission paths
|
|
47
|
+
|
|
48
|
+
### Writing deterministic, isolated tests
|
|
49
|
+
|
|
50
|
+
Both `scripts/test-unit.sh` (`bun run test:unit`) and `scripts/test-integration.sh`
|
|
51
|
+
(`bun run test:integration`) shard their target across up to `min(nproc, 8)`
|
|
52
|
+
concurrent `bun test` processes, splitting the file list round-robin — neither
|
|
53
|
+
runner is a single shared process, and neither is "the unit suite" alone.
|
|
54
|
+
Within one shard, every file assigned to that process still runs in **one
|
|
55
|
+
shared process**: one `process.env`, one module-singleton namespace, and
|
|
56
|
+
(under fake timers) one global clock for every file in that shard. A test that
|
|
57
|
+
mutates shared state without restoring it, or that asserts on a wall-clock
|
|
58
|
+
measurement, can pass on one scheduling and
|
|
59
|
+
fail on another — the two release/0.8.0 flakes (scoring-pipeline Issue #14
|
|
60
|
+
reading the wrong index DB after a sibling mutated `XDG_DATA_HOME`; the
|
|
61
|
+
llm-client timeout test racing real timers) were both this class.
|
|
62
|
+
|
|
63
|
+
Rules (conventions, not statically enforced — the lint script that policed
|
|
64
|
+
them was deleted in 0.9.8; the runtime guard in `src/core/paths.ts` throws
|
|
65
|
+
`TEST_ISOLATION_MISSING` and the preload tripwire catches leaks):
|
|
66
|
+
|
|
67
|
+
1. **Never mutate `AKM_*` / `XDG_*` / `HOME` on `process.env` directly.** Use the
|
|
68
|
+
sanctioned helpers in `tests/_helpers/sandbox.ts`:
|
|
69
|
+
- `sandboxStashDir`, `sandboxXdgConfigHome`, `sandboxXdgDataHome`,
|
|
70
|
+
`sandboxXdgCacheHome`, `sandboxXdgStateHome`, `sandboxHome` — set the env var
|
|
71
|
+
to an isolated temp dir and return a `cleanup` that restores the prior value.
|
|
72
|
+
Chain them and call `cleanup()` in `afterEach`.
|
|
73
|
+
- `withEnv({ AKM_BUNDLE_DIR }, async () => …)` — scoped override that always
|
|
74
|
+
restores in a `finally`, even on throw. Use this for per-call overrides
|
|
75
|
+
around an in-process CLI invocation.
|
|
76
|
+
- `makeStashDir` / `makeSandboxDir` — temp dirs that are NOT wired into env
|
|
77
|
+
(pass them to `withEnv` or a subprocess env object yourself).
|
|
78
|
+
|
|
79
|
+
The DB path resolves from `XDG_DATA_HOME`; if you `akmIndex` then `akmSearch`,
|
|
80
|
+
both must see the **same** sandboxed `XDG_DATA_HOME` or the search reads a
|
|
81
|
+
different (empty/stale) DB. Sandbox it in `beforeEach`.
|
|
82
|
+
|
|
83
|
+
2. **Do not assert on a measured wall-clock delta.** `expect(Date.now() - start)
|
|
84
|
+
.toBeLessThan(N)` races the scheduler. Assert the *observable result* instead
|
|
85
|
+
(e.g. `result.reason === "timeout"`), or drive time deterministically with
|
|
86
|
+
`jest.useFakeTimers()` + `jest.advanceTimersByTime(...)` and a fetch/spawn stub.
|
|
87
|
+
Asserting on a `durationMs` field computed from injected fixture timestamps is
|
|
88
|
+
fine (it is deterministic).
|
|
89
|
+
|
|
90
|
+
3. **Sort/compare on the value the user sees.** When a test asserts ordering,
|
|
91
|
+
make the production sort key the same quantized value that is displayed
|
|
92
|
+
(`db-search.ts` sorts on the clamped+rounded score, then breaks ties by name),
|
|
93
|
+
so an invisible sub-display-precision epsilon can never reorder visible ties.
|
|
94
|
+
|
|
95
|
+
4. **Avoid stateful feedback within one test.** Re-running `akmSearch` without
|
|
96
|
+
`skipLogging: true` writes utility/recency rows that perturb the next search's
|
|
97
|
+
ranking. Pass `skipLogging: true` when you need repeatable ranking across
|
|
98
|
+
calls in a single test.
|
|
99
|
+
|
|
100
|
+
If a file legitimately needs a literal env value (e.g. pure path-resolution unit
|
|
101
|
+
tests) and restores via its own save/restore wrapper, add it to the linter's
|
|
102
|
+
`ENV_ASSIGN_ALLOWED` set with a one-line justification — the list may only shrink.
|
|
103
|
+
|
|
104
|
+
### 2. End-to-end CLI validation
|
|
105
|
+
|
|
106
|
+
Run the full integration suite when changing CLI behavior, indexing, search,
|
|
107
|
+
config, source management, or output shaping:
|
|
108
|
+
|
|
109
|
+
```sh
|
|
110
|
+
bun run test:integration
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
Collectively, these suites (`tests/integration/`) exercise real flows,
|
|
114
|
+
including:
|
|
115
|
+
|
|
116
|
+
- fallback search without an index
|
|
117
|
+
- `index -> search -> show`
|
|
118
|
+
- CLI subprocess execution through `src/cli.ts`
|
|
119
|
+
- config read/write behavior
|
|
120
|
+
- registry-source compatibility
|
|
121
|
+
- progressive indexing and re-indexing
|
|
122
|
+
- update and upgrade command error paths
|
|
123
|
+
- knowledge `#fragment` selection and mixed asset discovery
|
|
124
|
+
|
|
125
|
+
## Semantic Search States
|
|
126
|
+
|
|
127
|
+
Semantic search does not behave as a simple on/off feature at runtime. Testing
|
|
128
|
+
should distinguish between saved-config state and actual readiness.
|
|
129
|
+
|
|
130
|
+
### Config intent
|
|
131
|
+
|
|
132
|
+
Semantic search intent is saved independently as `semanticSearchMode`:
|
|
133
|
+
|
|
134
|
+
- `off` when the user opts out explicitly
|
|
135
|
+
- `auto` when the user wants semantic search enabled
|
|
136
|
+
|
|
137
|
+
Setup should not flip intent from `auto` back to `off` because preparation or
|
|
138
|
+
verification fails transiently.
|
|
139
|
+
|
|
140
|
+
### Runtime readiness
|
|
141
|
+
|
|
142
|
+
Actual semantic readiness is tracked separately from config intent. Runtime state
|
|
143
|
+
can be:
|
|
144
|
+
|
|
145
|
+
- `pending` when semantic search is enabled but not yet verified
|
|
146
|
+
- `ready-js` when every entry has a vector (the name is historical; there is no other vector path)
|
|
147
|
+
- `blocked` when semantic search cannot run with the current provider/setup
|
|
148
|
+
|
|
149
|
+
These cases are covered by `tests/integration/setup-run.test.ts` and the focused
|
|
150
|
+
semantic/config suites.
|
|
151
|
+
|
|
152
|
+
The real-model gate (`AKM_SEMANTIC_TESTS=1`) honors an explicit `HF_HOME` and
|
|
153
|
+
otherwise uses the ignored, repo-local `.ci-cache/huggingface` directory. That
|
|
154
|
+
path is outside the preload's disposable test `HOME`, so a second local run
|
|
155
|
+
reuses the model without exposing the developer's normal AKM cache. Gated CI
|
|
156
|
+
sets the same path and restores it from a model/source-identified Actions
|
|
157
|
+
cache. Candidate tags and manual runs are restore-only; only the scheduled
|
|
158
|
+
default-branch run may save a cache entry.
|
|
159
|
+
|
|
160
|
+
The same gate runs real semantic index/search round-trips against the declared
|
|
161
|
+
external dependency. Package acceptance separately verifies the ordinary npm
|
|
162
|
+
package surface; there is no installed-consumer compatibility architecture or
|
|
163
|
+
copied semantic runtime to audit.
|
|
164
|
+
|
|
165
|
+
### What to test explicitly
|
|
166
|
+
|
|
167
|
+
- config stays `off` only when the user disables semantic search intentionally
|
|
168
|
+
- config stays `auto` when preparation is skipped intentionally
|
|
169
|
+
- config stays `auto` when preparation fails but runtime status becomes `blocked`
|
|
170
|
+
- runtime status becomes `pending`, `ready-js`, or `blocked` as appropriate
|
|
171
|
+
- index and info output report readiness state instead of only config intent
|
|
172
|
+
|
|
173
|
+
### 3. Docker deployment validation
|
|
174
|
+
|
|
175
|
+
Run the Docker matrix when changing install, packaging, startup, runtime
|
|
176
|
+
dependencies, or platform behavior:
|
|
177
|
+
|
|
178
|
+
```sh
|
|
179
|
+
AKM_DOCKER_TESTS=1 bun test tests/integration/docker-install.test.ts
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Or run the shell orchestrator directly:
|
|
183
|
+
|
|
184
|
+
```sh
|
|
185
|
+
./tests/docker/run-docker-tests.sh
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
This validates two deployment methods across four Linux families:
|
|
189
|
+
|
|
190
|
+
- bun-based install: Ubuntu, Debian, Alpine, Fedora
|
|
191
|
+
- compiled binary install: Ubuntu, Debian, Fedora
|
|
192
|
+
|
|
193
|
+
Binary validation currently excludes Alpine. The compiled Linux binary used in
|
|
194
|
+
this repo's Docker tests is not packaged for Alpine/musl compatibility, so the
|
|
195
|
+
binary deployment gate focuses on the glibc-based targets we currently support.
|
|
196
|
+
|
|
197
|
+
The Docker smoke test in `tests/docker/smoke-test.sh` verifies:
|
|
198
|
+
|
|
199
|
+
- `akm --help`
|
|
200
|
+
- `akm bundle create`
|
|
201
|
+
- bundle directory creation
|
|
202
|
+
- `akm index`
|
|
203
|
+
- `akm search`
|
|
204
|
+
- `akm show`
|
|
205
|
+
- `akm info`
|
|
206
|
+
- `akm bundle list`
|
|
207
|
+
- incremental re-index after adding a new asset
|
|
208
|
+
|
|
209
|
+
### 4. Benchmark (agent utility)
|
|
210
|
+
|
|
211
|
+
The LLM-provider-driven, multi-seed agent-utility benchmark (`akm-bench`) now
|
|
212
|
+
lives in the standalone repo **[itlackey/akm-bench](https://github.com/itlackey/akm-bench)**.
|
|
213
|
+
Run it from there after any change to `src/output/`, `src/commands/read/show.ts`,
|
|
214
|
+
APPLY directives, or other content that affects what agents see.
|
|
215
|
+
|
|
216
|
+
For curate/search ranking quality, run the retrieval eval of
|
|
217
|
+
**[itlackey/akm-eval](https://github.com/itlackey/akm-eval)**
|
|
218
|
+
(`evals/retrieval/run --corpus public`, with `AKM_BIN` naming the build under
|
|
219
|
+
test). It scores `akm search` and `akm curate` against graded judgments and
|
|
220
|
+
calls no model service. The in-repo curate benchmark that used to do this,
|
|
221
|
+
`akm-eval-curate-bench`, left with the rest of `scripts/akm-eval/`; see
|
|
222
|
+
`docs/maintainers/eval.md`.
|
|
223
|
+
|
|
224
|
+
## Recommended Workflow
|
|
225
|
+
|
|
226
|
+
### Normal change
|
|
227
|
+
|
|
228
|
+
Use this for most code changes:
|
|
229
|
+
|
|
230
|
+
```sh
|
|
231
|
+
bun run test:unit
|
|
232
|
+
bun run test:integration
|
|
233
|
+
bunx biome check --write src/ tests/
|
|
234
|
+
bunx tsc --noEmit
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
### Install, packaging, or release-related change
|
|
238
|
+
|
|
239
|
+
Use this when touching `src/cli.ts`, `src/commands/sources/self-update.ts`, install flows,
|
|
240
|
+
source management, or Docker assets:
|
|
241
|
+
|
|
242
|
+
```sh
|
|
243
|
+
bun run test:unit
|
|
244
|
+
bun test tests/integration/self-update.test.ts tests/integration/setup-run.test.ts tests/integration/install-script.test.ts
|
|
245
|
+
./tests/docker/run-docker-tests.sh
|
|
246
|
+
bunx biome check --write src/ tests/
|
|
247
|
+
bunx tsc --noEmit
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### Release gate
|
|
251
|
+
|
|
252
|
+
Use this before publishing a release:
|
|
253
|
+
|
|
254
|
+
```sh
|
|
255
|
+
bun run release:check
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
If Docker is available, prefer `./tests/docker/run-docker-tests.sh` over a
|
|
259
|
+
single-variant container run so both bun and binary installs are covered.
|
|
260
|
+
|
|
261
|
+
For a local release gate without Docker, use:
|
|
262
|
+
|
|
263
|
+
```sh
|
|
264
|
+
./tests/release-check.sh --skip-docker
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
That script now runs a dedicated install/setup regression suite before the full
|
|
268
|
+
test run so first-run, installer, and wizard failures surface early.
|
|
269
|
+
|
|
270
|
+
The local script is only one half of release validation. Follow the
|
|
271
|
+
[maintainer release checklist](../../maintainers/release-checklist.md) to
|
|
272
|
+
run **Gated CI** from a `gated-ci/candidate-*` tag targeting the exact candidate
|
|
273
|
+
commit, or manually dispatch it with the full candidate
|
|
274
|
+
SHA after the workflow reaches the default branch. Its real-embedding, Docker,
|
|
275
|
+
and Linux/macOS/Windows scheduler jobs must all succeed, and the release PR
|
|
276
|
+
must link the resulting Actions run. The weekly scheduled run detects
|
|
277
|
+
default-branch drift; it cannot attest a different release-candidate commit.
|
|
278
|
+
|
|
279
|
+
## Manual QA Authority
|
|
280
|
+
|
|
281
|
+
Use [AKM Manual Testing Runbook](./manual-testing-checklist.md) for every manual
|
|
282
|
+
flow. Its full sandbox is mandatory; the smaller historical XDG-only setup is
|
|
283
|
+
unsafe because `AKM_CONFIG_DIR` can bypass it. The runbook also owns expected
|
|
284
|
+
exits/channels, fixtures, release evidence, platform gates, and cleanup.
|
|
285
|
+
|
|
286
|
+
## Docker Deployment Validation
|
|
287
|
+
|
|
288
|
+
### Automated matrix
|
|
289
|
+
|
|
290
|
+
The repo already contains Dockerfiles for:
|
|
291
|
+
|
|
292
|
+
- `tests/docker/Dockerfile.ubuntu-bun`
|
|
293
|
+
- `tests/docker/Dockerfile.debian-bun`
|
|
294
|
+
- `tests/docker/Dockerfile.alpine-bun`
|
|
295
|
+
- `tests/docker/Dockerfile.fedora-bun`
|
|
296
|
+
- `tests/docker/Dockerfile.ubuntu-binary`
|
|
297
|
+
- `tests/docker/Dockerfile.debian-binary`
|
|
298
|
+
- `tests/docker/Dockerfile.fedora-binary`
|
|
299
|
+
|
|
300
|
+
`Dockerfile.alpine-binary` does not exist and is deliberately not part of this
|
|
301
|
+
matrix: binary validation excludes Alpine (see above) because the compiled
|
|
302
|
+
binary targets glibc and Alpine is musl-based.
|
|
303
|
+
|
|
304
|
+
Run one variant if you need a focused repro:
|
|
305
|
+
|
|
306
|
+
```sh
|
|
307
|
+
./tests/docker/run-docker-tests.sh ubuntu-binary
|
|
308
|
+
./tests/docker/run-docker-tests.sh --bun-only
|
|
309
|
+
./tests/docker/run-docker-tests.sh --binary-only
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### What the Docker matrix proves
|
|
313
|
+
|
|
314
|
+
- the CLI starts in minimal Linux images
|
|
315
|
+
- runtime dependencies are sufficient for `bundle create`, `index`, `search`, and `show`
|
|
316
|
+
- bun-linked installs work after building from source
|
|
317
|
+
- compiled Linux binaries run correctly when copied into the image
|
|
318
|
+
- the CLI can create a fresh bundle, build an index, and discover new assets
|
|
319
|
+
|
|
320
|
+
Treat this matrix as a release gate for shell-level regressions too. The Docker
|
|
321
|
+
smoke path exercises real entrypoint scripts and container command execution,
|
|
322
|
+
which can catch failures that unit and subprocess tests miss.
|
|
323
|
+
|
|
324
|
+
### What it does not prove by itself
|
|
325
|
+
|
|
326
|
+
- that the published release artifact matches the local compiled binary
|
|
327
|
+
- that `install.sh` works against a real GitHub release
|
|
328
|
+
- that self-upgrade can replace the running binary in-place
|
|
329
|
+
|
|
330
|
+
Those should be validated in disposable containers as described next.
|
|
331
|
+
|
|
332
|
+
## Published Artifact Acceptance
|
|
333
|
+
|
|
334
|
+
Published binary, installer, checksum, native-platform, and self-upgrade
|
|
335
|
+
procedures are release-facing manual gates. Run sections 21-22 of the
|
|
336
|
+
[manual runbook](./manual-testing-checklist.md); do not validate release bytes
|
|
337
|
+
with an installer fetched from raw `main`.
|
|
338
|
+
|
|
339
|
+
## Upgrade Regression Coverage
|
|
340
|
+
|
|
341
|
+
Managed-source updates and CLI self-upgrade are separate implementations.
|
|
342
|
+
Provider/registry suites cover source add/update/remove/cache behavior;
|
|
343
|
+
`tests/integration/self-update.test.ts` covers install-method detection,
|
|
344
|
+
orchestration, checksum, and failure paths. Real managed-source and self-upgrade
|
|
345
|
+
acceptance is manual and lives in section 21 of the
|
|
346
|
+
[manual runbook](./manual-testing-checklist.md).
|
|
347
|
+
|
|
348
|
+
### Upgrade rehearsal gate
|
|
349
|
+
|
|
350
|
+
`tests/integration/upgrade-rehearsal/` installs the PREVIOUS published stable
|
|
351
|
+
`akm-cli` release as a real global npm package (real `npm pack` / `npm
|
|
352
|
+
install --global` into a throwaway prefix — see `scripts/package-install.ts`)
|
|
353
|
+
under the label `live`, drives it to build a realistic home — a filesystem
|
|
354
|
+
bundle, a git bundle (with an in-bundle symlink at its root), a website
|
|
355
|
+
bundle, an npm bundle, three scheduled tasks (two granted, one left
|
|
356
|
+
ungranted) plus a manual task, and a synced native (fake) crontab — then
|
|
357
|
+
installs the CANDIDATE build OVER `live`, in the SAME prefix: an in-place
|
|
358
|
+
swap, the same thing a real `npm i -g akm-cli@…`/`bun add -g` upgrade does,
|
|
359
|
+
not a side-by-side install. It then runs the CANDIDATE against that home
|
|
360
|
+
(`migrate status`/`apply`, `bundle list` with every bundle confirmed enabled,
|
|
361
|
+
`search`/`show`, `task sync` dry-run and real — plain, no `--rebind`, as an
|
|
362
|
+
upgrading user actually runs it — executing the generated cron command and
|
|
363
|
+
confirming it ran the candidate, `task run`, `health`, `improve --dry-run`), and
|
|
364
|
+
finally installs a separate untouched copy of the PREVIOUS release and runs
|
|
365
|
+
it back against the candidate-written home to prove read-back still works.
|
|
366
|
+
It exists because no other suite drives a real prior release against a real
|
|
367
|
+
candidate build: the symlink-abort regression fixed in 0.9.17-alpha.3
|
|
368
|
+
(`d76af0a7b`) went undetected by the full unit/integration suite,
|
|
369
|
+
`tests/release-check.sh`, and the Docker matrix, because no fixture combined
|
|
370
|
+
a git bundle with an in-bundle symlink, a website bundle, an npm bundle, an
|
|
371
|
+
ungranted task, and a real crontab row in one home. Plain `task sync` proves
|
|
372
|
+
clean specifically because the candidate lands inside the SAME prefix the
|
|
373
|
+
previous release's scheduler rows already point at — no launcher path moves,
|
|
374
|
+
so nothing needs rebinding; a side-by-side install (a separate prefix) would
|
|
375
|
+
need `--rebind` instead, which is not what an in-place package-manager
|
|
376
|
+
upgrade does. `tests/integration/previous-release-corpus.test.ts` covers
|
|
377
|
+
persisted-data shapes read in isolation; this gate covers the whole CLI
|
|
378
|
+
surface driven end to end across two real installed releases.
|
|
379
|
+
|
|
380
|
+
Run it locally with:
|
|
381
|
+
|
|
382
|
+
```sh
|
|
383
|
+
bun run build
|
|
384
|
+
AKM_UPGRADE_REHEARSAL=1 TMPDIR=/tmp bun test --timeout=900000 tests/integration/upgrade-rehearsal/
|
|
385
|
+
```
|
|
386
|
+
|
|
387
|
+
Unset (the default), the suite logs one line and skips — it never fails
|
|
388
|
+
"inconclusively" (#795): every missing capability (no `npm` on `PATH`, no
|
|
389
|
+
network reachable to resolve/fetch the previous release, no candidate build)
|
|
390
|
+
throws naming the fix instead. Env overrides:
|
|
391
|
+
|
|
392
|
+
- `AKM_UPGRADE_FROM=<version>` — pin the previous release instead of
|
|
393
|
+
resolving the highest published stable version below the candidate's
|
|
394
|
+
`package.json` version.
|
|
395
|
+
- `AKM_CANDIDATE_TARBALL=<path>` — use an already-packed candidate tarball
|
|
396
|
+
(`tests/release-check.sh` passes `$PACKAGE_CANDIDATE`) instead of running
|
|
397
|
+
`npm pack` on the working tree (which requires `dist/cli.js` — run
|
|
398
|
+
`bun run build` first).
|
|
399
|
+
|
|
400
|
+
Fetched previous-release tarballs are cached under
|
|
401
|
+
`${TMPDIR:-/tmp}/akm-upgrade-rehearsal/previous-release/<version>/` so repeat
|
|
402
|
+
runs do not re-hit the network. It is wired into CI as the `upgrade-rehearsal`
|
|
403
|
+
job (`.github/workflows/ci.yml`) and into `tests/release-check.sh` right
|
|
404
|
+
after packing the release candidate.
|
|
405
|
+
|
|
406
|
+
## Coverage Gap Guide
|
|
407
|
+
|
|
408
|
+
This repo now has broad coverage across the major CLI, indexing, registry, and
|
|
409
|
+
semantic-search paths. Use this file as a current gap guide, not a greenfield
|
|
410
|
+
test plan.
|
|
411
|
+
|
|
412
|
+
### Areas With Strong Existing Coverage
|
|
413
|
+
|
|
414
|
+
- database and scoring (`tests/integration/db.test.ts`, `tests/integration/db-scoring.test.ts`, `tests/integration/fts-field-weighting.test.ts`)
|
|
415
|
+
- search/show CLI surfaces (`tests/integration/commands/search-cli-envelope.test.ts`, `tests/integration/commands/show.test.ts`, and the other `search-*`/`show-*` suites under `tests/integration/`)
|
|
416
|
+
- registry install/search/update/list flows
|
|
417
|
+
- workflow, vault, and wiki behavior
|
|
418
|
+
- semantic status, vector search, and embedding config behavior
|
|
419
|
+
- CLI error handling and output shaping
|
|
420
|
+
- Docker install validation
|
|
421
|
+
|
|
422
|
+
### Highest-Value Remaining Gaps
|
|
423
|
+
|
|
424
|
+
1. corrupt or version-mismatched DB fallback behavior during search
|
|
425
|
+
2. local model download and ONNX startup failures
|
|
426
|
+
3. partial embedding-generation failures during indexing
|
|
427
|
+
4. concurrent search/embedder behavior under load
|
|
428
|
+
5. semantic readiness reporting parity between `setup`, `search`, and `info`
|
|
429
|
+
6. broader platform CI for Alpine/musl, ARM, and Windows edge cases
|
|
430
|
+
|
|
431
|
+
### When Adding Tests
|
|
432
|
+
|
|
433
|
+
- prefer focused `bun:test` files under `tests/`
|
|
434
|
+
- use isolated temp config/cache/stash dirs
|
|
435
|
+
- cover the user-visible CLI behavior when the risk is output shaping or command routing
|
|
436
|
+
- cover internal units directly when the risk is scoring, metadata extraction, or persistence
|
|
437
|
+
|
|
438
|
+
### Useful Existing Suites To Extend
|
|
439
|
+
|
|
440
|
+
- `tests/integration/commands/search-cli-envelope.test.ts`
|
|
441
|
+
- `tests/integration/commands/show.test.ts`
|
|
442
|
+
- `tests/integration/vector-search.test.ts`
|
|
443
|
+
- `tests/integration/semantic-status.test.ts`
|
|
444
|
+
- `tests/setup-wizard.test.ts`, `tests/setup-scheduled-tasks.test.ts`
|
|
445
|
+
- `tests/integration/info-command.test.ts`
|
|
446
|
+
- `tests/integration/docker-install.test.ts`
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
# Architecture: The Workflow Engine
|
|
2
|
+
|
|
3
|
+
A workflow compiles to a frozen plan, persists run and unit state, dispatches
|
|
4
|
+
its work, verifies declared gates, and resumes without replaying completed
|
|
5
|
+
units. This page is the architecture-level reference for that engine — how a
|
|
6
|
+
run's plan is frozen and stored, how dispatch and resume actually work, how
|
|
7
|
+
one engine owns a run, and how isolated file-mutating units execute. For the
|
|
8
|
+
exact frontmatter/body syntax that produces the plan, see
|
|
9
|
+
[Workflow Schema](../reference/workflow-schema.md). For the day-to-day
|
|
10
|
+
commands that drive a run, see [Running Workflows](../guides/run-workflows.md).
|
|
11
|
+
|
|
12
|
+
> **`akm workflow run` is Experimental (see `STABILITY.md`), ungated, and the only
|
|
13
|
+
> execution surface.** It is the canonical start/resume/execute command; there is
|
|
14
|
+
> no separate external-driver protocol.
|
|
15
|
+
|
|
16
|
+
## Frozen plans
|
|
17
|
+
|
|
18
|
+
The first `akm workflow run <ref>` compiles either peer source format
|
|
19
|
+
(Markdown or GitHub-Actions-style YAML) straight to the one plan type and
|
|
20
|
+
stores it as durable plan **`irVersion` 6** on the run row (`plan_json` +
|
|
21
|
+
`plan_hash`); a new start never emits an older version. `plan_ir_version` and
|
|
22
|
+
`plan_hash` are recorded provenance, not gates: a stored plan is decoded as it
|
|
23
|
+
is — irVersion 4 and 5 plans included — and one frozen by an older or newer
|
|
24
|
+
akm that still decodes simply runs (with one warning). A newer akm's plan that
|
|
25
|
+
does not decode is refused with a message naming "Upgrade akm".
|
|
26
|
+
|
|
27
|
+
The durable plan records `sourceHash`, the sha256 of the workflow source file
|
|
28
|
+
at freeze. It is used only for the resume warning below, never to refuse a
|
|
29
|
+
run.
|
|
30
|
+
|
|
31
|
+
Dispatch-significant material is immutable. The resolved request is frozen,
|
|
32
|
+
the resolved target is frozen, and runner selection is frozen.
|
|
33
|
+
Working directory (`cwd`) identity is frozen.
|
|
34
|
+
Git identity and its commit OID are frozen. The executable a unit runs is
|
|
35
|
+
resolved at dispatch, so upgrading a CLI (say, `claude`) never strands a run.
|
|
36
|
+
Exact models, inference, tools and authorization,
|
|
37
|
+
execution limits, parameter snapshots, command/script bytes, and verifier
|
|
38
|
+
selection therefore cannot drift under an in-flight run.
|
|
39
|
+
|
|
40
|
+
Workflow environment asset values are the narrow live-value exception within
|
|
41
|
+
authored workflow inputs.
|
|
42
|
+
The environment owner key set and secret-token topology are frozen.
|
|
43
|
+
Literal values remain frozen. Pass-through bindings
|
|
44
|
+
materialize at dispatch from the current process, and env/secret references
|
|
45
|
+
materialize their current values only after owner/topology checks. Durable
|
|
46
|
+
plans never store secret values or enable whole-process `inheritEnv`.
|
|
47
|
+
|
|
48
|
+
**A run executes the plan compiled at creation; edits to source need a new
|
|
49
|
+
run.** Resuming a run re-reads its workflow source only to warn, once, when
|
|
50
|
+
the source changed since the freeze — the run continues on the frozen plan.
|
|
51
|
+
Orchestration decisions are pure functions of the frozen plan, run params,
|
|
52
|
+
and journaled results.
|
|
53
|
+
|
|
54
|
+
## Child workflows
|
|
55
|
+
|
|
56
|
+
A step that composes another workflow — directly (`uses: workflows/<ref>`)
|
|
57
|
+
or through a task whose own target is a workflow (`uses: tasks/<ref>`) —
|
|
58
|
+
freezes to a `child-workflow` frozen target. Unlike the `command`/`shell`/
|
|
59
|
+
`script` targets, a `child-workflow` target carries the child's **complete
|
|
60
|
+
frozen plan, embedded**: compiling the parent recursively compiles,
|
|
61
|
+
validates, and freezes each child in full — depth-first, all of it — before
|
|
62
|
+
the parent run is ever published. Nothing about a child is re-read at
|
|
63
|
+
dispatch time; the embedded plan is authoritative. See
|
|
64
|
+
[Workflow Schema: Child workflows](../reference/workflow-schema.md#child-workflows)
|
|
65
|
+
for the authoring-side view, including the three composition bounds (depth,
|
|
66
|
+
cycle, aggregate embedded bytes) enforced at freeze.
|
|
67
|
+
|
|
68
|
+
**Decoding.** An embedded child plan is decoded by the same structural
|
|
69
|
+
decoder as its parent, recursively. Its `planHash` and the target's
|
|
70
|
+
`contentHash` are recorded provenance, carried as data and never re-verified
|
|
71
|
+
against the bytes.
|
|
72
|
+
|
|
73
|
+
**The dispatch seam.** Dispatching a step whose target is
|
|
74
|
+
`kind: "child-workflow"` is the one branch point in
|
|
75
|
+
`dispatchJournaledAttempt` (`src/workflows/exec/native-executor.ts`) that
|
|
76
|
+
does not call the ordinary unit dispatcher: it calls
|
|
77
|
+
`driveChildWorkflowUnit` instead, with everything the composing unit already
|
|
78
|
+
resolved — the frozen target, the parent's dispatch context, the child's
|
|
79
|
+
resolved params, and the unit input hash. The branch sits **inside** the
|
|
80
|
+
existing retry loop, after the parent unit's attempt row is already claimed
|
|
81
|
+
`running` (so a crash between claiming that row and publishing the child
|
|
82
|
+
leaves a recoverable `running` parent unit and no orphaned child) and
|
|
83
|
+
**before** the ordinary post-dispatch journaling (redaction, attempt
|
|
84
|
+
finishing), which runs unchanged either way — a
|
|
85
|
+
child-workflow unit is journaled exactly like any other.
|
|
86
|
+
|
|
87
|
+
**The drive contract.** `driveChildWorkflowUnit` validates and resolves the
|
|
88
|
+
child's params through the same input-binding
|
|
89
|
+
resolution every frozen target uses, computes the child's identity key from
|
|
90
|
+
`{parentRunId, parentUnitId, unitInputHash}`, and publishes the child run —
|
|
91
|
+
idempotently: the same three inputs always resolve to the same child row,
|
|
92
|
+
so a retried or resumed composing step re-drives the run it already started
|
|
93
|
+
rather than starting a new one, and only a change to the composing step's
|
|
94
|
+
own inputs (params, an upstream step output it reads, or gate feedback from
|
|
95
|
+
a rejected verification loop) produces a different child. A child found
|
|
96
|
+
already `blocked` or `failed` is not re-driven — driving happens once per
|
|
97
|
+
call, and a terminal-but-unhealthy child surfaces through the status mapping
|
|
98
|
+
below instead. The child's final status maps onto the composing unit, and
|
|
99
|
+
from there onto the parent step and run, exactly as described in [Workflow
|
|
100
|
+
Schema: Child execution](../reference/workflow-schema.md#child-execution).
|
|
101
|
+
|
|
102
|
+
**Why `runWorkflowSteps` is reused, not a second executor.** The child drive
|
|
103
|
+
calls the exact same exported entry point `akm workflow run` calls —
|
|
104
|
+
`runWorkflowSteps(options)`, pointed at the child's run id as `target` —
|
|
105
|
+
with no special-casing for "this target is a child": resolving a run id,
|
|
106
|
+
decoding the stored plan, taking that run's own lock, and walking its spine
|
|
107
|
+
through `completeWorkflowStep` are identical to the top-level path. That
|
|
108
|
+
reuse is what makes child run locks arbitrate two-parent contention with no
|
|
109
|
+
new mechanism, and what makes a resumed parent skip a completed child step
|
|
110
|
+
with zero dispatcher calls. The child drive passes a no-op
|
|
111
|
+
`disposeDispatchResources` (the parent's `finally` remains the sole owner of
|
|
112
|
+
the process-lifecycle drain for the whole process) and no `maxSteps` or
|
|
113
|
+
`maxRetries` (the parent's own budgets count only its own spine steps). The
|
|
114
|
+
lower-level `driveRun` that `runWorkflowSteps` wraps stays module-private —
|
|
115
|
+
reaching for it directly, instead of the public entry point, would be
|
|
116
|
+
exactly the second executor this design avoids.
|
|
117
|
+
|
|
118
|
+
**Why `hashVersion` is 7, and why child composition did not move it.** The
|
|
119
|
+
version prefix mixed into a unit's input hash is 7
|
|
120
|
+
(`src/workflows/exec/step-work.ts`); 0.9.2 bumped it — a single, durable
|
|
121
|
+
5 → 7 step, since every released tag on the line carries 5 — when
|
|
122
|
+
`taskInputs`, the resolved values of a composed task's reference-kind
|
|
123
|
+
`inputBindings`, joined the preimage (see [ADR
|
|
124
|
+
0002](decisions/0002-unit-reuse-and-input-hash-scope.md)). Child composition
|
|
125
|
+
itself contributed nothing to that bump: the parent unit's input-hash
|
|
126
|
+
preimage already covers everything the child drive depends on — the frozen
|
|
127
|
+
target carries the child's ref, plan hash, content hash, binding mode, and
|
|
128
|
+
its entire embedded plan, so any change anywhere in the child changes the
|
|
129
|
+
parent unit's own input hash transitively. The child run id (minted at
|
|
130
|
+
dispatch) and its result (the child's last step output) are unit *outputs*, not inputs, so neither
|
|
131
|
+
belongs in the preimage — adding either would be a hashing-boundary
|
|
132
|
+
violation, not a fix.
|
|
133
|
+
|
|
134
|
+
## Resume skips completed units
|
|
135
|
+
|
|
136
|
+
Resume never re-reads config or the asset index, and reads the workflow
|
|
137
|
+
source only for the drift warning above. It consumes the frozen plan plus
|
|
138
|
+
the journaled attempts and results. A stored plan that this akm cannot
|
|
139
|
+
decode is not an error to fix in place: `akm workflow run` marks such a run
|
|
140
|
+
abandoned (status `failed`) and says to start a new run with
|
|
141
|
+
`akm workflow run <ref>`; `akm workflow status`, `list`, and `abandon` never
|
|
142
|
+
read the plan at all. A plan frozen by a newer akm that this one cannot
|
|
143
|
+
decode is left untouched, and the message names upgrading akm.
|
|
144
|
+
|
|
145
|
+
Every dispatched unit is journaled under a content-derived identity — the
|
|
146
|
+
node id plus a hash of its item for a map unit (`<node>:solo` otherwise) —
|
|
147
|
+
together with an input hash over everything the unit was asked to do (its
|
|
148
|
+
frozen instructions and target, declared `inputs:` artifacts, the params
|
|
149
|
+
snapshot, gate feedback). On
|
|
150
|
+
re-run, a unit whose journal row is `completed` is **reused**, never
|
|
151
|
+
re-dispatched; a failed or missing unit is dispatched live. The recorded
|
|
152
|
+
input hash is informational: a completed unit stays completed even when the
|
|
153
|
+
params row or an upstream artifact changed since — a fresh run is what
|
|
154
|
+
recomputes it.
|
|
155
|
+
|
|
156
|
+
## Durable attempts and at-least-once dispatch
|
|
157
|
+
|
|
158
|
+
Workflow dispatch is at-least-once. Every unit has a stable content-derived
|
|
159
|
+
unit id and an append-only sequence of attempts.
|
|
160
|
+
A crash reclaim reuses the same stable dispatchId for the interrupted attempt.
|
|
161
|
+
An explicit retry gets a new dispatchId under one stable unit id and increments the attempt number.
|
|
162
|
+
|
|
163
|
+
One driver per run (below) keeps a second engine off a run, and a finished
|
|
164
|
+
attempt accepts no second terminal write, but neither can prove whether an
|
|
165
|
+
external process completed immediately before a crash. An ambiguous crash
|
|
166
|
+
outcome may re-run and can produce a duplicate side effect. Workflow actions
|
|
167
|
+
should be idempotent or use the stable dispatch identity as their own
|
|
168
|
+
deduplication key.
|
|
169
|
+
|
|
170
|
+
## One engine drives a run (the run lock)
|
|
171
|
+
|
|
172
|
+
`akm workflow run` takes the run's **lock file** before reading the plan or
|
|
173
|
+
dispatching anything: one `O_EXCL` file per run id under the data directory
|
|
174
|
+
(`workflow-run-locks/<run id>.lock`, next to `state.db`), recording the
|
|
175
|
+
holder's pid, released when the invocation exits. A second `workflow run`
|
|
176
|
+
against a run another live process holds refuses up front with
|
|
177
|
+
`RUN_LEASE_HELD` (exit 75), naming the holder pid. A lock whose holder pid is
|
|
178
|
+
dead is reclaimed at once, so a crashed engine never wedges a run; nothing
|
|
179
|
+
expires by age and nothing renews. `workflow status` and `list` never take
|
|
180
|
+
the lock.
|
|
181
|
+
|
|
182
|
+
## Concurrency limits
|
|
183
|
+
|
|
184
|
+
Native fan-out (`akm workflow run`) uses the minimum of four limits: the
|
|
185
|
+
map's declared `concurrency`, the run's frozen `workflow.maxConcurrency`, the
|
|
186
|
+
selected frozen LLM engine's `concurrency` (including an SDK engine's
|
|
187
|
+
fallback LLM), and the current host's CPU-derived safety limit. Reapplying
|
|
188
|
+
host safety keeps a run safe when it resumes on a smaller machine.
|
|
189
|
+
|
|
190
|
+
- **Unset (default):** the CPU-derived value `min(16, max(1, cores − 2))` — a
|
|
191
|
+
conservative default that leaves headroom on the host and matches the
|
|
192
|
+
original Claude-Code cap.
|
|
193
|
+
- **Set:** an explicit positive integer, clamped when frozen to `[1, 64]`
|
|
194
|
+
(values above 64 are clamped down, never rejected, so one config shared
|
|
195
|
+
across machines with different core counts never hard-fails).
|
|
196
|
+
|
|
197
|
+
```console
|
|
198
|
+
$ akm config set workflow.maxConcurrency 8 # raise the frozen workflow limit
|
|
199
|
+
$ akm config get workflow.maxConcurrency
|
|
200
|
+
8
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
A workflow that fans out is authorizing **N parallel agents**, not one — see
|
|
204
|
+
[Running Workflows: workflow sources are executed code](../guides/run-workflows.md#security-workflow-sources-are-executed-code)
|
|
205
|
+
for what that means for trust.
|
|
206
|
+
|
|
207
|
+
## Run scope and persistence
|
|
208
|
+
|
|
209
|
+
Run state (`plan_json`, `plan_hash`, step statuses, and the unit journal)
|
|
210
|
+
persists in the project's `state.db`; the per-run lock file sits beside it. Run state is scoped to
|
|
211
|
+
the current project directory — the nearest `.akm/config.json`, git root,
|
|
212
|
+
bundle root, or current directory — so the same workflow can run
|
|
213
|
+
independently in separate projects, and `akm workflow list`/`status` without
|
|
214
|
+
an explicit run id only ever see runs in that scope.
|
|
215
|
+
|
|
216
|
+
## See also
|
|
217
|
+
|
|
218
|
+
- [Workflow Schema](../reference/workflow-schema.md) — exact frontmatter,
|
|
219
|
+
refs, gates, and outputs syntax
|
|
220
|
+
- [Running Workflows](../guides/run-workflows.md) — start, inspect, resume,
|
|
221
|
+
and abandon a run
|
|
222
|
+
- [Author's Guide: Writing Workflows](../guides/author-workflows.md) — writing
|
|
223
|
+
and testing a workflow definition
|