akm-cli 0.10.261012-beta → 0.10.261014-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 +710 -3
- package/README.md +15 -0
- package/SECURITY.md +11 -10
- package/STABILITY.md +47 -51
- package/dist/assets/hints/cli-hints-full.md +21 -19
- package/dist/assets/hints/cli-hints-short.md +3 -4
- package/dist/assets/opencode/akm-plugin.js +177 -0
- package/dist/assets/stash-skeleton/README.md +1 -1
- package/dist/assets/tasks/core/improve.yml +1 -1
- package/dist/assets/tasks/improve/akm-improve-consolidate.yml +1 -1
- package/dist/assets/ui/config.js +27 -10
- package/dist/assets/workflows/workflow-template.md +2 -2
- package/dist/cli/clack.js +3 -1
- package/dist/cli/selection.js +33 -0
- package/dist/cli/shared.js +14 -1
- package/dist/cli/unknown-flags.js +6 -37
- package/dist/cli.js +69 -48
- package/dist/commands/agent/agent-dispatch.js +17 -25
- package/dist/commands/agent/contribute-cli.js +9 -8
- package/dist/commands/command/command-cli.js +4 -8
- package/dist/commands/command/command-execution.js +25 -39
- package/dist/commands/command/execution-source-loader.js +10 -14
- package/dist/commands/completions.js +1 -1
- package/dist/commands/config-cli.js +14 -5
- package/dist/commands/env/child-env.js +12 -14
- package/dist/commands/env/env-binding.js +47 -58
- package/dist/commands/env/env-cli.js +22 -24
- package/dist/commands/env/env.js +10 -58
- package/dist/commands/env/secret-cli.js +11 -29
- package/dist/commands/env/secret.js +3 -10
- package/dist/commands/health/checks.js +10 -849
- package/dist/commands/health/connections-and-harnesses-check.js +109 -0
- package/dist/commands/health/egress.js +3 -3
- package/dist/commands/health/html-report.js +9 -10
- package/dist/commands/health/plugin-staleness.js +18 -11
- package/dist/commands/health/report-view-model.js +16 -12
- package/dist/commands/health/scheduler-binary.js +1 -1
- package/dist/commands/health/semantic-search-check.js +85 -0
- package/dist/commands/health/type-directory-check.js +0 -3
- package/dist/commands/health.js +30 -42
- package/dist/commands/improve/consolidate/pair-pass.js +10 -25
- package/dist/commands/improve/consolidate.js +10 -15
- package/dist/commands/improve/distill.js +5 -17
- package/dist/commands/improve/eligibility.js +1 -3
- package/dist/commands/improve/execution.js +37 -40
- package/dist/commands/improve/extract-cli.js +6 -11
- package/dist/commands/improve/extract-prompt.js +2 -2
- package/dist/commands/improve/extract.js +67 -97
- package/dist/commands/improve/improve-cli.js +22 -128
- package/dist/commands/improve/improve-report.js +1 -1
- package/dist/commands/improve/improve-strategies.js +25 -108
- package/dist/commands/improve/improve.js +10 -14
- package/dist/commands/improve/loop-stages.js +3 -0
- package/dist/commands/improve/memory/memory-improve.js +1 -1
- package/dist/commands/improve/preparation.js +8 -13
- package/dist/commands/improve/reflect.js +203 -332
- package/dist/commands/improve/retrieval-scope.js +1 -1
- package/dist/commands/improve/session-asset.js +3 -2
- package/dist/commands/improve/stage.js +87 -115
- package/dist/commands/lint/base-linter.js +3 -3
- package/dist/commands/lint/env-key-rules.js +7 -6
- package/dist/commands/lint/index.js +3 -3
- package/dist/commands/models-cli.js +103 -63
- package/dist/commands/proposal/drain.js +26 -39
- package/dist/commands/proposal/proposal-cli.js +14 -18
- package/dist/commands/proposal/propose-cli.js +4 -2
- package/dist/commands/proposal/propose.js +37 -64
- package/dist/commands/proposal/repository.js +17 -17
- package/dist/commands/proposal/validators/proposal-validators.js +3 -6
- package/dist/commands/read/curate.js +10 -6
- package/dist/commands/read/registry-search.js +2 -48
- package/dist/commands/read/search-cli.js +1 -8
- package/dist/commands/read/search.js +5 -6
- package/dist/commands/read/show.js +6 -29
- package/dist/commands/remember.js +25 -40
- package/dist/commands/sources/add-cli.js +8 -63
- package/dist/commands/sources/bundle-cli.js +8 -9
- package/dist/commands/sources/bundle-config-ops.js +2 -2
- package/dist/commands/sources/info.js +12 -1
- package/dist/commands/sources/init.js +1 -1
- package/dist/commands/sources/installed-stashes.js +119 -63
- package/dist/commands/sources/migration-help.js +1 -1
- package/dist/commands/sources/plugin-upgrade.js +8 -15
- package/dist/commands/sources/schema-repair.js +4 -10
- package/dist/commands/sources/source-add.js +2 -2
- package/dist/commands/sources/source-clone.js +31 -7
- package/dist/commands/sources/source-manage.js +4 -4
- package/dist/commands/targets.js +175 -0
- package/dist/commands/tasks/explain.js +104 -69
- package/dist/commands/tasks/tasks-cli.js +9 -11
- package/dist/commands/tasks/tasks.js +75 -97
- package/dist/commands/ui/api.js +11 -3
- package/dist/commands/ui/redact.js +5 -31
- package/dist/commands/ui/workspace-actions.js +1 -1
- package/dist/commands/workflow/plan.js +48 -9
- package/dist/commands/workflow-cli.js +40 -45
- package/dist/core/adapter/adapters/agent-skills-adapter.js +10 -11
- package/dist/core/adapter/adapters/akm-adapter.js +36 -41
- package/dist/core/adapter/adapters/akm-lint.js +10 -12
- package/dist/core/adapter/adapters/akm-metadata.js +2 -2
- package/dist/core/adapter/adapters/akm-task-adapter.js +8 -9
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +5 -5
- package/dist/core/adapter/adapters/claude-adapter.js +1 -1
- package/dist/core/adapter/adapters/dotenv-adapter.js +7 -6
- package/dist/core/adapter/adapters/generic-files-adapter.js +5 -5
- package/dist/core/adapter/adapters/index.js +3 -4
- package/dist/core/adapter/adapters/llm-wiki-adapter.js +12 -14
- package/dist/core/adapter/adapters/okf-adapter.js +8 -10
- package/dist/core/adapter/adapters/opencode-adapter.js +1 -1
- package/dist/core/adapter/adapters/shared.js +3 -3
- package/dist/core/adapter/adapters/tool-dir-shared.js +7 -25
- package/dist/core/adapter/adapters/website-snapshot-adapter.js +3 -3
- package/dist/core/adapter/detect-adapter.js +1 -1
- package/dist/core/adapter/execution-source.js +13 -35
- package/dist/core/adapter/registry.js +1 -1
- package/dist/core/adapter/validate-context.js +2 -4
- package/dist/core/asset/asset-placement.js +1 -1
- package/dist/core/asset/asset-ref.js +3 -3
- package/dist/core/asset/resolve-ref.js +5 -0
- package/dist/core/bundle-rename.js +12 -4
- package/dist/core/closest-match.js +37 -0
- package/dist/core/common.js +37 -57
- package/dist/core/config/config-io.js +26 -18
- package/dist/core/config/config-schema.js +19 -106
- package/dist/core/config/config-sources.js +3 -3
- package/dist/core/config/config-types.js +4 -4
- package/dist/core/config/config-walker.js +50 -77
- package/dist/core/config/config.js +438 -109
- package/dist/core/config/convert-engine-references.js +114 -0
- package/dist/core/config/convert-engines-shared.js +40 -0
- package/dist/core/config/convert-engines.js +300 -0
- package/dist/core/config/convert-models-overlay.js +137 -0
- package/dist/core/config/credentials.js +304 -0
- package/dist/core/config/engine-semantics.js +3 -3
- package/dist/core/config/migrate-keys.js +222 -0
- package/dist/core/config/model-aliases.js +37 -0
- package/dist/core/config/models-file.js +34 -0
- package/dist/core/config/retired-engines.js +53 -0
- package/dist/core/config/schema/connections.js +41 -0
- package/dist/core/config/schema/embedding.js +2 -2
- package/dist/core/config/schema/harnesses.js +41 -0
- package/dist/core/config/schema/improve-processes.js +9 -28
- package/dist/core/config/schema/improve.js +36 -1
- package/dist/core/config/schema/index-config.js +18 -20
- package/dist/core/config/schema/primitives.js +42 -17
- package/dist/core/config/schema/search.js +6 -11
- package/dist/core/config/schema/sources-bundles.js +9 -9
- package/dist/core/config/schema/workflow.js +2 -6
- package/dist/core/config/unusable-entries.js +66 -0
- package/dist/core/content-safety.js +3 -6
- package/dist/core/endpoint-url.js +47 -0
- package/dist/core/env-secret-ref.js +84 -73
- package/dist/core/errors.js +10 -16
- package/dist/core/extra-params.js +3 -3
- package/dist/core/improve-result.js +8 -9
- package/dist/core/json-schema.js +1 -1
- package/dist/core/lesson-lint.js +1 -1
- package/dist/core/llm-inference.js +80 -0
- package/dist/core/parse.js +2 -2
- package/dist/core/paths.js +33 -10
- package/dist/core/recognition-util.js +8 -10
- package/dist/core/redaction.js +94 -55
- package/dist/core/ref-token.js +82 -0
- package/dist/core/secret-value.js +14 -0
- package/dist/core/state/migrations.js +17 -22
- package/dist/core/structured.js +2 -68
- package/dist/core/subprocess.js +63 -22
- package/dist/core/type-presentation.js +10 -14
- package/dist/core/write-source.js +20 -4
- package/dist/execution/input-contract.js +3 -6
- package/dist/execution/notices.js +49 -0
- package/dist/execution/resolved-request.js +24 -40
- package/dist/execution/source.js +21 -45
- package/dist/execution/target-ref.js +2 -2
- package/dist/indexer/bundle-identity-guard.js +6 -5
- package/dist/indexer/ensure-index.js +1 -1
- package/dist/indexer/index-writer-lock.js +1 -1
- package/dist/indexer/indexer.js +46 -42
- package/dist/indexer/installations.js +12 -22
- package/dist/indexer/lookup/adapter-concept-owner.js +40 -14
- package/dist/indexer/materialize-embeddings.js +20 -16
- package/dist/indexer/passes/memory-inference.js +21 -50
- package/dist/indexer/passes/metadata.js +5 -5
- package/dist/indexer/scan/doc-to-entry.js +1 -1
- package/dist/indexer/scan/drain-dir.js +9 -11
- package/dist/indexer/search/db-search.js +9 -7
- package/dist/indexer/search/search-source.js +42 -22
- package/dist/indexer/usage/usage-events.js +2 -3
- package/dist/indexer/walk/index-context.js +2 -1
- package/dist/indexer/walk/matchers.js +3 -11
- package/dist/indexer/walk/path-resolver.js +13 -68
- package/dist/indexer/walk/walker.js +32 -26
- package/dist/integrations/agent/akm-read-tools.js +81 -0
- package/dist/integrations/agent/config.js +1 -1
- package/dist/integrations/agent/detect.js +32 -36
- package/dist/integrations/agent/execution.js +130 -428
- package/dist/integrations/agent/index.js +1 -1
- package/dist/integrations/agent/profiles.js +24 -28
- package/dist/integrations/agent/prompts.js +17 -30
- package/dist/integrations/agent/request-lowering.js +67 -101
- package/dist/integrations/agent/resolution.js +332 -0
- package/dist/integrations/agent/runner-dispatch.js +156 -181
- package/dist/integrations/agent/runner.js +20 -70
- package/dist/integrations/agent/runtime-port.js +4 -0
- package/dist/integrations/agent/runtime.js +10 -0
- package/dist/integrations/agent/spawn.js +65 -190
- package/dist/integrations/harnesses/aider/index.js +19 -39
- package/dist/integrations/harnesses/amazonq/index.js +17 -32
- package/dist/integrations/harnesses/claude/index.js +59 -28
- package/dist/integrations/harnesses/claude/session-log.js +7 -5
- package/dist/integrations/harnesses/codex/index.js +19 -31
- package/dist/integrations/harnesses/copilot/index.js +17 -35
- package/dist/integrations/harnesses/gemini/index.js +18 -34
- package/dist/integrations/harnesses/harness.js +36 -0
- package/dist/integrations/harnesses/index.js +20 -51
- package/dist/integrations/harnesses/opencode/agent-builder.js +132 -100
- package/dist/integrations/harnesses/opencode/index.js +11 -33
- package/dist/integrations/harnesses/opencode/roots.js +50 -0
- package/dist/integrations/harnesses/opencode/runtime/binary.js +206 -0
- package/dist/integrations/harnesses/opencode/runtime/command.js +152 -0
- package/dist/integrations/harnesses/opencode/runtime/index.js +177 -0
- package/dist/integrations/harnesses/opencode/runtime/tar.js +107 -0
- package/dist/integrations/harnesses/opencode/session-log-v1.js +15 -7
- package/dist/integrations/harnesses/opencode/session-log-v2.js +72 -48
- package/dist/integrations/harnesses/opencode/session-log.js +58 -137
- package/dist/integrations/harnesses/opencode/version.js +34 -53
- package/dist/integrations/harnesses/openhands/index.js +13 -37
- package/dist/integrations/harnesses/pi/index.js +21 -32
- package/dist/integrations/lockfile.js +1 -1
- package/dist/integrations/session-logs/index.js +11 -31
- package/dist/llm/client.js +93 -111
- package/dist/llm/embedder.js +19 -34
- package/dist/llm/embedders/connection.js +31 -0
- package/dist/llm/embedders/local-model-files.js +56 -0
- package/dist/llm/embedders/local.js +146 -115
- package/dist/llm/embedders/remote.js +26 -23
- package/dist/llm/embedders/types.js +1 -1
- package/dist/llm/index-passes.js +33 -39
- package/dist/llm/memory-infer.js +67 -77
- package/dist/llm/model-list.js +35 -0
- package/dist/llm/rerank-client.js +8 -14
- package/dist/llm/structured-call.js +45 -99
- package/dist/llm/structured.js +60 -0
- package/dist/output/renderers.js +2 -8
- package/dist/output/shapes/helpers.js +18 -44
- package/dist/output/shapes/passthrough.js +1 -0
- package/dist/output/shapes.js +1 -7
- package/dist/output/text/command-format.js +41 -39
- package/dist/output/text/health-format.js +8 -2
- package/dist/output/text/helpers.js +1 -1
- package/dist/output/text/migrate.js +12 -0
- package/dist/output/text/models.js +3 -2
- package/dist/output/text/registry-commands.js +1 -2
- package/dist/output/text/show-directives.js +16 -28
- package/dist/output/text/show-format.js +0 -2
- package/dist/output/text/targets-table.js +70 -0
- package/dist/output/text/workflow-format.js +44 -15
- package/dist/output/text.js +1 -1
- package/dist/registry/providers/skills-sh.js +1 -28
- package/dist/registry/providers/static-index.js +1 -71
- package/dist/runtime.js +6 -2
- package/dist/scripts/akm-migrate-node.js +47095 -44905
- package/dist/scripts/akm-migrate.js +46946 -44755
- package/dist/setup/detect.js +28 -273
- package/dist/setup/endpoint.js +36 -0
- package/dist/setup/semantic-assets.js +13 -19
- package/dist/setup/setup-flags.js +77 -0
- package/dist/setup/setup-plan.js +144 -0
- package/dist/setup/setup.js +134 -358
- package/dist/setup/steps/connection-shared.js +49 -101
- package/dist/setup/steps/connection.js +121 -524
- package/dist/setup/steps/embeddings.js +151 -0
- package/dist/setup/steps/harnesses.js +118 -0
- package/dist/setup/steps/platforms.js +2 -81
- package/dist/setup/steps/tasks.js +1 -2
- package/dist/setup/steps.js +10 -0
- package/dist/setup/summary.js +67 -0
- package/dist/sources/freshness.js +16 -21
- package/dist/sources/providers/git-provider.js +2 -9
- package/dist/sources/providers/provider-utils.js +13 -5
- package/dist/sources/resolve.js +12 -16
- package/dist/sources/snapshot-fetchers/robots.js +11 -12
- package/dist/sources/snapshot-fetchers/secret-seam.js +2 -4
- package/dist/sources/snapshot-fetchers/website-ingest.js +8 -15
- package/dist/sources/snapshot-fetchers/x.js +1 -1
- package/dist/standalone/onnxruntime-library.js +52 -0
- package/dist/storage/repositories/improve-ledger-repository.js +1 -1
- package/dist/storage/repositories/improve-runs-repository.js +0 -13
- package/dist/storage/repositories/index-entries-repository.js +2 -2
- package/dist/storage/repositories/proposals-repository.js +2 -2
- package/dist/storage/repositories/task-history-repository.js +2 -2
- package/dist/storage/repositories/workflow-runs-repository.js +44 -129
- package/dist/storage/sqlite-read-snapshot.js +33 -29
- package/dist/tasks/embedded.js +1 -1
- package/dist/tasks/log-redaction.js +7 -119
- package/dist/tasks/prepare/prepare-support.js +8 -7
- package/dist/tasks/prepare/prepare.js +8 -9
- package/dist/tasks/prepare/script-capture.js +9 -25
- package/dist/tasks/run/attempt-lifecycle.js +17 -35
- package/dist/tasks/run/load-task.js +54 -27
- package/dist/tasks/run/run-command-task.js +15 -10
- package/dist/tasks/run/run-native-task.js +8 -21
- package/dist/tasks/run/run-task.js +5 -8
- package/dist/tasks/run/run-workflow-task.js +14 -21
- package/dist/tasks/run/task-history.js +9 -17
- package/dist/tasks/run/task-log.js +1 -5
- package/dist/tasks/scheduler-invocation.js +13 -18
- package/dist/tasks/scheduler-sync.js +0 -1
- package/dist/tasks/source/bounded-document.js +31 -117
- package/dist/tasks/source/parse-task-source.js +0 -1
- package/dist/tasks/source/project-v4.js +5 -3
- package/dist/tasks/source/task-input-diagnostics.js +3 -4
- package/dist/tasks/source/task-source-v4.js +48 -72
- package/dist/tasks/source-v3.js +2 -5
- package/dist/tasks/task-run-reserved-flags.js +1 -2
- package/dist/workflows/authoring/authoring.js +2 -7
- package/dist/workflows/compile.js +1 -15
- package/dist/workflows/concurrency-policy.js +4 -4
- package/dist/workflows/exec/child-workflow.js +1 -4
- package/dist/workflows/exec/dispatch-redaction.js +35 -86
- package/dist/workflows/exec/environment.js +13 -77
- package/dist/workflows/exec/exec-unit.js +14 -55
- package/dist/workflows/exec/frozen-judge.js +26 -28
- package/dist/workflows/exec/native-executor.js +126 -71
- package/dist/workflows/exec/run-workflow.js +38 -42
- package/dist/workflows/exec/step-work.js +13 -17
- package/dist/workflows/exec/unit-dispatch.js +7 -21
- package/dist/workflows/freeze/environment.js +14 -119
- package/dist/workflows/freeze/freeze.js +14 -33
- package/dist/workflows/freeze/step-values.js +6 -13
- package/dist/workflows/freeze/targets/child-workflow.js +3 -5
- package/dist/workflows/freeze/targets/command.js +9 -15
- package/dist/workflows/freeze/targets/shell.js +0 -3
- package/dist/workflows/freeze/task-bindings.js +0 -1
- package/dist/workflows/parser.js +50 -59
- package/dist/workflows/plan.js +8 -2
- package/dist/workflows/renderer.js +83 -9
- package/dist/workflows/resource-limits.js +2 -2
- package/dist/workflows/runtime/run-plan.js +38 -23
- package/dist/workflows/runtime/runs.js +55 -93
- package/dist/workflows/runtime/workflow-asset-loader.js +55 -86
- package/dist/workflows/source-files.js +7 -19
- package/docs/README.md +10 -16
- package/docs/architecture/README.md +2 -37
- package/docs/architecture/adapters.md +2 -2
- package/docs/architecture/akm-core-principles.md +256 -118
- package/docs/architecture/architecture.md +283 -99
- package/docs/architecture/improvement.md +8 -2
- package/docs/architecture/internals/classification.md +1 -3
- package/docs/architecture/internals/fresh-host-rebuild-runbook.md +7 -6
- package/docs/architecture/internals/health-advisories.md +35 -74
- package/docs/architecture/internals/improve-workflow.md +27 -26
- package/docs/architecture/internals/indexing.md +3 -3
- package/docs/architecture/internals/storage-locations.md +48 -15
- package/docs/architecture/persisted-data-compat.md +10 -6
- package/docs/architecture/specs/okf-support.md +9 -11
- package/docs/architecture/specs/ref.md +7 -9
- package/docs/architecture/testing/testing-workflow.md +172 -52
- package/docs/architecture/workflow-engine.md +51 -34
- package/docs/guides/README.md +0 -1
- package/docs/guides/author-bundles.md +15 -20
- package/docs/guides/author-workflows.md +93 -71
- package/docs/guides/bundles.md +20 -16
- package/docs/guides/discover-and-load.md +1 -1
- package/docs/guides/getting-started.md +49 -3
- package/docs/guides/improve-the-library.md +10 -4
- package/docs/guides/recipes/headless-install.md +11 -16
- package/docs/guides/run-workflows.md +29 -20
- package/docs/guides/scheduling.md +2 -2
- package/docs/guides/use-with-any-agent.md +20 -22
- package/docs/integration/bundling-akm.md +19 -9
- package/docs/maintainers/README.md +2 -6
- package/docs/maintainers/release-checklist.md +73 -126
- package/docs/migration/README.md +10 -3
- package/docs/migration/release-notes/0.10.0.md +81 -16
- 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.9.0.md +1 -1
- package/docs/migration/release-notes/README.md +1 -1
- package/docs/migration/v0.9-to-v0.10.md +300 -60
- package/docs/migration/v0.9.1-to-v0.9.2.md +6 -5
- package/docs/posts/config-v2-lessons-16.md +1 -1
- package/docs/posts/llm-mode-reflect-13.md +1 -1
- package/docs/posts/release-0.6.0.md +11 -11
- package/docs/posts/release-0.8.0.md +4 -4
- package/docs/posts/workflows-vaults-09.md +1 -1
- package/docs/reference/README.md +1 -1
- package/docs/reference/asset-types.md +2 -2
- package/docs/reference/cli.md +477 -388
- package/docs/reference/configuration.md +569 -550
- package/docs/reference/data-and-telemetry.md +9 -6
- package/docs/reference/env-and-secrets.md +72 -15
- package/docs/reference/refs.md +3 -20
- package/docs/reference/registry.md +12 -38
- package/docs/reference/supported-formats.md +1 -1
- package/docs/reference/tasks.md +22 -11
- package/docs/reference/ui-api.md +14 -9
- package/docs/reference/workflow-schema.md +199 -154
- package/docs/reference/workflows.md +4 -6
- package/package.json +9 -11
- package/schemas/akm-config.json +1696 -2922
- package/schemas/akm-task.json +4 -4
- package/schemas/akm-workflow.json +36 -9
- package/ROADMAP.md +0 -112
- package/dist/assets/models.json +0 -35
- package/dist/commands/health/engine-usage.js +0 -45
- package/dist/commands/sources/dangerous-env-audit.js +0 -134
- package/dist/core/activation-policy.js +0 -67
- package/dist/core/config/schema/engines.js +0 -160
- package/dist/core/config/schema/execution.js +0 -23
- package/dist/core/spawn-env.js +0 -268
- package/dist/execution/directory-identity.js +0 -78
- package/dist/integrations/agent/builder-shared.js +0 -33
- package/dist/integrations/agent/builders.js +0 -43
- package/dist/integrations/agent/engine-fallback.js +0 -59
- package/dist/integrations/agent/engine-resolution.js +0 -333
- package/dist/integrations/agent/model-map.js +0 -475
- package/dist/integrations/harnesses/aider/agent-builder.js +0 -107
- package/dist/integrations/harnesses/aider/result-extractor.js +0 -53
- package/dist/integrations/harnesses/amazonq/agent-builder.js +0 -138
- package/dist/integrations/harnesses/amazonq/result-extractor.js +0 -48
- package/dist/integrations/harnesses/claude/agent-builder.js +0 -106
- package/dist/integrations/harnesses/claude/config-import.js +0 -67
- package/dist/integrations/harnesses/claude/result-extractor.js +0 -67
- package/dist/integrations/harnesses/codex/agent-builder.js +0 -150
- package/dist/integrations/harnesses/codex/result-extractor.js +0 -110
- package/dist/integrations/harnesses/copilot/agent-builder.js +0 -117
- package/dist/integrations/harnesses/copilot/result-extractor.js +0 -178
- package/dist/integrations/harnesses/gemini/agent-builder.js +0 -114
- package/dist/integrations/harnesses/gemini/result-extractor.js +0 -149
- package/dist/integrations/harnesses/opencode/config-import.js +0 -149
- package/dist/integrations/harnesses/opencode/model-config.js +0 -33
- package/dist/integrations/harnesses/opencode/model-work-agent.js +0 -115
- package/dist/integrations/harnesses/opencode/session-log-types.js +0 -12
- package/dist/integrations/harnesses/opencode-sdk/index.js +0 -44
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +0 -1052
- package/dist/integrations/harnesses/opencode-sdk/v1-adapter.js +0 -199
- package/dist/integrations/harnesses/opencode-sdk/v2-adapter.js +0 -254
- package/dist/integrations/harnesses/opencode-sdk/wire.js +0 -66
- package/dist/integrations/harnesses/openhands/agent-builder.js +0 -120
- package/dist/integrations/harnesses/openhands/result-extractor.js +0 -135
- package/dist/integrations/harnesses/pi/agent-builder.js +0 -89
- package/dist/integrations/harnesses/pi/result-extractor.js +0 -168
- package/dist/integrations/harnesses/shared.js +0 -18
- package/dist/integrations/harnesses/types.js +0 -55
- package/dist/llm/feature-gate.js +0 -115
- package/dist/output/shapes/models-list.js +0 -16
- package/dist/output/shapes/registry-search.js +0 -10
- package/dist/setup/detected-engines.js +0 -136
- package/dist/setup/engine-config.js +0 -97
- package/dist/setup/harness-config-import.js +0 -47
- package/dist/setup/providers.js +0 -14
- package/dist/setup/steps/semantic.js +0 -39
- package/dist/workflows/authoring/scope-key.js +0 -79
- package/dist/workflows/exec/lowering-notices.js +0 -23
- package/dist/workflows/source-semantics.js +0 -110
- package/docs/architecture/0.10-process-rules.md +0 -832
- package/docs/architecture/akm-architecture-decision-history.md +0 -2055
- package/docs/architecture/comparisons/claude-code-vs-akm-workflows-full.md +0 -550
- package/docs/architecture/decisions/0001-no-interpolation-attached-structured-context.md +0 -72
- package/docs/architecture/decisions/0002-unit-reuse-and-input-hash-scope.md +0 -142
- package/docs/architecture/decisions/0003-child-env-allowlist-and-provenance.md +0 -189
- package/docs/architecture/decisions/0004-task-input-contract-and-flag-coercion.md +0 -97
- package/docs/architecture/decisions/0005-task-result-vocabulary-and-legacy-read-mapping.md +0 -108
- package/docs/architecture/decisions/0006-task-source-version-routing.md +0 -124
- package/docs/architecture/decisions/0007-workflow-composition-bounds.md +0 -83
- package/docs/architecture/decisions/0008-task-binding-normalization.md +0 -88
- package/docs/architecture/decisions/0009-child-run-publication-column-parity.md +0 -80
- package/docs/architecture/decisions/0010-driver-protocol-cut.md +0 -36
- package/docs/architecture/decisions/0011-engine-run-loop-invariants.md +0 -125
- package/docs/architecture/decisions/README.md +0 -62
- package/docs/architecture/internals/functional-contract-patterns.md +0 -340
- package/docs/architecture/internals/registry-network-boundary.md +0 -57
- package/docs/architecture/internals/search.md +0 -248
- package/docs/architecture/reviews/env-secret-access.md +0 -319
- package/docs/architecture/runtime-boundary-design.md +0 -153
- package/docs/architecture/specs/0.9.0-close-out-plan.md +0 -361
- package/docs/architecture/specs/0.9.0-decisions.md +0 -532
- package/docs/architecture/specs/0.9.0-docs-code-drift-register.md +0 -745
- package/docs/architecture/specs/0.9.0-open-items-register.md +0 -135
- package/docs/architecture/specs/0.9.0-public-api-issue-backlog.md +0 -740
- package/docs/architecture/specs/0.9.0-release-surface-review.md +0 -636
- package/docs/architecture/specs/agent-command-engine-model-design.md +0 -513
- package/docs/architecture/specs/akm-0.9.0-bundle-adapter-spec.md +0 -501
- package/docs/architecture/specs/akm-0.9.0-ref-grammar-decision.md +0 -291
- package/docs/architecture/specs/akm-format-neutral-bundle-workspace-spec.md +0 -2059
- package/docs/architecture/specs/di-seams-plan.md +0 -539
- package/docs/architecture/specs/driver-protocol-keep-or-cut.md +0 -275
- package/docs/architecture/specs/fact-asset-type.md +0 -142
- package/docs/architecture/specs/improve-collapse-churn-detector-design.md +0 -634
- package/docs/architecture/specs/reviews/task-workflow-unification/README.md +0 -72
- package/docs/architecture/specs/reviews/task-workflow-unification/findings-consolidated.md +0 -152
- package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-alternatives.md +0 -352
- package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-bunqueue.md +0 -300
- package/docs/architecture/specs/reviews/task-workflow-unification/library-eval-openworkflow.md +0 -402
- package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-1.md +0 -758
- package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-2.md +0 -645
- package/docs/architecture/specs/reviews/task-workflow-unification/opus-review-3.md +0 -602
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-adversarial.md +0 -27
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-architecture.md +0 -27
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-coverage.md +0 -74
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r1-security.md +0 -15
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r2-adversarial.md +0 -132
- package/docs/architecture/specs/reviews/task-workflow-unification/panel-r2-verification.md +0 -147
- package/docs/architecture/specs/stash-conventions-code-spec.md +0 -275
- package/docs/architecture/specs/stash-organization-conventions.md +0 -377
- package/docs/architecture/specs/task-workflow-format-unification.md +0 -721
- package/docs/architecture/specs/workflow-engine-buy-vs-build.md +0 -231
- package/docs/architecture/specs/workflow-format-unification.md +0 -432
- package/docs/architecture/testing/manual-testing-checklist.md +0 -3411
- package/docs/architecture/testing/okf-v0.2-conformance-runbook.md +0 -924
- package/docs/architecture/testing/task-workflow-manual-tests.md +0 -1720
- package/docs/guides/claude-code-vs-akm-workflows.md +0 -29
- package/docs/guides/knowledge-management.md +0 -18
- package/docs/maintainers/curate-workmap.md +0 -335
- package/docs/migration/v0.5-to-v0.6.md +0 -759
- package/docs/migration/v0.7-to-v0.8.md +0 -1378
- package/docs/plans/0.9.2-agent-command-workflow-plan.md +0 -423
|
@@ -4,12 +4,12 @@
|
|
|
4
4
|
/**
|
|
5
5
|
* Native executor — executes one frozen step subgraph (`WorkflowPlanStep.root`)
|
|
6
6
|
* locally: fan-out through the scheduler, structured output through
|
|
7
|
-
* `
|
|
7
|
+
* `structuredLoop`, per-unit journaling through the serialized writer queue,
|
|
8
8
|
* and `workflow_unit_*` events. It never writes step rows; advancing the spine
|
|
9
9
|
* is `run-workflow.ts`'s job.
|
|
10
10
|
*
|
|
11
11
|
* - Data flow: instructions are the step's prose byte-exact; data reaches a
|
|
12
|
-
* unit as attached context
|
|
12
|
+
* unit as attached context.
|
|
13
13
|
* - An empty successful free-text output is journaled as absent, so a live
|
|
14
14
|
* run and a resume promote the same artifact.
|
|
15
15
|
* - A declared step `output` schema is validated before the step completes;
|
|
@@ -23,26 +23,28 @@
|
|
|
23
23
|
* - Run `budget` ceilings are consumed per actual dispatch and abort the step
|
|
24
24
|
* when crossed, regardless of `on_error`.
|
|
25
25
|
*/
|
|
26
|
-
import {
|
|
26
|
+
import { resolveRefToken } from "../../commands/env/env-binding.js";
|
|
27
|
+
import { isInstalledBundle } from "../../core/env-secret-ref.js";
|
|
28
|
+
import { NotFoundError } from "../../core/errors.js";
|
|
27
29
|
import { validateJsonSchemaSubset } from "../../core/json-schema.js";
|
|
28
|
-
import {
|
|
30
|
+
import { substituteRefTokens } from "../../core/ref-token.js";
|
|
29
31
|
import { warn } from "../../core/warn.js";
|
|
30
|
-
import {
|
|
32
|
+
import { mergeNotices } from "../../execution/notices.js";
|
|
33
|
+
import { isRefused, jsonParser, structuredLoop } from "../../llm/structured.js";
|
|
31
34
|
import { withWorkflowRunsConnection, withWorkflowRunsRepo, } from "../../storage/repositories/workflow-runs-repository.js";
|
|
32
35
|
import { WORKFLOW_UNIT_DIAGNOSTIC_CLIP } from "../resource-limits.js";
|
|
36
|
+
import { resolveRunBundleRoot } from "../runtime/workflow-asset-loader.js";
|
|
33
37
|
// The ONE child-workflow drive — publishes and drives a
|
|
34
38
|
// `child-workflow`-targeted unit; this module's dispatch seam is its only
|
|
35
39
|
// production caller.
|
|
36
40
|
import { driveChildWorkflowUnit } from "./child-workflow.js";
|
|
37
|
-
// The
|
|
38
|
-
// (exec/frozen-judge.ts). Consumers import the leaf directly — this module is
|
|
41
|
+
// The unit outcome scrub. Consumers import the leaf directly — this module is
|
|
39
42
|
// not a second front door onto the seam.
|
|
40
43
|
import { collectWorkflowDispatchSensitiveValues, redactUnitOutcome } from "./dispatch-redaction.js";
|
|
41
44
|
import { materializeFrozenWorkflowEnvironment } from "./environment.js";
|
|
42
45
|
// The exec (shell) unit runner — a leaf that owns argv spawning, containment,
|
|
43
46
|
// and the process-outcome → failure-reason mapping.
|
|
44
47
|
import { runExecUnit } from "./exec-unit.js";
|
|
45
|
-
import { mergeLoweringNotices } from "./lowering-notices.js";
|
|
46
48
|
import { secretShapedParamValues } from "./param-secrets.js";
|
|
47
49
|
import { scheduleUnits } from "./scheduler.js";
|
|
48
50
|
// Shared step semantics — the ONE implementation consumed by the engine
|
|
@@ -167,22 +169,28 @@ function openDispatchBudget(ctx, dispatched) {
|
|
|
167
169
|
}
|
|
168
170
|
/** Resolve the live-at-dispatch prerequisites once, after durable-row reuse is known. */
|
|
169
171
|
async function prepareStepDispatchPrerequisites(input) {
|
|
170
|
-
const { plan, workUnits, willDispatch, dispatched } = input;
|
|
172
|
+
const { plan, ctx, workUnits, willDispatch, dispatched } = input;
|
|
171
173
|
let env;
|
|
172
174
|
let sensitiveValues;
|
|
175
|
+
// The run's bundle is found again here, never frozen: a bundle update moves it to a new directory.
|
|
176
|
+
let cwd = ctx.bundleRootOverride;
|
|
177
|
+
if (willDispatch && cwd === undefined) {
|
|
178
|
+
try {
|
|
179
|
+
cwd = resolveRunBundleRoot(ctx.workflowRef);
|
|
180
|
+
}
|
|
181
|
+
catch (err) {
|
|
182
|
+
return {
|
|
183
|
+
ok: false,
|
|
184
|
+
result: failedStep(dispatched, `Step "${plan.stepId}" cannot run: ${message(err).replace(/\.$/, "")}.`),
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
}
|
|
173
188
|
const frozenEnvironment = workUnits[0]?.environment;
|
|
174
189
|
if (willDispatch && frozenEnvironment && frozenEnvironment.length > 0) {
|
|
175
190
|
try {
|
|
176
191
|
const materialized = materializeFrozenWorkflowEnvironment(frozenEnvironment);
|
|
177
192
|
env = materialized.values;
|
|
178
193
|
sensitiveValues = materialized.sensitiveValues;
|
|
179
|
-
for (const audit of materialized.audits) {
|
|
180
|
-
appendEvent({
|
|
181
|
-
eventType: audit.eventType,
|
|
182
|
-
ref: audit.ref,
|
|
183
|
-
metadata: { keys: audit.keys, secretNames: audit.secretNames },
|
|
184
|
-
});
|
|
185
|
-
}
|
|
186
194
|
}
|
|
187
195
|
catch (err) {
|
|
188
196
|
return {
|
|
@@ -193,6 +201,7 @@ async function prepareStepDispatchPrerequisites(input) {
|
|
|
193
201
|
}
|
|
194
202
|
return {
|
|
195
203
|
ok: true,
|
|
204
|
+
...(cwd !== undefined ? { cwd } : {}),
|
|
196
205
|
...(env ? { env } : {}),
|
|
197
206
|
...(sensitiveValues ? { sensitiveValues } : {}),
|
|
198
207
|
};
|
|
@@ -229,13 +238,14 @@ async function executeStepPlanInConnection(plan, ctx) {
|
|
|
229
238
|
const willDispatch = reuseDecisions.some((decision) => decision.kind === "dispatch");
|
|
230
239
|
const prerequisites = await prepareStepDispatchPrerequisites({
|
|
231
240
|
plan,
|
|
241
|
+
ctx,
|
|
232
242
|
workUnits,
|
|
233
243
|
willDispatch,
|
|
234
244
|
dispatched,
|
|
235
245
|
});
|
|
236
246
|
if (!prerequisites.ok)
|
|
237
247
|
return prerequisites.result;
|
|
238
|
-
const { env, sensitiveValues } = prerequisites;
|
|
248
|
+
const { cwd, env, sensitiveValues } = prerequisites;
|
|
239
249
|
// Budget ceilings + lifetime-cap accounting, and the budget-chained abort
|
|
240
250
|
// signal they trip. Extracted verbatim (behavior-identical) — see
|
|
241
251
|
// {@link openDispatchBudget}.
|
|
@@ -246,6 +256,7 @@ async function executeStepPlanInConnection(plan, ctx) {
|
|
|
246
256
|
outcomes = await scheduleUnits(workUnits, (workUnit, index) => runUnit({
|
|
247
257
|
plan,
|
|
248
258
|
workUnit,
|
|
259
|
+
cwd,
|
|
249
260
|
env,
|
|
250
261
|
sensitiveValues,
|
|
251
262
|
ctx,
|
|
@@ -267,7 +278,7 @@ async function executeStepPlanInConnection(plan, ctx) {
|
|
|
267
278
|
// list with a failed-step envelope. Budget/cap and journal-write failures
|
|
268
279
|
// must not erase notices already observed from real dispatches; durable row
|
|
269
280
|
// reuses naturally contribute none.
|
|
270
|
-
const notices =
|
|
281
|
+
const notices = mergeNotices(...outcomes.map((outcome) => outcome?.notices));
|
|
271
282
|
// A declared budget ceiling is a hard backstop: a step that hit one FAILS
|
|
272
283
|
// regardless of on_error policy (a capped run must never quietly pass its
|
|
273
284
|
// gate). The budget message names WHICH ceiling tripped.
|
|
@@ -299,7 +310,7 @@ async function executeStepPlanInConnection(plan, ctx) {
|
|
|
299
310
|
};
|
|
300
311
|
}
|
|
301
312
|
async function runUnit(input) {
|
|
302
|
-
const { plan, workUnit, env, sensitiveValues, ctx, dispatcher } = input;
|
|
313
|
+
const { plan, workUnit, cwd, env, sensitiveValues, ctx, dispatcher } = input;
|
|
303
314
|
const unitId = workUnit.unitId;
|
|
304
315
|
// Target validity is a WHOLE-LIST invariant, never a per-unit condition:
|
|
305
316
|
// computeStepWorkList rejects a step before building any unit when its sole
|
|
@@ -317,10 +328,7 @@ async function runUnit(input) {
|
|
|
317
328
|
prompt,
|
|
318
329
|
frozenTarget: workUnit.frozenTarget,
|
|
319
330
|
...(workUnit.execContext ? { execContext: workUnit.execContext } : {}),
|
|
320
|
-
|
|
321
|
-
// exec units get it: handing an agent unit a cwd it never had would change
|
|
322
|
-
// harness behavior, and the agent path already takes its cwd from its profile.
|
|
323
|
-
...(workUnit.frozenTarget.kind !== "command" && ctx.workDir !== undefined ? { cwd: ctx.workDir } : {}),
|
|
331
|
+
...(cwd !== undefined ? { cwd } : {}),
|
|
324
332
|
timeoutMs: workUnit.timeoutMs,
|
|
325
333
|
...(workUnit.schema ? { schema: workUnit.schema } : {}),
|
|
326
334
|
...(env ? { env } : {}),
|
|
@@ -432,8 +440,8 @@ async function reserveJournaledDispatch(input, startedAt) {
|
|
|
432
440
|
parentUnitId: workUnit.isFanOut ? `${plan.stepId}.map` : null,
|
|
433
441
|
phase: "unit",
|
|
434
442
|
runner: workUnit.runner,
|
|
435
|
-
engine: target.kind === "command" ? target.request.
|
|
436
|
-
model: target.kind === "command" ? (target.request.model?.
|
|
443
|
+
engine: target.kind === "command" ? target.request.target.name : null,
|
|
444
|
+
model: target.kind === "command" ? (target.request.model?.model ?? null) : null,
|
|
437
445
|
inputHash,
|
|
438
446
|
now: startedAt,
|
|
439
447
|
}).attempt;
|
|
@@ -498,6 +506,7 @@ async function dispatchJournaledAttempt(input) {
|
|
|
498
506
|
};
|
|
499
507
|
// A child-workflow unit goes to the child executor instead of the
|
|
500
508
|
// dispatcher, after its attempt row is reserved, so it journals like any unit.
|
|
509
|
+
const resolvedSecrets = new Set();
|
|
501
510
|
const dispatched = request.frozenTarget.kind === "child-workflow"
|
|
502
511
|
? await driveChildWorkflowUnit({
|
|
503
512
|
request,
|
|
@@ -507,17 +516,18 @@ async function dispatchJournaledAttempt(input) {
|
|
|
507
516
|
inputHash: input.inputHash,
|
|
508
517
|
dispatcher,
|
|
509
518
|
})
|
|
510
|
-
: await dispatchUnit(request, dispatcher);
|
|
519
|
+
: await dispatchUnit(request, dispatcher, resolvedSecrets);
|
|
511
520
|
// Credential and passthrough values are intentionally sampled only AFTER
|
|
512
|
-
// the default dispatcher has
|
|
521
|
+
// the default dispatcher has lowered the frozen request and
|
|
513
522
|
// materialized credentials at its terminal dispatch boundary. Custom test
|
|
514
523
|
// dispatchers receive the same post-dispatch journal scrub. Secret-shaped
|
|
515
524
|
// run params join the set: they must reach the prompt in clear (the unit
|
|
516
|
-
// needs them), but nothing about them needs to reach the journal.
|
|
525
|
+
// needs them), but nothing about them needs to reach the journal. So do the
|
|
526
|
+
// secrets the dispatcher resolved itself (an exec unit's argv/cwd tokens).
|
|
517
527
|
const sensitiveValues = collectWorkflowDispatchSensitiveValues({
|
|
518
528
|
...(request.frozenTarget.kind === "command" ? { runner: request.frozenTarget.runner } : {}),
|
|
519
|
-
sensitiveValues: [...(request.sensitiveValues ?? []), ...secretShapedParamValues(ctx.params)],
|
|
520
|
-
}
|
|
529
|
+
sensitiveValues: [...(request.sensitiveValues ?? []), ...resolvedSecrets, ...secretShapedParamValues(ctx.params)],
|
|
530
|
+
});
|
|
521
531
|
const outcome = redactUnitOutcome(dispatched, sensitiveValues);
|
|
522
532
|
const finishedAt = new Date().toISOString();
|
|
523
533
|
// A dispatched unit's outcome is NEVER silently discarded: the attempt is
|
|
@@ -566,7 +576,7 @@ async function dispatchJournaledAttempt(input) {
|
|
|
566
576
|
* and hunts for a JSON island inside prose, which is the right forgiving
|
|
567
577
|
* behavior for an LLM and the wrong one for a command, where it would silently
|
|
568
578
|
* promote a JSON fragment found in unrelated log noise as the typed artifact.
|
|
569
|
-
* Returning `undefined` makes
|
|
579
|
+
* Returning `undefined` makes the structured loop report `parse_error` (a real
|
|
570
580
|
* member of the retry taxonomy), so `retry.on: [parse_error]` still works.
|
|
571
581
|
*/
|
|
572
582
|
function parseExecJson(raw) {
|
|
@@ -580,16 +590,9 @@ function parseExecJson(raw) {
|
|
|
580
590
|
return undefined;
|
|
581
591
|
}
|
|
582
592
|
}
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
constructor(result) {
|
|
587
|
-
super(result.error ?? "unit dispatch failed");
|
|
588
|
-
this.result = result;
|
|
589
|
-
this.name = "UnitTransportError";
|
|
590
|
-
}
|
|
591
|
-
}
|
|
592
|
-
async function dispatchUnit(request, dispatcher) {
|
|
593
|
+
async function dispatchUnit(request, dispatcher,
|
|
594
|
+
/** Receives the secret values the dispatcher resolved, for the caller's journal scrub. */
|
|
595
|
+
resolvedSecrets) {
|
|
593
596
|
let tokens = 0;
|
|
594
597
|
let sawUsage = false;
|
|
595
598
|
let loweringNotices;
|
|
@@ -600,20 +603,36 @@ async function dispatchUnit(request, dispatcher) {
|
|
|
600
603
|
let sessionId;
|
|
601
604
|
const dispatchOnce = async (feedback) => {
|
|
602
605
|
const result = await dispatcher(request, feedback);
|
|
606
|
+
for (const value of result.sensitiveValues ?? [])
|
|
607
|
+
resolvedSecrets.add(value);
|
|
603
608
|
if (result.usage) {
|
|
604
609
|
sawUsage = true;
|
|
605
610
|
tokens +=
|
|
606
611
|
(result.usage.inputTokens ?? 0) + (result.usage.outputTokens ?? 0) + (result.usage.reasoningTokens ?? 0);
|
|
607
612
|
}
|
|
608
|
-
loweringNotices =
|
|
613
|
+
loweringNotices = mergeNotices(loweringNotices, result.notices);
|
|
609
614
|
// Capture before the ok-check: a failed attempt can still have configured
|
|
610
615
|
// a session (e.g. codex `session_configured` then a tool crash).
|
|
611
616
|
if (result.sessionId !== undefined)
|
|
612
617
|
sessionId = result.sessionId;
|
|
613
|
-
if (!result.ok)
|
|
614
|
-
|
|
615
|
-
|
|
618
|
+
if (!result.ok) {
|
|
619
|
+
return {
|
|
620
|
+
ok: false,
|
|
621
|
+
failureReason: result.failureReason ?? "dispatch_error",
|
|
622
|
+
error: result.error ?? "unit dispatch failed",
|
|
623
|
+
text: result.text,
|
|
624
|
+
};
|
|
625
|
+
}
|
|
626
|
+
return { ok: true, raw: result.text };
|
|
616
627
|
};
|
|
628
|
+
const transportFailed = (failure) => ({
|
|
629
|
+
unitId: request.unitId,
|
|
630
|
+
ok: false,
|
|
631
|
+
failureReason: failure.failureReason,
|
|
632
|
+
error: failure.error,
|
|
633
|
+
text: failure.text,
|
|
634
|
+
...captured(),
|
|
635
|
+
});
|
|
617
636
|
const captured = () => ({
|
|
618
637
|
...(sawUsage ? { tokens } : {}),
|
|
619
638
|
...(sessionId !== undefined ? { sessionId } : {}),
|
|
@@ -622,28 +641,42 @@ async function dispatchUnit(request, dispatcher) {
|
|
|
622
641
|
try {
|
|
623
642
|
if (request.schema) {
|
|
624
643
|
const schema = request.schema;
|
|
625
|
-
const
|
|
626
|
-
|
|
644
|
+
const validate = (candidate) => {
|
|
645
|
+
const errors = validateJsonSchemaSubset(candidate, schema);
|
|
646
|
+
return errors.length === 0
|
|
647
|
+
? { ok: true, value: candidate }
|
|
648
|
+
: { ok: false, errors, reason: "validation_error" };
|
|
649
|
+
};
|
|
650
|
+
const structured = await structuredLoop({
|
|
651
|
+
dispatch: (correction) => dispatchOnce(correction?.text),
|
|
627
652
|
// A command is not re-promptable. Its stdout must be EXACTLY one JSON
|
|
628
653
|
// value: the default embedded-JSON scan (fences, think-blocks, "find the
|
|
629
654
|
// JSON inside the prose") is right for an LLM and wrong for a command,
|
|
630
655
|
// where it would pluck a JSON fragment out of unrelated log noise and
|
|
631
|
-
// promote it as the typed artifact. And it gets exactly ONE attempt
|
|
632
|
-
//
|
|
656
|
+
// promote it as the typed artifact. And it gets exactly ONE attempt:
|
|
657
|
+
// the loop's corrective retry re-dispatches with feedback, which
|
|
633
658
|
// for a command means running a SIDE-EFFECTING process a second time
|
|
634
659
|
// with byte-identical argv: it cannot produce different output, and it
|
|
635
660
|
// can produce a second deployment. Declared `retry:` still applies (the
|
|
636
661
|
// executor's own loop), because that is a policy the author opted into
|
|
637
662
|
// per failure reason.
|
|
638
|
-
...(request.frozenTarget.kind !== "command"
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
663
|
+
...(request.frozenTarget.kind !== "command"
|
|
664
|
+
? {
|
|
665
|
+
attempts: 1,
|
|
666
|
+
parse: (raw) => {
|
|
667
|
+
const candidate = parseExecJson(raw);
|
|
668
|
+
return candidate === undefined
|
|
669
|
+
? { ok: false, errors: ["no JSON structure found in response"], reason: "parse_error" }
|
|
670
|
+
: validate(candidate);
|
|
671
|
+
},
|
|
672
|
+
}
|
|
673
|
+
: { parse: jsonParser(validate) }),
|
|
643
674
|
});
|
|
644
675
|
if (structured.ok) {
|
|
645
676
|
return { unitId: request.unitId, ok: true, result: structured.value, ...captured() };
|
|
646
677
|
}
|
|
678
|
+
if (!isRefused(structured))
|
|
679
|
+
return transportFailed(structured);
|
|
647
680
|
return {
|
|
648
681
|
unitId: request.unitId,
|
|
649
682
|
ok: false,
|
|
@@ -661,7 +694,10 @@ async function dispatchUnit(request, dispatcher) {
|
|
|
661
694
|
...captured(),
|
|
662
695
|
};
|
|
663
696
|
}
|
|
664
|
-
const
|
|
697
|
+
const dispatched = await dispatchOnce();
|
|
698
|
+
if (!dispatched.ok)
|
|
699
|
+
return transportFailed(dispatched);
|
|
700
|
+
const text = dispatched.raw;
|
|
665
701
|
// Normalize an EMPTY successful output to "no text". `finishUnitAttempt` journals
|
|
666
702
|
// result_json = NULL for a falsy text, so durable-reuse rehydrates NO text
|
|
667
703
|
// from the row (unitOutcomeFromRow). Preserving `text: ""` only in this live
|
|
@@ -672,16 +708,6 @@ async function dispatchUnit(request, dispatcher) {
|
|
|
672
708
|
return { unitId: request.unitId, ok: true, ...(text ? { text } : {}), ...captured() };
|
|
673
709
|
}
|
|
674
710
|
catch (err) {
|
|
675
|
-
if (err instanceof UnitTransportError) {
|
|
676
|
-
return {
|
|
677
|
-
unitId: request.unitId,
|
|
678
|
-
ok: false,
|
|
679
|
-
failureReason: err.result.failureReason ?? "dispatch_error",
|
|
680
|
-
error: err.result.error ?? "unit dispatch failed",
|
|
681
|
-
text: err.result.text,
|
|
682
|
-
...captured(),
|
|
683
|
-
};
|
|
684
|
-
}
|
|
685
711
|
return {
|
|
686
712
|
unitId: request.unitId,
|
|
687
713
|
ok: false,
|
|
@@ -693,19 +719,21 @@ async function dispatchUnit(request, dispatcher) {
|
|
|
693
719
|
}
|
|
694
720
|
// ── Default dispatcher (production substrate) ───────────────────────────────
|
|
695
721
|
/**
|
|
696
|
-
* Dispatch a frozen
|
|
722
|
+
* Dispatch a frozen connection or harness through the common prepare → lower → dispatch seam.
|
|
697
723
|
* No live profile/default/model map is consulted, and credentials remain
|
|
698
724
|
* symbolic until the final dispatch boundary.
|
|
699
725
|
*/
|
|
700
726
|
export const defaultUnitDispatcher = async (request, feedback) => {
|
|
701
727
|
const frozenTarget = request.frozenTarget;
|
|
702
728
|
if (frozenTarget.kind === "shell") {
|
|
703
|
-
if (
|
|
704
|
-
|
|
705
|
-
|
|
729
|
+
if (request.cwd === undefined) {
|
|
730
|
+
throw new Error(`exec unit "${request.unitId}" was dispatched with no working directory.`);
|
|
731
|
+
}
|
|
732
|
+
const { exec, secretValues } = substituteExecRefs(request.unitId, frozenTarget.exec);
|
|
733
|
+
const outcome = await runExecUnit({
|
|
706
734
|
unitId: request.unitId,
|
|
707
|
-
exec
|
|
708
|
-
baseDir: request.cwd
|
|
735
|
+
exec,
|
|
736
|
+
baseDir: request.cwd,
|
|
709
737
|
...(request.env ? { env: request.env } : {}),
|
|
710
738
|
...(request.execContext ? { context: request.execContext } : {}),
|
|
711
739
|
...(request.schema ? { hasOutputSchema: true } : {}),
|
|
@@ -713,9 +741,36 @@ export const defaultUnitDispatcher = async (request, feedback) => {
|
|
|
713
741
|
...(request.signal ? { signal: request.signal } : {}),
|
|
714
742
|
...(request.eventSource !== undefined ? { eventSource: request.eventSource } : {}),
|
|
715
743
|
});
|
|
744
|
+
// A secret substituted into argv joins the redaction set, like one bound through an env asset: the
|
|
745
|
+
// executor scrubs after the structured parse, so a quoted or numeric secret is not missed or corrupted.
|
|
746
|
+
return { ...outcome, sensitiveValues: secretValues };
|
|
716
747
|
}
|
|
717
748
|
return dispatchWorkflowExecution(request, feedback);
|
|
718
749
|
};
|
|
750
|
+
/**
|
|
751
|
+
* Replace the `${ref}` tokens in an exec unit's argv and `cwd` (prompts are not substituted): a
|
|
752
|
+
* `secrets/` ref with the secret's value, any other asset ref with its absolute path. A ref no
|
|
753
|
+
* bundle owns fails the unit before anything is spawned.
|
|
754
|
+
*/
|
|
755
|
+
function substituteExecRefs(unitId, exec) {
|
|
756
|
+
const slots = Object.fromEntries(exec.command.entries());
|
|
757
|
+
if (exec.cwd !== undefined)
|
|
758
|
+
slots.cwd = exec.cwd;
|
|
759
|
+
const { values, missing, secretValues } = substituteRefTokens(slots, resolveRefToken, isInstalledBundle);
|
|
760
|
+
if (missing.length > 0) {
|
|
761
|
+
throw new NotFoundError(`exec unit "${unitId}" references asset(s) that no bundle owns: ${missing.join(", ")}. Nothing was run.`, "FILE_NOT_FOUND",
|
|
762
|
+
// biome-ignore lint/suspicious/noTemplateCurlyInString: literal `${ref}` token syntax documented for users, not interpolation
|
|
763
|
+
"Write each `${ref}` as a full akm ref that exists, e.g. `${team//scripts/run.sh}`.");
|
|
764
|
+
}
|
|
765
|
+
return {
|
|
766
|
+
exec: {
|
|
767
|
+
...exec,
|
|
768
|
+
command: exec.command.map((_, index) => values[index]),
|
|
769
|
+
...(exec.cwd !== undefined ? { cwd: values.cwd } : {}),
|
|
770
|
+
},
|
|
771
|
+
secretValues,
|
|
772
|
+
};
|
|
773
|
+
}
|
|
719
774
|
// ── Small helpers ────────────────────────────────────────────────────────────
|
|
720
775
|
/**
|
|
721
776
|
* Rehydrate a journaled completed unit row into a UnitOutcome (durable-row
|
|
@@ -6,25 +6,22 @@
|
|
|
6
6
|
* execute path. akm walks the frozen plan (read from `plan_json`, never live
|
|
7
7
|
* source) and dispatches every unit itself; every step advances through
|
|
8
8
|
* `completeWorkflowStep`; one O_EXCL lock file per run keeps a second driver
|
|
9
|
-
* off (a dead holder's lock is reclaimed); gate loops are bounded
|
|
10
|
-
* SDK dispatch registry is drained on every exit so the process can exit.
|
|
11
|
-
* See docs/architecture/decisions/0011-engine-run-loop-invariants.md.
|
|
9
|
+
* off (a dead holder's lock is reclaimed); and gate loops are bounded.
|
|
12
10
|
*/
|
|
13
11
|
import { createHash } from "node:crypto";
|
|
14
12
|
import fs from "node:fs";
|
|
15
13
|
import path from "node:path";
|
|
16
14
|
import { TransientError, UsageError } from "../../core/errors.js";
|
|
17
|
-
import { releaseLock } from "../../core/file-lock.js";
|
|
15
|
+
import { probeLock, releaseLock } from "../../core/file-lock.js";
|
|
18
16
|
import { formatLockHolderPid, tryAcquireRunLock } from "../../core/run-lock.js";
|
|
19
|
-
import {
|
|
17
|
+
import { mergeNotices } from "../../execution/notices.js";
|
|
20
18
|
import { resolveStorageLocations } from "../../storage/locations.js";
|
|
21
19
|
import { withWorkflowRunsConnection, withWorkflowRunsRepo } from "../../storage/repositories/workflow-runs-repository.js";
|
|
22
20
|
import { computePlanHash } from "../ir/plan-hash.js";
|
|
23
21
|
import { decodeWorkflowPlan, readRunPlan } from "../runtime/run-plan.js";
|
|
24
|
-
import { abandonWorkflowRun, getNextWorkflowStep, resumeWorkflowRun } from "../runtime/runs.js";
|
|
22
|
+
import { abandonWorkflowRun, getNextWorkflowStep, listWorkflowRuns, resolveWorkflowRunTarget, resumeWorkflowRun, } from "../runtime/runs.js";
|
|
25
23
|
import { loadWorkflowAsset } from "../runtime/workflow-asset-loader.js";
|
|
26
|
-
import { frozenSummaryJudge } from "./frozen-judge.js";
|
|
27
|
-
import { mergeLoweringNotices } from "./lowering-notices.js";
|
|
24
|
+
import { frozenSummaryJudge, resolveJudgeCwd } from "./frozen-judge.js";
|
|
28
25
|
import { defaultUnitDispatcher, executeStepPlan, } from "./native-executor.js";
|
|
29
26
|
// Shared step semantics — gate-evaluation journaling, and the whole step-completion path
|
|
30
27
|
// (`finalizeExecutedStep`) live in step-work.ts as ONE implementation, so the
|
|
@@ -34,10 +31,6 @@ export async function runWorkflowSteps(options) {
|
|
|
34
31
|
let target = options.target;
|
|
35
32
|
let params = options.params;
|
|
36
33
|
let parameterFlags = options.parameterFlags;
|
|
37
|
-
// `--new` only applies to the FIRST resolution of `target` (a ref); every
|
|
38
|
-
// retry re-targets the run id `startWorkflowRun` already created, so it is
|
|
39
|
-
// cleared alongside `params`/`parameterFlags` below (#919).
|
|
40
|
-
let newRun = options.newRun;
|
|
41
34
|
let remainingRetries = options.maxRetries ?? 0;
|
|
42
35
|
let remainingSteps = options.maxSteps;
|
|
43
36
|
const executed = [];
|
|
@@ -53,12 +46,11 @@ export async function runWorkflowSteps(options) {
|
|
|
53
46
|
target,
|
|
54
47
|
...(params !== undefined ? { params } : { params: undefined }),
|
|
55
48
|
...(parameterFlags !== undefined ? { parameterFlags } : { parameterFlags: undefined }),
|
|
56
|
-
newRun,
|
|
57
49
|
...(remainingSteps !== undefined ? { maxSteps: remainingSteps } : { maxSteps: undefined }),
|
|
58
50
|
}, liveEvidence);
|
|
59
51
|
executed.push(...result.executed);
|
|
60
52
|
stepsProcessed += result.stepsProcessed;
|
|
61
|
-
const notices =
|
|
53
|
+
const notices = mergeNotices(...executed.map((step) => step.notices));
|
|
62
54
|
const aggregate = { ...result, executed, stepsProcessed, ...(notices ? { notices } : {}) };
|
|
63
55
|
// An attempt that executed nothing (an abandoned, undecodable plan) has no
|
|
64
56
|
// failed step for a retry to re-open.
|
|
@@ -81,14 +73,12 @@ export async function runWorkflowSteps(options) {
|
|
|
81
73
|
target = result.run.id;
|
|
82
74
|
params = undefined;
|
|
83
75
|
parameterFlags = undefined;
|
|
84
|
-
newRun = undefined;
|
|
85
76
|
remainingRetries -= 1;
|
|
86
77
|
}
|
|
87
78
|
}
|
|
88
79
|
async function runWorkflowAttempt(options, liveEvidence) {
|
|
89
80
|
const next = await getNextWorkflowStep(options.target, options.params, {
|
|
90
81
|
parameterFlags: options.parameterFlags,
|
|
91
|
-
newRun: options.newRun,
|
|
92
82
|
});
|
|
93
83
|
// Refuse non-active runs BEFORE any dispatch — completeWorkflowStep would
|
|
94
84
|
// reject the completion anyway, but only after the units already ran (and
|
|
@@ -125,7 +115,6 @@ async function runWorkflowAttempt(options, liveEvidence) {
|
|
|
125
115
|
executed: [],
|
|
126
116
|
stepsProcessed: 0,
|
|
127
117
|
warnings: [...warnings, message],
|
|
128
|
-
...(next.resumed ? { resumed: true } : {}),
|
|
129
118
|
};
|
|
130
119
|
}
|
|
131
120
|
plan = read.plan;
|
|
@@ -141,37 +130,43 @@ async function runWorkflowAttempt(options, liveEvidence) {
|
|
|
141
130
|
// Creation/resume-time notices reach the caller only here: the run row
|
|
142
131
|
// has no warnings column, and a later invocation of the same run must
|
|
143
132
|
// stay silent about a decision it did not make. `driveRun` never sets
|
|
144
|
-
// `warnings`
|
|
145
|
-
//
|
|
133
|
+
// `warnings` — it is a property of THIS resolution of `target`, not of
|
|
134
|
+
// the run row.
|
|
146
135
|
return {
|
|
147
136
|
...result,
|
|
148
|
-
...(next.resumed ? { resumed: true } : {}),
|
|
149
137
|
...(warnings.length > 0 ? { warnings } : {}),
|
|
150
138
|
};
|
|
151
139
|
}
|
|
152
140
|
finally {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
releaseLock(lock);
|
|
156
|
-
}
|
|
157
|
-
finally {
|
|
158
|
-
// Process-lifecycle drain (owner finding 4): release any cached SDK server
|
|
159
|
-
// child processes so a one-shot CLI invocation exits cleanly instead of
|
|
160
|
-
// hanging on the leaked handle. Runs even if the lock release itself
|
|
161
|
-
// fails; a teardown-time error must not skip dispatch cleanup.
|
|
162
|
-
try {
|
|
163
|
-
await (options.disposeDispatchResources ?? disposeDispatchResources)();
|
|
164
|
-
}
|
|
165
|
-
catch {
|
|
166
|
-
/* disposal is best-effort; never let cleanup mask the run outcome */
|
|
167
|
-
}
|
|
168
|
-
}
|
|
141
|
+
if (lock)
|
|
142
|
+
releaseLock(lock);
|
|
169
143
|
}
|
|
170
144
|
}
|
|
171
145
|
/** The per-run lock file: `<data dir>/workflow-run-locks/<run id>.lock`, next to `state.db`. */
|
|
172
146
|
export function workflowRunLockPath(runId) {
|
|
173
147
|
return path.join(path.dirname(resolveStorageLocations().stateDb), "workflow-run-locks", `${runId}.lock`);
|
|
174
148
|
}
|
|
149
|
+
/**
|
|
150
|
+
* `--skip-if-locked` for a workflow REF (#1239): an active run of `ref` whose
|
|
151
|
+
* lock a live process holds, or `undefined`. A run id (which drives that one
|
|
152
|
+
* run, and fails with `RUN_LEASE_HELD` if it is held) is never a ref. Read-only:
|
|
153
|
+
* `probeLock` reports a dead holder as stale without reclaiming it.
|
|
154
|
+
*/
|
|
155
|
+
export async function findLiveLockedRunOfRef(target) {
|
|
156
|
+
if ((await resolveWorkflowRunTarget(target)) !== undefined)
|
|
157
|
+
return undefined;
|
|
158
|
+
const { runs } = await listWorkflowRuns({ workflowRef: target, activeOnly: true });
|
|
159
|
+
for (const run of runs) {
|
|
160
|
+
const probe = probeLock(workflowRunLockPath(run.id));
|
|
161
|
+
if (probe.state === "held") {
|
|
162
|
+
return {
|
|
163
|
+
runId: run.id,
|
|
164
|
+
holder: formatLockHolderPid({ pid: probe.holderPid, launcherPid: probe.launcherPid ?? null }),
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return undefined;
|
|
169
|
+
}
|
|
175
170
|
/**
|
|
176
171
|
* Take the run's O_EXCL lock file, or refuse with `RUN_LEASE_HELD` (exit 75)
|
|
177
172
|
* naming the live holder. A lock whose holder pid is dead is reclaimed by
|
|
@@ -215,7 +210,7 @@ async function workflowSourceDriftWarning(runId, workflowRef, plan) {
|
|
|
215
210
|
if (current === plan.sourceHash)
|
|
216
211
|
return undefined;
|
|
217
212
|
return (`Workflow run ${runId}: ${workflowRef} (${sourcePath}) has changed since this run was frozen; ` +
|
|
218
|
-
`continuing with the frozen plan. Start a new run with 'akm workflow run ${workflowRef}
|
|
213
|
+
`continuing with the frozen plan. Start a new run with 'akm workflow run ${workflowRef}' to pick up the edit.`);
|
|
219
214
|
}
|
|
220
215
|
/**
|
|
221
216
|
* A terminal run is a pure no-op: do not load or integrity-check its frozen
|
|
@@ -230,11 +225,11 @@ async function completedRunResult(runId) {
|
|
|
230
225
|
...(doneState.run.status === "completed" ? { done: true } : {}),
|
|
231
226
|
};
|
|
232
227
|
}
|
|
233
|
-
function workflowSummaryJudge(options, stepPlan, signal, owner) {
|
|
228
|
+
function workflowSummaryJudge(options, stepPlan, signal, owner, workflowRef) {
|
|
234
229
|
if (options.summaryJudge !== undefined)
|
|
235
230
|
return options.summaryJudge;
|
|
236
231
|
// The judge dispatches under the real run/step identity and the same event source as units.
|
|
237
|
-
return frozenSummaryJudge(stepPlan.gate.frozenJudge, signal, options.dispatcher ?? defaultUnitDispatcher, owner, options.eventSource);
|
|
232
|
+
return frozenSummaryJudge(stepPlan.gate.frozenJudge, signal, options.dispatcher ?? defaultUnitDispatcher, owner, options.eventSource, options.bundleRootOverride ?? resolveJudgeCwd(stepPlan.gate.frozenJudge, workflowRef));
|
|
238
233
|
}
|
|
239
234
|
/**
|
|
240
235
|
* Seed the run's budget from the append-only attempt journal so a resumed run
|
|
@@ -307,6 +302,7 @@ async function executeStepSubgraph(ctx, loop) {
|
|
|
307
302
|
...(options.eventSource !== undefined ? { eventSource: options.eventSource } : {}),
|
|
308
303
|
...(options.signal ? { signal: options.signal } : {}),
|
|
309
304
|
...(options.dispatcher ? { dispatcher: options.dispatcher } : {}),
|
|
305
|
+
...(options.bundleRootOverride !== undefined ? { bundleRootOverride: options.bundleRootOverride } : {}),
|
|
310
306
|
maxConcurrency: Math.min(options.maxConcurrency ?? Number.POSITIVE_INFINITY, plan.execution?.maxConcurrency ?? 1),
|
|
311
307
|
});
|
|
312
308
|
}
|
|
@@ -484,7 +480,7 @@ liveEvidence) {
|
|
|
484
480
|
break;
|
|
485
481
|
}
|
|
486
482
|
// Judge-outage contract: resolve the step's frozen completion judge BEFORE
|
|
487
|
-
// any dispatch. An unresolvable judge (missing frozen
|
|
483
|
+
// any dispatch. An unresolvable judge (missing frozen connection or harness, no dispatcher
|
|
488
484
|
// for an agent judge) is verifier INFRASTRUCTURE failure — block the step
|
|
489
485
|
// for `akm workflow resume` instead of spending on units the gate can never
|
|
490
486
|
// verify. No gate loop is consumed and nothing is dispatched.
|
|
@@ -493,7 +489,7 @@ liveEvidence) {
|
|
|
493
489
|
summaryJudge = workflowSummaryJudge(options, stepPlan, options.signal, {
|
|
494
490
|
runId: next.run.id,
|
|
495
491
|
stepId: step.id,
|
|
496
|
-
});
|
|
492
|
+
}, next.run.workflowRef);
|
|
497
493
|
}
|
|
498
494
|
catch (error) {
|
|
499
495
|
const detail = error instanceof Error && error.message ? ` (${error.message})` : "";
|
|
@@ -541,7 +537,7 @@ liveEvidence) {
|
|
|
541
537
|
}
|
|
542
538
|
// Re-read for the freshest run state (the loop may have exited on maxSteps).
|
|
543
539
|
const finalState = await getNextWorkflowStep(next.run.id);
|
|
544
|
-
const notices =
|
|
540
|
+
const notices = mergeNotices(...executed.map((step) => step.notices));
|
|
545
541
|
return {
|
|
546
542
|
run: finalState.run,
|
|
547
543
|
executed,
|