akm-cli 0.9.16 → 0.9.17-alpha.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +2101 -0
- package/STABILITY.md +11 -10
- package/dist/akm +124 -193
- package/dist/akm-migrate +38 -19
- package/dist/assets/hints/cli-hints-full.md +6 -7
- package/dist/assets/improve-strategies/catchup.json +0 -3
- package/dist/assets/improve-strategies/consolidate.json +0 -1
- package/dist/assets/improve-strategies/default.json +1 -2
- package/dist/assets/improve-strategies/proactive-maintenance.json +1 -2
- package/dist/assets/improve-strategies/quick.json +1 -2
- package/dist/assets/improve-strategies/reflect-distill.json +1 -2
- package/dist/assets/improve-strategies/thorough.json +0 -3
- package/dist/assets/prompts/consolidate-pair.md +20 -0
- package/dist/assets/prompts/consolidate-system.md +4 -11
- package/dist/assets/prompts/retrieval-relevance-judge.md +6 -0
- package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +20 -20
- package/dist/assets/stash-skeleton/facts/conventions/domains.md +2 -2
- package/dist/assets/templates/html/health.html +3 -5
- package/dist/cli/retired-commands.js +1 -1
- package/dist/cli/shared.js +6 -2
- package/dist/cli/unknown-flags.js +24 -1
- package/dist/cli.js +68 -10
- package/dist/commands/agent/agent-dispatch.js +1 -1
- package/dist/commands/command/command-execution.js +24 -62
- package/dist/commands/feedback-cli.js +0 -1
- package/dist/commands/health/accept-rate.js +6 -0
- package/dist/commands/health/archive-usage.js +92 -0
- package/dist/commands/health/checks.js +83 -74
- package/dist/commands/health/config-skew.js +38 -0
- package/dist/commands/health/data-dir-usage.js +25 -13
- package/dist/commands/health/egress.js +54 -0
- package/dist/commands/health/html-report.js +1 -42
- package/dist/commands/health/improve-metrics.js +136 -591
- package/dist/commands/health/md-report.js +1 -6
- package/dist/commands/health/plugin-staleness.js +53 -3
- package/dist/commands/health/renderers.js +12 -4
- package/dist/commands/health/report-view-model.js +14 -120
- package/dist/commands/health/types-improve.js +4 -19
- package/dist/commands/health/windows.js +64 -74
- package/dist/commands/health.js +145 -143
- package/dist/commands/improve/consolidate/chunking.js +26 -117
- package/dist/commands/improve/consolidate/continuity-check.js +137 -0
- package/dist/commands/improve/consolidate/pair-pass.js +791 -0
- package/dist/commands/improve/consolidate/sanitize.js +54 -149
- package/dist/commands/improve/consolidate.js +589 -1127
- package/dist/commands/improve/content-hash.js +16 -24
- package/dist/commands/improve/distill/content-repair.js +18 -100
- package/dist/commands/improve/distill-guards.js +20 -81
- package/dist/commands/improve/distill-promotion-policy.js +23 -243
- package/dist/commands/improve/distill.js +608 -1041
- package/dist/commands/improve/eligibility.js +126 -390
- package/dist/commands/improve/execution.js +8 -10
- package/dist/commands/improve/extract-prompt.js +1 -2
- package/dist/commands/improve/extract.js +487 -1046
- package/dist/commands/improve/feedback-valence.js +0 -25
- package/dist/commands/improve/improve-cli.js +75 -169
- package/dist/commands/improve/improve-result-file.js +10 -66
- package/dist/commands/improve/improve-strategies.js +52 -4
- package/dist/commands/improve/improve-usage-report.js +18 -64
- package/dist/commands/improve/improve.js +480 -1074
- package/dist/commands/improve/ledger.js +119 -0
- package/dist/commands/improve/locks.js +2 -8
- package/dist/commands/improve/loop-stages.js +415 -1073
- package/dist/commands/improve/memory/derived-ref.js +12 -77
- package/dist/commands/improve/memory/memory-belief.js +16 -118
- package/dist/commands/improve/memory/memory-improve.js +266 -14
- package/dist/commands/improve/outcome-loop.js +28 -156
- package/dist/commands/improve/planner.js +5 -15
- package/dist/commands/improve/preparation.js +779 -2319
- package/dist/commands/improve/proactive-maintenance.js +34 -101
- package/dist/commands/improve/reflect-noise.js +104 -280
- package/dist/commands/improve/reflect.js +642 -1353
- package/dist/commands/improve/retrieval-gate.js +127 -0
- package/dist/commands/improve/retrieval-scope.js +92 -0
- package/dist/commands/improve/salience.js +41 -240
- package/dist/commands/improve/session-asset.js +19 -100
- package/dist/commands/improve/stage.js +322 -0
- package/dist/commands/lint/base-linter.js +37 -15
- package/dist/commands/proposal/drain.js +261 -578
- package/dist/commands/proposal/proposal-cli.js +19 -20
- package/dist/commands/proposal/proposal-types.js +31 -24
- package/dist/commands/proposal/proposal.js +38 -8
- package/dist/commands/proposal/propose.js +134 -160
- package/dist/commands/proposal/repository.js +1097 -1394
- package/dist/commands/proposal/validators/proposal-quality-validators.js +71 -174
- package/dist/commands/proposal/validators/proposal-validators.js +1 -1
- package/dist/commands/proposal/validators/proposals.js +22 -89
- package/dist/commands/read/curate.js +105 -462
- package/dist/commands/read/knowledge.js +3 -2
- package/dist/commands/read/search-cli.js +16 -33
- package/dist/commands/read/search.js +17 -23
- package/dist/commands/read/show.js +57 -108
- package/dist/commands/sources/bundle-cli.js +25 -2
- package/dist/commands/sources/bundle-config-ops.js +4 -0
- package/dist/commands/sources/dangerous-env-audit.js +1 -2
- package/dist/commands/sources/info.js +127 -29
- package/dist/commands/sources/installed-stashes.js +197 -746
- package/dist/commands/sources/schema-repair.js +98 -129
- package/dist/commands/sources/source-add.js +62 -12
- package/dist/commands/sources/source-manage.js +9 -2
- package/dist/commands/sources/stash-cli.js +24 -4
- package/dist/commands/tasks/explain.js +10 -13
- package/dist/commands/tasks/tasks-cli.js +12 -13
- package/dist/commands/tasks/tasks.js +350 -936
- package/dist/commands/tasks/validate.js +26 -24
- package/dist/commands/workflow/plan.js +22 -29
- package/dist/commands/workflow-cli.js +4 -4
- package/dist/core/adapter/adapters/akm-adapter.js +2 -1
- package/dist/core/adapter/adapters/akm-lint.js +2 -3
- package/dist/core/adapter/adapters/akm-metadata.js +42 -12
- package/dist/core/adapter/adapters/akm-task-adapter.js +29 -8
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +1 -1
- package/dist/core/adapter/execution-source.js +17 -29
- package/dist/core/asset/asset-placement.js +4 -13
- package/dist/core/asset/frontmatter.js +106 -1
- package/dist/core/asset/resolve-ref.js +1 -1
- package/dist/core/bundle-id.js +42 -5
- package/dist/core/bundle-rename.js +285 -0
- package/dist/core/config/config-io.js +1 -2
- package/dist/core/config/config-schema.js +9 -34
- package/dist/core/config/config-walker.js +1 -1
- package/dist/core/config/config.js +184 -111
- package/dist/core/config/engine-semantics.js +0 -2
- package/dist/core/config/legacy-source-shape-shim.js +38 -9
- package/dist/core/config/schema/embedding.js +20 -5
- package/dist/core/config/schema/engines.js +5 -0
- package/dist/core/config/schema/execution.js +1 -1
- package/dist/core/config/schema/experimental.js +1 -1
- package/dist/core/config/schema/improve-processes.js +54 -125
- package/dist/core/config/schema/improve.js +4 -42
- package/dist/core/config/schema/index-config.js +9 -48
- package/dist/core/config/schema/scheduler.js +12 -12
- package/dist/core/config/schema/search.js +6 -22
- package/dist/core/env-secret-ref.js +0 -1
- package/dist/core/errors.js +8 -9
- package/dist/core/file-change.js +13 -5
- package/dist/core/file-lock.js +76 -173
- package/dist/core/improve-result.js +35 -7
- package/dist/core/improve-types.js +0 -1
- package/dist/core/logs-db.js +2 -2
- package/dist/core/loopback.js +7 -12
- package/dist/core/non-task-input.js +20 -0
- package/dist/core/parse.js +13 -16
- package/dist/core/paths.js +0 -24
- package/dist/core/redaction.js +109 -2
- package/dist/core/run-lock.js +2 -5
- package/dist/core/spawn-env.js +1 -1
- package/dist/core/state/migrations.js +123 -61
- package/dist/core/state-db-scope.js +2 -4
- package/dist/core/state-db.js +126 -692
- package/dist/core/time.js +0 -20
- package/dist/core/type-presentation.js +1 -9
- package/dist/core/write-source.js +294 -1005
- package/dist/execution/input-contract.js +1 -1
- package/dist/execution/resolved-request.js +135 -689
- package/dist/execution/source.js +63 -257
- package/dist/execution/target-ref.js +1 -1
- package/dist/indexer/bundle-identity-guard.js +2 -2
- package/dist/indexer/db/llm-cache.js +2 -2
- package/dist/indexer/ensure-index.js +77 -73
- package/dist/indexer/index-rebuild-lock.js +3 -11
- package/dist/indexer/index-writer-lock.js +8 -17
- package/dist/indexer/index-written-assets.js +141 -154
- package/dist/indexer/indexer.js +400 -1124
- package/dist/indexer/links/declared-links.js +90 -0
- package/dist/indexer/materialize-embeddings.js +60 -397
- package/dist/indexer/passes/memory-inference.js +96 -90
- package/dist/indexer/passes/metadata.js +132 -219
- package/dist/indexer/read-preflight.js +0 -7
- package/dist/indexer/scan/doc-to-entry.js +2 -3
- package/dist/indexer/scan/drain-dir.js +1 -1
- package/dist/indexer/search/db-search.js +190 -590
- package/dist/indexer/search/fts-query.js +30 -41
- package/dist/indexer/search/ranking.js +28 -154
- package/dist/indexer/search/search-attribution.js +12 -32
- package/dist/indexer/search/search-fields.js +11 -15
- package/dist/indexer/search/search-hit-enrichers.js +54 -85
- package/dist/indexer/search/search-source.js +1 -4
- package/dist/indexer/usage/usage-events.js +36 -7
- package/dist/indexer/walk/walker.js +3 -4
- package/dist/integrations/agent/engine-fallback.js +23 -40
- package/dist/integrations/agent/engine-resolution.js +93 -183
- package/dist/integrations/agent/execution.js +507 -0
- package/dist/integrations/agent/model-map.js +28 -156
- package/dist/integrations/agent/request-lowering.js +66 -141
- package/dist/integrations/agent/runner-dispatch.js +143 -321
- package/dist/integrations/agent/runner.js +54 -14
- package/dist/integrations/lockfile.js +53 -101
- package/dist/llm/client.js +18 -6
- package/dist/llm/embedders/deterministic.js +2 -3
- package/dist/llm/embedders/profile.js +71 -0
- package/dist/llm/embedders/remote.js +11 -17
- package/dist/llm/feature-gate.js +0 -8
- package/dist/llm/index-passes.js +3 -5
- package/dist/llm/memory-infer.js +1 -2
- package/dist/llm/structured-call.js +5 -24
- package/dist/output/generic-render.js +23 -11
- package/dist/output/html-render.js +13 -10
- package/dist/output/render-registry.js +3 -32
- package/dist/output/shapes/helpers.js +25 -38
- package/dist/output/shapes/passthrough.js +1 -9
- package/dist/{indexer/graph/graph-types.js → output/text/bundle-rename.js} +4 -1
- package/dist/output/text/command-format.js +69 -31
- package/dist/output/text/helpers.js +1 -1
- package/dist/output/text/migrate.js +5 -14
- package/dist/output/text/proposal-format.js +48 -3
- package/dist/output/text/show-format.js +13 -17
- package/dist/output/text/workflow-format.js +0 -32
- package/dist/output/text.js +2 -0
- package/dist/registry/factory.js +4 -19
- package/dist/registry/network.js +66 -220
- package/dist/registry/providers/index.js +0 -2
- package/dist/registry/providers/skills-sh.js +3 -14
- package/dist/registry/providers/static-index.js +24 -26
- package/dist/registry/resolve.js +55 -131
- package/dist/scripts/akm-migrate-node.js +42948 -92369
- package/dist/scripts/akm-migrate.js +42935 -92354
- package/dist/setup/registry-stash-loader.js +4 -13
- package/dist/setup/semantic-assets.js +3 -44
- package/dist/setup/setup.js +1 -1
- package/dist/setup/steps/connection.js +5 -6
- package/dist/setup/steps/platforms.js +2 -2
- package/dist/setup/steps/tasks.js +25 -15
- package/dist/sources/provider-factory.js +17 -18
- package/dist/sources/providers/filesystem.js +2 -3
- package/dist/sources/providers/git-install.js +7 -1
- package/dist/sources/providers/git-provider.js +0 -3
- package/dist/sources/providers/git-stash.js +83 -21
- package/dist/sources/providers/npm.js +2 -4
- package/dist/sources/providers/provider-utils.js +5 -10
- package/dist/sources/providers/website.js +0 -2
- package/dist/sources/snapshot-fetchers/website-ingest.js +1 -1
- package/dist/sources/website-url.js +2 -2
- package/dist/storage/database.js +9 -35
- package/dist/storage/repositories/improve-ledger-repository.js +209 -0
- package/dist/storage/repositories/index-connection.js +39 -72
- package/dist/storage/repositories/index-entries-repository.js +131 -129
- package/dist/storage/repositories/index-entry-mapper.js +1 -2
- package/dist/storage/repositories/index-entry-schema.js +101 -268
- package/dist/storage/repositories/index-fts-repository.js +86 -256
- package/dist/storage/repositories/index-links-repository.js +143 -0
- package/dist/storage/repositories/index-llm-cache-repository.js +7 -9
- package/dist/storage/repositories/index-meta-repository.js +6 -4
- package/dist/storage/repositories/index-schema.js +257 -325
- package/dist/storage/repositories/index-utility-repository.js +8 -29
- package/dist/storage/repositories/index-vec-repository.js +133 -414
- package/dist/storage/repositories/outcome-repository.js +2 -1
- package/dist/storage/repositories/proposals-repository.js +104 -1
- package/dist/storage/repositories/registry-index-cache-repository.js +100 -0
- package/dist/storage/repositories/salience-repository.js +1 -19
- package/dist/storage/repositories/task-history-repository.js +26 -4
- package/dist/storage/repositories/workflow-runs-repository.js +53 -244
- package/dist/storage/sqlite-migrations.js +136 -0
- package/dist/storage/sqlite-pragmas.js +11 -9
- package/dist/storage/sqlite-transaction.js +170 -0
- package/dist/storage/state-db-integrity.js +130 -0
- package/dist/tasks/activation-config.js +134 -62
- package/dist/tasks/backends/cron.js +191 -302
- package/dist/tasks/backends/exec-utils.js +2 -5
- package/dist/tasks/backends/launchd.js +141 -748
- package/dist/tasks/backends/schtasks.js +119 -623
- package/dist/tasks/prepare/prepare-support.js +5 -15
- package/dist/tasks/prepare/prepare.js +0 -2
- package/dist/tasks/resolve-akm-bin.js +20 -79
- package/dist/tasks/run/attempt-lifecycle.js +0 -1
- package/dist/tasks/run/load-task.js +1 -1
- package/dist/tasks/scheduler-binding.js +20 -238
- package/dist/tasks/scheduler-invocation.js +136 -244
- package/dist/tasks/scheduler-lock.js +53 -0
- package/dist/tasks/scheduler-sync.js +368 -679
- package/dist/tasks/source/parse-task-source.js +55 -9
- package/dist/tasks/source/task-source-v3-frozen.js +3 -4
- package/dist/tasks/source/task-to-v4.js +464 -88
- package/dist/workflows/authoring/authoring.js +3 -12
- package/dist/workflows/compile.js +211 -0
- package/dist/workflows/concurrency-policy.js +13 -74
- package/dist/workflows/exec/child-invocation.js +3 -17
- package/dist/workflows/exec/child-workflow.js +32 -141
- package/dist/workflows/exec/dispatch-redaction.js +13 -53
- package/dist/workflows/exec/environment.js +98 -0
- package/dist/workflows/exec/exec-unit.js +33 -140
- package/dist/workflows/exec/frozen-judge.js +7 -59
- package/dist/workflows/exec/native-executor.js +82 -341
- package/dist/workflows/exec/param-secrets.js +29 -47
- package/dist/workflows/exec/run-workflow.js +154 -387
- package/dist/workflows/exec/scheduler.js +9 -36
- package/dist/workflows/exec/step-work.js +127 -430
- package/dist/workflows/exec/unit-dispatch.js +11 -63
- package/dist/workflows/exec/unit-writer.js +8 -52
- package/dist/workflows/exec/worktree.js +39 -273
- package/dist/workflows/freeze/child-output-references.js +4 -15
- package/dist/workflows/freeze/environment.js +99 -92
- package/dist/workflows/freeze/freeze.js +172 -0
- package/dist/workflows/freeze/step-values.js +19 -21
- package/dist/workflows/freeze/targets/child-workflow.js +23 -92
- package/dist/workflows/freeze/targets/command.js +10 -33
- package/dist/workflows/freeze/targets/script.js +5 -12
- package/dist/workflows/freeze/targets/shell.js +3 -6
- package/dist/workflows/freeze/targets/task.js +25 -80
- package/dist/workflows/freeze/task-bindings.js +20 -67
- package/dist/workflows/{source-ir/github-yaml.js → github-yaml.js} +88 -206
- package/dist/workflows/ir/params.js +6 -51
- package/dist/workflows/ir/plan-hash.js +2 -34
- package/dist/workflows/parser.js +140 -43
- package/dist/{commands/improve/consolidate/types.js → workflows/plan.js} +2 -1
- package/dist/workflows/renderer.js +36 -69
- package/dist/workflows/resource-limits.js +12 -120
- package/dist/workflows/runtime/agent-identity.js +8 -40
- package/dist/workflows/runtime/run-outputs.js +3 -6
- package/dist/workflows/runtime/run-plan.js +316 -0
- package/dist/workflows/runtime/runs.js +48 -200
- package/dist/workflows/runtime/workflow-asset-loader.js +24 -57
- package/dist/workflows/{source-ir/semantics.js → source-semantics.js} +16 -20
- package/dist/workflows/validate-summary.js +2 -7
- package/docs/integration/bundling-akm.md +49 -42
- package/docs/migration/README.md +1 -0
- package/docs/migration/release-notes/0.9.17.md +43 -0
- package/docs/migration/v0.9.1-to-v0.9.2.md +23 -7
- package/docs/reference/cli.md +232 -135
- package/docs/reference/configuration.md +71 -57
- package/docs/reference/data-and-telemetry.md +20 -21
- package/docs/reference/tasks.md +105 -39
- package/docs/reference/workflow-schema.md +14 -18
- package/docs/reference/workflows.md +6 -9
- package/package.json +1 -1
- package/schemas/akm-config.json +115 -738
- package/schemas/akm-workflow.json +1 -0
- package/dist/assets/improve-strategies/graph-refresh.json +0 -15
- package/dist/assets/prompts/contradiction-judge.md +0 -33
- package/dist/assets/prompts/graph-extract-system.md +0 -1
- package/dist/assets/prompts/graph-extract-user-prompt.md +0 -35
- package/dist/assets/prompts/metadata-enhance-system.md +0 -1
- package/dist/assets/tasks/improve/akm-graph-refresh-weekly.yml +0 -4
- package/dist/commands/health/advisories.js +0 -150
- package/dist/commands/health/metrics.js +0 -329
- package/dist/commands/health/surfaces.js +0 -102
- package/dist/commands/improve/anti-collapse.js +0 -83
- package/dist/commands/improve/collapse-detector.js +0 -432
- package/dist/commands/improve/consolidate/eligibility.js +0 -48
- package/dist/commands/improve/consolidate/merge.js +0 -149
- package/dist/commands/improve/distill/promote-memory.js +0 -291
- package/dist/commands/improve/distill/quality-gate.js +0 -337
- package/dist/commands/improve/eval-cases.js +0 -52
- package/dist/commands/improve/memory/memory-contradiction-detect.js +0 -291
- package/dist/commands/improve/proposal-envelope.js +0 -31
- package/dist/commands/improve/run-context.js +0 -123
- package/dist/commands/improve/shared.js +0 -31
- package/dist/commands/improve/source-identity.js +0 -28
- package/dist/commands/improve/triage.js +0 -96
- package/dist/commands/proposal/drain-policies.js +0 -151
- package/dist/commands/sources/update-transaction.js +0 -220
- package/dist/core/action-contributors.js +0 -28
- package/dist/core/config/config-version-shim.js +0 -101
- package/dist/core/fs-txn.js +0 -405
- package/dist/core/lexical-score.js +0 -25
- package/dist/core/maintenance-barrier.js +0 -167
- package/dist/execution/executable-identity.js +0 -105
- package/dist/execution/guarded-source.js +0 -427
- package/dist/indexer/db/graph-db.js +0 -444
- package/dist/indexer/graph/graph-boost.js +0 -427
- package/dist/indexer/graph/graph-dedup.js +0 -95
- package/dist/indexer/graph/graph-extraction.js +0 -1108
- package/dist/indexer/search/name-match.js +0 -35
- package/dist/indexer/search/ranking-contributors.js +0 -515
- package/dist/indexer/search/ranking-types.js +0 -4
- package/dist/indexer/walk/project-context.js +0 -192
- package/dist/integrations/agent/execution-cascade.js +0 -566
- package/dist/integrations/agent/execution-definitions.js +0 -202
- package/dist/integrations/agent/execution-lowering.js +0 -841
- package/dist/integrations/agent/execution-preparation.js +0 -98
- package/dist/integrations/agent/inline-execution.js +0 -74
- package/dist/llm/graph-extract.js +0 -728
- package/dist/llm/metadata-enhance.js +0 -96
- package/dist/registry/create-provider-registry.js +0 -29
- package/dist/registry/pinned-request-helper.js +0 -247
- package/dist/registry/pinned-transport.js +0 -717
- package/dist/sources/providers/index.js +0 -14
- package/dist/storage/engines/sqlite-migrations.js +0 -271
- package/dist/storage/repositories/canaries-repository.js +0 -107
- package/dist/storage/repositories/embedding-salvage-repository.js +0 -184
- package/dist/storage/repositories/registry-cache.js +0 -113
- package/dist/tasks/scheduler-sync-preview.js +0 -52
- package/dist/tasks/source/task-to-v3.js +0 -507
- package/dist/workflows/freeze/resolve-steps.js +0 -86
- package/dist/workflows/freeze/source-freeze.js +0 -64
- package/dist/workflows/ir/compile.js +0 -321
- package/dist/workflows/ir/environment-v4.js +0 -330
- package/dist/workflows/ir/freeze-v4.js +0 -153
- package/dist/workflows/ir/schema-v4.js +0 -745
- package/dist/workflows/ir/schema.js +0 -354
- package/dist/workflows/program/schema.js +0 -77
- package/dist/workflows/runtime/checkin.js +0 -57
- package/dist/workflows/runtime/plan-classifier.js +0 -196
- package/dist/workflows/runtime/unit-checkin.js +0 -45
- package/dist/workflows/runtime/unit-phases.js +0 -20
- package/dist/workflows/schema.js +0 -4
- package/dist/workflows/source-ir/compile.js +0 -200
- package/dist/workflows/source-ir/program.js +0 -50
- package/dist/workflows/source-ir/result.js +0 -26
- package/dist/workflows/source-ir/schema.js +0 -786
- package/dist/workflows/source-ir/triggers.js +0 -79
- package/dist/workflows/source-ir/uses.js +0 -40
- package/dist/workflows/validator.js +0 -60
|
@@ -2,42 +2,24 @@
|
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
4
|
/**
|
|
5
|
-
* The
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* OWN target is a workflow (`targets/task.ts`'s `taskDispatch`,
|
|
12
|
-
* `via: "task"`).
|
|
13
|
-
*
|
|
14
|
-
* `childWorkflowDispatch` resolves and qualifies the child ref, enforces the
|
|
15
|
-
* three composition bounds (depth, cycle, aggregate embedded bytes — all
|
|
16
|
-
* FREEZE-time, before publication, `COMPOSITION_INVALID`), recursively
|
|
17
|
-
* freezes the child COMPLETELY through the injected `ResolutionContext.freezeChild`
|
|
18
|
-
* (never a direct import of `compileResolveFreezeWorkflowV4` —
|
|
19
|
-
* `freeze/step-values.ts`'s `ChildCompositionContext` doc explains why: this
|
|
20
|
-
* module is downstream of `ir/freeze-v4.ts`, so importing back from it would
|
|
21
|
-
* close a static cycle), absorbs the child's own fresh source collector into
|
|
22
|
-
* the parent's (A-N7), binds the composing step's effective inputs against
|
|
23
|
-
* the child's declared `params:` (A-N8 — see `AuthoredChildInputs` below for
|
|
24
|
-
* the two ways that mapping arrives), and returns the standard
|
|
25
|
-
* `ResolvedDispatch` envelope carrying a `FrozenChildWorkflowTarget`
|
|
26
|
-
* (`ir/schema-v4.ts`).
|
|
5
|
+
* The one child-workflow resolver. Both composition forms lower here: a direct
|
|
6
|
+
* `uses: workflows/<ref>` step (`via: "direct"`) and a `uses: tasks/<ref>`
|
|
7
|
+
* step whose task targets a workflow (`via: "task"`). It resolves the child,
|
|
8
|
+
* refuses a composition cycle, freezes the child completely through the
|
|
9
|
+
* injected `ResolutionContext.freezeChild`, binds the step's inputs against
|
|
10
|
+
* the child's `params:`, and embeds the frozen child plan in the target.
|
|
27
11
|
*/
|
|
28
12
|
import { createHash } from "node:crypto";
|
|
29
13
|
import { parseBundleRef } from "../../../core/asset/asset-ref.js";
|
|
30
14
|
import { UsageError } from "../../../core/errors.js";
|
|
31
15
|
import { warn } from "../../../core/warn.js";
|
|
32
|
-
import { GuardedExecutionSourceCollector } from "../../../execution/guarded-source.js";
|
|
33
16
|
import { workflowParamContract } from "../../ir/params.js";
|
|
34
17
|
import { canonicalJson, canonicalPlanJson } from "../../ir/plan-hash.js";
|
|
35
|
-
import { utf8Bytes } from "../../resource-limits.js";
|
|
36
18
|
import { loadWorkflowAsset } from "../../runtime/workflow-asset-loader.js";
|
|
37
19
|
import { resolveOwnedAsset } from "../environment.js";
|
|
38
|
-
import { declaredParamNames, earlierStepIds } from "../step-values.js";
|
|
20
|
+
import { declaredParamNames, earlierStepIds, } from "../step-values.js";
|
|
39
21
|
import { freezeTaskInputBindings, rebindTaskInputBindings } from "../task-bindings.js";
|
|
40
|
-
/**
|
|
22
|
+
/** The child target's own content identity: its ref, embedded plan hash, route, and bindings. */
|
|
41
23
|
function childWorkflowContentHash(fields) {
|
|
42
24
|
return createHash("sha256")
|
|
43
25
|
.update("akm.workflow.child-workflow\0v1\0")
|
|
@@ -50,19 +32,7 @@ function childWorkflowContentHash(fields) {
|
|
|
50
32
|
}))
|
|
51
33
|
.digest("hex");
|
|
52
34
|
}
|
|
53
|
-
/**
|
|
54
|
-
* Code-review finding (see this file's `environment: []` return field): a
|
|
55
|
-
* step composing a child workflow has no path to honor its own authored
|
|
56
|
-
* `env:` — the child run carries its own frozen environment inside its own
|
|
57
|
-
* plan, so `freezeEnvironment` (the ONE mechanism a step's `env:` reaches a
|
|
58
|
-
* frozen unit through, `../environment.ts`) is never called for this
|
|
59
|
-
* target. Leaving that silent would repeat exactly the defect A-N5 already
|
|
60
|
-
* closed for `with:` on a non-binding surface — an authored construct that
|
|
61
|
-
* cannot be honored on this composing target now rejects instead of
|
|
62
|
-
* vanishing. Checks BOTH shapes a step's `env:` can take (`../environment.ts`'s
|
|
63
|
-
* `freezeEnvironment`): literal `env:` values and `unit: {env: [...]}` refs.
|
|
64
|
-
* An absent/empty `env:` is not authored and stays valid.
|
|
65
|
-
*/
|
|
35
|
+
/** A composing step's own `env:` (literal or `unit.env`) cannot reach the child run, so say so. */
|
|
66
36
|
function warnIfStepEnvironment(stepId, childRef, source) {
|
|
67
37
|
const hasLiteralEnv = Object.keys(source.env ?? {}).length > 0;
|
|
68
38
|
const hasEnvRefs = (source.unit?.env ?? []).length > 0;
|
|
@@ -72,7 +42,7 @@ function warnIfStepEnvironment(stepId, childRef, source) {
|
|
|
72
42
|
`environment inside its own plan, so this composing step's env: (or unit: env:) is not delivered into it ` +
|
|
73
43
|
`and has no effect. Set those variables inside ${childRef}'s own source instead.`);
|
|
74
44
|
}
|
|
75
|
-
/** A workflow entry of a composition `refPath` — the only entries a cycle can close through
|
|
45
|
+
/** A workflow entry of a composition `refPath` — the only entries a cycle can close through. */
|
|
76
46
|
function isWorkflowRef(ref) {
|
|
77
47
|
try {
|
|
78
48
|
return parseBundleRef(ref).conceptId.startsWith("workflows/");
|
|
@@ -91,20 +61,10 @@ function assertNoCompositionCycle(stepId, childRef, refPath) {
|
|
|
91
61
|
`Path: ${compositionPath(refPath, childRef)}.`, "COMPOSITION_INVALID", "Break the cycle: remove or redirect one of the compositions in the path above so no workflow ends up " +
|
|
92
62
|
"composing itself, directly or through intermediates.");
|
|
93
63
|
}
|
|
94
|
-
/**
|
|
95
|
-
* Add the child's embedded plan bytes to the shared, tree-wide budget
|
|
96
|
-
* (A-N6) and fail before publication if the AGGREGATE crosses the cap.
|
|
97
|
-
* Mutates `budget` only on success — a rejected step leaves the running
|
|
98
|
-
* total exactly as it was, matching every other freeze-time failure's
|
|
99
|
-
* no-partial-effect shape.
|
|
100
|
-
*/
|
|
101
|
-
function chargeEmbeddedBudget(_stepId, _childRef, childPlanBytes, budget) {
|
|
102
|
-
budget.embeddedBytes += childPlanBytes;
|
|
103
|
-
}
|
|
104
64
|
export async function childWorkflowDispatch(input) {
|
|
105
65
|
const { source, baseUnit, childRefInput, context, via, taskRef, authoredInputs } = input;
|
|
106
|
-
//
|
|
107
|
-
// in code and shape
|
|
66
|
+
// resolve + qualify. Resolution failures propagate unchanged,
|
|
67
|
+
// in code and shape — the same authority every other
|
|
108
68
|
// composition target (command/script/task) already resolves through.
|
|
109
69
|
const owned = await resolveOwnedAsset(childRefInput, "workflow", context);
|
|
110
70
|
const childAsset = await loadWorkflowAsset(owned.ref);
|
|
@@ -113,44 +73,15 @@ export async function childWorkflowDispatch(input) {
|
|
|
113
73
|
// the child run — warn rather than vanish silently (see
|
|
114
74
|
// warnIfStepEnvironment's doc comment).
|
|
115
75
|
warnIfStepEnvironment(source.id, childRef, source);
|
|
116
|
-
//
|
|
117
|
-
assertNoCompositionCycle(source.id, childRef, context.
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
//
|
|
122
|
-
// sees every descendant across the whole tree.
|
|
123
|
-
const childRefPath = via === "task" && taskRef !== undefined
|
|
124
|
-
? [...context.composition.refPath, taskRef, childRef]
|
|
125
|
-
: [...context.composition.refPath, childRef];
|
|
126
|
-
const child = await context.freezeChild({
|
|
127
|
-
asset: childAsset,
|
|
128
|
-
sourceCollector: new GuardedExecutionSourceCollector(),
|
|
129
|
-
composition: { depth: childDepth, refPath: childRefPath, budget: context.composition.budget },
|
|
130
|
-
});
|
|
131
|
-
// The embedded `frozenPlan` must be a PLAIN, symbol-free JSON structure —
|
|
132
|
-
// exactly the shape `decodeWorkflowPlanV4` will (recursively) re-verify it
|
|
133
|
-
// as, both right now (the PARENT's own top-level `decodeWorkflowPlanV4`
|
|
134
|
-
// call in `ir/freeze-v4.ts` walks straight into this target) and later,
|
|
135
|
-
// read back from a stored run's `plan_json`. `child.plan` — the in-memory
|
|
136
|
-
// result of the child's OWN already-decoded freeze — carries internal
|
|
137
|
-
// resolved-request construction brands (`execution/resolved-request.ts`)
|
|
138
|
-
// that `decodeResolvedExecutionRequest` deliberately rejects on ANY
|
|
139
|
-
// "fresh rehydrate" input; round-tripping through canonical JSON strips
|
|
140
|
-
// them, the same way persisting and re-reading `plan_json` naturally would.
|
|
76
|
+
// the composition cycle check, before any child compilation.
|
|
77
|
+
assertNoCompositionCycle(source.id, childRef, context.refPath);
|
|
78
|
+
// Freeze the child completely; its plan is a pure function of its own source.
|
|
79
|
+
const childRefPath = via === "task" && taskRef !== undefined ? [...context.refPath, taskRef, childRef] : [...context.refPath, childRef];
|
|
80
|
+
const child = await context.freezeChild(childAsset, childRefPath);
|
|
81
|
+
// Embed the child plan as plain canonical JSON, exactly as `plan_json` stores it.
|
|
141
82
|
const embeddedPlanJson = canonicalPlanJson(child.plan);
|
|
142
83
|
const frozenPlan = JSON.parse(embeddedPlanJson);
|
|
143
|
-
//
|
|
144
|
-
chargeEmbeddedBudget(source.id, childRef, utf8Bytes(embeddedPlanJson), context.composition.budget);
|
|
145
|
-
// §4.2 step 6 (A-N7): absorb the child's captured sources so the parent's
|
|
146
|
-
// final pre-publication CAS (`revalidate()`) covers every child file too.
|
|
147
|
-
context.collector.absorb(child.sourceCollector);
|
|
148
|
-
// §4.2 step 7 (A-N8): bind the composing step's effective inputs against
|
|
149
|
-
// the child's declared params:. A genuinely authored `with:` goes through
|
|
150
|
-
// the SAME normalizer every other binding surface uses; an
|
|
151
|
-
// already-classified binding set (a v4 task's effective inputs) is
|
|
152
|
-
// RE-bound instead, never round-tripped back through the `with:` grammar
|
|
153
|
-
// (code-review finding — see AuthoredChildInputs above).
|
|
84
|
+
// Bind the step's effective inputs against the child's declared params.
|
|
154
85
|
const inputBindings = authoredInputs.kind === "bindings"
|
|
155
86
|
? rebindTaskInputBindings({
|
|
156
87
|
stepId: source.id,
|
|
@@ -163,10 +94,10 @@ export async function childWorkflowDispatch(input) {
|
|
|
163
94
|
targetRef: childRef,
|
|
164
95
|
with: authoredInputs.value,
|
|
165
96
|
contract: workflowParamContract(frozenPlan),
|
|
166
|
-
earlierStepIds: earlierStepIds(context.
|
|
167
|
-
declaredParamNames: declaredParamNames(context.
|
|
97
|
+
earlierStepIds: earlierStepIds(context.plan, source.id),
|
|
98
|
+
declaredParamNames: declaredParamNames(context.plan),
|
|
168
99
|
});
|
|
169
|
-
//
|
|
100
|
+
// build the frozen target.
|
|
170
101
|
const planHash = createHash("sha256").update(embeddedPlanJson).digest("hex");
|
|
171
102
|
const contentHash = childWorkflowContentHash({ ref: childRef, planHash, via, taskRef, inputBindings });
|
|
172
103
|
const target = Object.freeze({
|
|
@@ -183,7 +114,7 @@ export async function childWorkflowDispatch(input) {
|
|
|
183
114
|
target,
|
|
184
115
|
// A child run carries its own frozen environment inside its own plan.
|
|
185
116
|
// A composing step's own env: cannot reach it, so assertNoStepEnvironment
|
|
186
|
-
// above rejects one instead of it silently vanishing here
|
|
117
|
+
// above rejects one instead of it silently vanishing here.
|
|
187
118
|
environment: [],
|
|
188
119
|
unit: baseUnit,
|
|
189
120
|
instructions: source.instructions ??
|
|
@@ -6,15 +6,12 @@ import { parseBuiltinCommandAction } from "../../../commands/command/builtin-act
|
|
|
6
6
|
import { prepareCommandInvocation } from "../../../commands/command/command-execution.js";
|
|
7
7
|
import { PORTABLE_ARGUMENTS_PLACEHOLDER } from "../../../commands/command/portable-template.js";
|
|
8
8
|
import { captureFrozenDirectoryIdentity } from "../../../execution/directory-identity.js";
|
|
9
|
-
import { freezeExecutableIdentity } from "../../../execution/executable-identity.js";
|
|
10
9
|
import { canonicalResolvedExecutionRequest, } from "../../../execution/resolved-request.js";
|
|
11
10
|
import { fallbackAnnouncement } from "../../../integrations/agent/engine-fallback.js";
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import { prepareInlineExecution } from "../../../integrations/agent/inline-execution.js";
|
|
15
|
-
import { freezeEnvironment, guardedExecutionSource } from "../environment.js";
|
|
11
|
+
import { buildExecution } from "../../../integrations/agent/execution.js";
|
|
12
|
+
import { freezeEnvironment, workflowExecutionSource } from "../environment.js";
|
|
16
13
|
import { gitIdentity } from "../identity.js";
|
|
17
|
-
import { durableRequest, executionUnitValues,
|
|
14
|
+
import { durableRequest, executionUnitValues, targetConcurrency, } from "../step-values.js";
|
|
18
15
|
function inlineWorkflowCommandAction(action, commandMode) {
|
|
19
16
|
if (commandMode !== "portable-template")
|
|
20
17
|
return action;
|
|
@@ -27,41 +24,22 @@ export async function commandDispatch(source, baseUnit, action, context) {
|
|
|
27
24
|
const prepared = await prepareCommandInvocation({
|
|
28
25
|
action: inlineWorkflowCommandAction(action, source.commandMode),
|
|
29
26
|
config: context.config,
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
? { invocationDefaults: executionUnitValues(context.sourceIr.defaults, context.asset.sourcePath) }
|
|
27
|
+
...(context.plan.defaults
|
|
28
|
+
? { invocationDefaults: executionUnitValues(context.plan.defaults, context.asset.sourcePath) }
|
|
33
29
|
: {}),
|
|
34
30
|
...(source.commandMode === "literal" || source.commandMode === "portable-template"
|
|
35
31
|
? { inlineContentMode: "literal" }
|
|
36
32
|
: {}),
|
|
37
|
-
current:
|
|
38
|
-
sourceLoader: (ref, kind) =>
|
|
39
|
-
});
|
|
40
|
-
return commandResult(source, baseUnit, prepared, context);
|
|
41
|
-
}
|
|
42
|
-
export function inlineDispatch(source, baseUnit, context) {
|
|
43
|
-
const content = source.instructions ?? `Execute workflow step ${source.id}.`;
|
|
44
|
-
const prepared = prepareInlineExecution({
|
|
45
|
-
content,
|
|
46
|
-
config: context.config,
|
|
47
|
-
invocationKind: "workflow",
|
|
48
|
-
...(context.sourceIr.defaults
|
|
49
|
-
? { invocationDefaults: executionUnitValues(context.sourceIr.defaults, context.asset.sourcePath) }
|
|
50
|
-
: {}),
|
|
51
|
-
current: executionValues(source, context.asset.sourcePath),
|
|
33
|
+
current: executionUnitValues(source.unit, context.asset.sourcePath),
|
|
34
|
+
sourceLoader: (ref, kind) => workflowExecutionSource(ref, kind, context),
|
|
52
35
|
});
|
|
53
36
|
return commandResult(source, baseUnit, prepared, context);
|
|
54
37
|
}
|
|
55
38
|
export function commandResult(source, baseUnit, prepared, context, literals = []) {
|
|
56
|
-
const request = durableRequest(
|
|
57
|
-
const lowered =
|
|
39
|
+
const request = durableRequest(prepared.request);
|
|
40
|
+
const lowered = buildExecution(request, prepared.runner);
|
|
58
41
|
const cwdIdentity = captureFrozenDirectoryIdentity(context.asset.sourcePath);
|
|
59
|
-
|
|
60
|
-
let executable;
|
|
61
|
-
if (runner.kind === "agent") {
|
|
62
|
-
executable = freezeExecutableIdentity(runner.profile.bin, { cwd: cwdIdentity.realCwd });
|
|
63
|
-
runner = Object.freeze({ ...runner, profile: Object.freeze({ ...runner.profile, bin: executable.absolutePath }) });
|
|
64
|
-
}
|
|
42
|
+
const runner = lowered.runner;
|
|
65
43
|
const unit = {
|
|
66
44
|
...baseUnit,
|
|
67
45
|
engine: request.engine.name,
|
|
@@ -79,7 +57,6 @@ export function commandResult(source, baseUnit, prepared, context, literals = []
|
|
|
79
57
|
runner,
|
|
80
58
|
...(targetConcurrency(runner, context.config) ? { concurrency: targetConcurrency(runner, context.config) } : {}),
|
|
81
59
|
cwdIdentity,
|
|
82
|
-
...(executable ? { executable } : {}),
|
|
83
60
|
...gitIdentity(baseUnit, cwdIdentity.realRoot),
|
|
84
61
|
});
|
|
85
62
|
const engineAnnouncement = fallbackAnnouncement(prepared.fallbackEngineName, request.engine.name);
|
|
@@ -1,22 +1,18 @@
|
|
|
1
1
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
-
import
|
|
4
|
+
import fs from "node:fs";
|
|
5
5
|
import { prepareScriptTarget } from "../../../tasks/prepare/prepare-script-target.js";
|
|
6
|
-
import {
|
|
6
|
+
import { freezeEnvironment, resolveOwnedAsset } from "../environment.js";
|
|
7
7
|
import { gitIdentity, scriptExecutable } from "../identity.js";
|
|
8
|
-
import { freezeExecSpec } from "../step-values.js";
|
|
8
|
+
import { freezeExecSpec, } from "../step-values.js";
|
|
9
9
|
export async function directScript(source, baseUnit, refInput, context) {
|
|
10
10
|
const owned = await resolveOwnedAsset(refInput, "script", context);
|
|
11
|
-
captureOwned(owned, context.collector);
|
|
12
|
-
// Typed preparer (P1b spec §4.3) — no synthetic task YAML, no parseTaskV3Yaml
|
|
13
|
-
// call, no fabricated schedule/filePath/taskId/taskRef. The script's own
|
|
14
|
-
// owned identity (ref/file/bundleRoot) is all prepareScriptTarget needs.
|
|
15
11
|
const captured = prepareScriptTarget({
|
|
16
12
|
ref: owned.ref,
|
|
17
13
|
file: owned.file,
|
|
18
14
|
bundleRoot: owned.root,
|
|
19
|
-
readFile: () =>
|
|
15
|
+
readFile: () => fs.readFileSync(owned.file),
|
|
20
16
|
});
|
|
21
17
|
return scriptResult(source, baseUnit, {
|
|
22
18
|
sourceRef: captured.ref,
|
|
@@ -29,9 +25,7 @@ export async function directScript(source, baseUnit, refInput, context) {
|
|
|
29
25
|
}, context, []);
|
|
30
26
|
}
|
|
31
27
|
export function scriptResult(source, baseUnit, prepared, context, literals) {
|
|
32
|
-
const
|
|
33
|
-
const executable = freezeExecutableIdentity(requestedExecutable, { cwd: prepared.cwdIdentity.realCwd });
|
|
34
|
-
const authoredExec = { command: [executable.absolutePath, "<frozen-script>"] };
|
|
28
|
+
const authoredExec = { command: [scriptExecutable(prepared.interpreter), "<frozen-script>"] };
|
|
35
29
|
const exec = freezeExecSpec(source, authoredExec, context);
|
|
36
30
|
const environment = Object.freeze([...literals, ...freezeEnvironment(source, authoredExec, context)]);
|
|
37
31
|
const target = Object.freeze({
|
|
@@ -45,7 +39,6 @@ export function scriptResult(source, baseUnit, prepared, context, literals) {
|
|
|
45
39
|
byteLength: prepared.byteLength,
|
|
46
40
|
cwdIdentity: prepared.cwdIdentity,
|
|
47
41
|
materialization: "ephemeral-0700-delete",
|
|
48
|
-
executable,
|
|
49
42
|
...gitIdentity(baseUnit, prepared.cwdIdentity.realRoot),
|
|
50
43
|
});
|
|
51
44
|
return {
|
|
@@ -2,30 +2,27 @@
|
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
4
|
import { captureFrozenDirectoryIdentity } from "../../../execution/directory-identity.js";
|
|
5
|
-
import { freezeExecutableIdentity } from "../../../execution/executable-identity.js";
|
|
6
5
|
import { freezeEnvironment } from "../environment.js";
|
|
7
6
|
import { gitIdentity } from "../identity.js";
|
|
8
|
-
import { freezeExecSpec } from "../step-values.js";
|
|
7
|
+
import { freezeExecSpec, } from "../step-values.js";
|
|
9
8
|
export function directShell(source, baseUnit, context) {
|
|
10
9
|
const authoredExec = baseUnit.exec;
|
|
11
10
|
if (!authoredExec)
|
|
12
|
-
throw new Error(`workflow shell step ${source.id}
|
|
11
|
+
throw new Error(`workflow shell step ${source.id} has no argv`);
|
|
13
12
|
const exec = freezeExecSpec(source, authoredExec, context);
|
|
14
13
|
const cwdIdentity = captureFrozenDirectoryIdentity(context.asset.sourcePath, authoredExec.cwd);
|
|
15
|
-
const executable = freezeExecutableIdentity(authoredExec.command[0], { cwd: cwdIdentity.realCwd });
|
|
16
14
|
const environment = Object.freeze(freezeEnvironment(source, authoredExec, context));
|
|
17
15
|
const target = Object.freeze({
|
|
18
16
|
kind: "shell",
|
|
19
17
|
contentHash: "",
|
|
20
18
|
exec,
|
|
21
19
|
cwdIdentity,
|
|
22
|
-
executable,
|
|
23
20
|
...gitIdentity(baseUnit, cwdIdentity.realRoot),
|
|
24
21
|
});
|
|
25
22
|
return {
|
|
26
23
|
target,
|
|
27
24
|
environment,
|
|
28
25
|
unit: { ...baseUnit, exec },
|
|
29
|
-
instructions: source.instructions ?? `Run ${
|
|
26
|
+
instructions: source.instructions ?? `Run ${authoredExec.command.join(" ")}.`,
|
|
30
27
|
};
|
|
31
28
|
}
|
|
@@ -1,101 +1,60 @@
|
|
|
1
1
|
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
2
|
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
+
import fs from "node:fs";
|
|
4
5
|
import path from "node:path";
|
|
5
6
|
import { parseBundleRef } from "../../../core/asset/asset-ref.js";
|
|
6
7
|
import { UsageError } from "../../../core/errors.js";
|
|
7
|
-
import { freezeExecutableIdentity } from "../../../execution/executable-identity.js";
|
|
8
8
|
import { prepareTaskV3Execution } from "../../../tasks/prepare/prepare.js";
|
|
9
9
|
import { parseTaskSource } from "../../../tasks/source/parse-task-source.js";
|
|
10
10
|
import { projectTaskSourceV4 } from "../../../tasks/source/project-v4.js";
|
|
11
|
-
import { workflowShellCommand } from "../../source-
|
|
12
|
-
import {
|
|
11
|
+
import { workflowShellCommand } from "../../source-semantics.js";
|
|
12
|
+
import { freezeEnvironment, resolveOwnedAsset, workflowExecutionSource } from "../environment.js";
|
|
13
13
|
import { gitIdentity } from "../identity.js";
|
|
14
14
|
import { declaredParamNames, earlierStepIds, freezeExecSpec, } from "../step-values.js";
|
|
15
15
|
import { freezeTaskInputBindings } from "../task-bindings.js";
|
|
16
16
|
import { childWorkflowDispatch } from "./child-workflow.js";
|
|
17
17
|
import { commandResult } from "./command.js";
|
|
18
18
|
import { scriptResult } from "./script.js";
|
|
19
|
-
/** The
|
|
19
|
+
/** The rejection for a `with:` on a task that declares no inputs (or does not resolve). */
|
|
20
20
|
function noDeclaredInputsError(stepId, ref) {
|
|
21
21
|
return new UsageError(`Workflow step ${stepId} cannot pass with: to task target ${ref}; ${ref} declares no inputs.`, "COMPOSITION_INVALID");
|
|
22
22
|
}
|
|
23
23
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
* (B-07, B-08). `contract` is undefined for a v3 task (which can never
|
|
29
|
-
* declare `inputs:`, P2a §1.2 D2) or a v4 task with no `inputs:` key at all —
|
|
30
|
-
* either way, "no declared inputs" (A-N5).
|
|
31
|
-
*
|
|
32
|
-
* RECORDED TENSION (spec §0, Review log): A-N5's "no declared inputs"
|
|
33
|
-
* rejection is reasoned from the target's PARSED `inputs:` contract, which
|
|
34
|
-
* needs the target to resolve — yet `tests/workflows/with-rejection.test.ts`
|
|
35
|
-
* B-02b pins `COMPOSITION_INVALID` (not an asset-resolution error) for an
|
|
36
|
-
* UNRESOLVABLE task ref with an authored `with:`. Reconciled here: an
|
|
37
|
-
* authored `with:` whose target cannot even be resolved/parsed "cannot be
|
|
38
|
-
* proven a valid binding surface", so it is refused the same
|
|
39
|
-
* no-declared-inputs way — a `with:`-free step's resolution failure is
|
|
40
|
-
* untouched and propagates as before.
|
|
41
|
-
*
|
|
42
|
-
* Code-review finding: that reconciliation must stay scoped to ASSET
|
|
43
|
-
* resolution (`resolveOwnedAsset`/`captureOwned`) only. Once the target
|
|
44
|
-
* resolves to a real file, `parseTaskSource`/`projectTaskSourceV4` reports a
|
|
45
|
-
* genuine, path-and-line-anchored defect in the composed task's OWN source
|
|
46
|
-
* (e.g. `TASK_SOURCE_INVALID` for an unsupported `inputs.<name>` field) —
|
|
47
|
-
* that is never "cannot be proven a valid binding surface" and must not be
|
|
48
|
-
* repainted as `noDeclaredInputsError`. Parsing therefore happens OUTSIDE
|
|
49
|
-
* the try/catch below, so its errors propagate unchanged regardless of
|
|
50
|
-
* whether this step authored a `with:`.
|
|
24
|
+
* Resolve and parse the composed task. An authored `with:` whose target does
|
|
25
|
+
* not even resolve cannot be proven a valid binding surface, so it is refused
|
|
26
|
+
* the same no-declared-inputs way; a genuine defect in the resolved task's own
|
|
27
|
+
* source propagates unchanged.
|
|
51
28
|
*/
|
|
52
29
|
async function resolveTaskForComposition(source, refInput, context) {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
const contract = parsed.v4.inputs;
|
|
56
|
-
const task = projectTaskSourceV4(parsed.v4);
|
|
57
|
-
return { owned, task, contract };
|
|
58
|
-
}
|
|
59
|
-
/** The asset-resolution-only half of {@link resolveTaskForComposition} — the sole failure mode an authored `with:` on an unresolvable ref may repaint as `noDeclaredInputsError` (A-N5's `with-rejection.test.ts` B-02b). */
|
|
60
|
-
async function resolveAndCaptureTaskAsset(source, refInput, context) {
|
|
30
|
+
let owned;
|
|
31
|
+
let yaml;
|
|
61
32
|
try {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
return { owned, retained };
|
|
33
|
+
owned = await resolveOwnedAsset(refInput, "task", context);
|
|
34
|
+
yaml = fs.readFileSync(owned.file, "utf8");
|
|
65
35
|
}
|
|
66
36
|
catch (cause) {
|
|
67
37
|
if (source.with !== undefined)
|
|
68
38
|
throw noDeclaredInputsError(source.id, refInput);
|
|
69
39
|
throw cause;
|
|
70
40
|
}
|
|
41
|
+
const parsed = parseTaskSource({ yaml, filePath: owned.file, workspaceRoot: owned.root });
|
|
42
|
+
return { owned, task: projectTaskSourceV4(parsed.v4), contract: parsed.v4.inputs };
|
|
71
43
|
}
|
|
72
44
|
export async function taskDispatch(source, baseUnit, refInput, context) {
|
|
73
45
|
const { owned, task, contract } = await resolveTaskForComposition(source, refInput, context);
|
|
74
|
-
//
|
|
75
|
-
// COMPOSITION_INVALID. Fires on ANY authored with: shape, including `{}`
|
|
76
|
-
// (the check is `!== undefined`, not "non-empty").
|
|
46
|
+
// Any authored `with:` (even `{}`) on a task that declares no inputs is COMPOSITION_INVALID.
|
|
77
47
|
if (source.with !== undefined && contract === undefined) {
|
|
78
48
|
throw noDeclaredInputsError(source.id, refInput);
|
|
79
49
|
}
|
|
80
|
-
//
|
|
81
|
-
// whose OWN target is `uses: workflows/<ref>` used to fast-fail here,
|
|
82
|
-
// before ever calling prepareTaskV3Execution. That rejection is REMOVED —
|
|
83
|
-
// flow continues to the bindings computation and the prepare call exactly
|
|
84
|
-
// as for any other task target, and `prepared.kind === "workflow"` below
|
|
85
|
-
// routes to the ONE child-workflow resolver instead.
|
|
86
|
-
// Lane A2 (§3.2-§3.5): normalize THIS step's own with: against THIS task's
|
|
87
|
-
// OWN declared inputs — no merge across a composition chain (B-29). A task
|
|
88
|
-
// with no inputs: has contract === undefined, so an empty {} contract is
|
|
89
|
-
// used; freezeTaskInputBindings then produces no bindings for it (there is
|
|
90
|
-
// nothing to bind, and the COMPOSITION_INVALID check above already fired
|
|
91
|
-
// for any authored with:).
|
|
50
|
+
// This step's own `with:` against this task's own declared inputs (none → no bindings).
|
|
92
51
|
const bindings = freezeTaskInputBindings({
|
|
93
52
|
stepId: source.id,
|
|
94
53
|
targetRef: refInput,
|
|
95
54
|
with: source.with,
|
|
96
55
|
contract: contract ?? {},
|
|
97
|
-
earlierStepIds: earlierStepIds(context.
|
|
98
|
-
declaredParamNames: declaredParamNames(context.
|
|
56
|
+
earlierStepIds: earlierStepIds(context.plan, source.id),
|
|
57
|
+
declaredParamNames: declaredParamNames(context.plan),
|
|
99
58
|
});
|
|
100
59
|
const prepared = await prepareTaskV3Execution(task, {
|
|
101
60
|
taskId: parseBundleRef(owned.ref).conceptId.slice("tasks/".length),
|
|
@@ -103,30 +62,18 @@ export async function taskDispatch(source, baseUnit, refInput, context) {
|
|
|
103
62
|
bundleName: owned.bundle,
|
|
104
63
|
bundleRoot: owned.root,
|
|
105
64
|
config: context.config,
|
|
106
|
-
commandSourceLoader: (ref, kind) =>
|
|
65
|
+
commandSourceLoader: (ref, kind) => workflowExecutionSource(ref, kind, context),
|
|
107
66
|
resolveAsset: async ({ ref, type }) => {
|
|
108
67
|
const target = await resolveOwnedAsset(ref, type, context);
|
|
109
|
-
captureOwned(target, context.collector);
|
|
110
68
|
return { file: target.file, bundleRoot: target.root };
|
|
111
69
|
},
|
|
112
|
-
readFile: (file, root = owned.root) => context.collector.readBytes(file, root),
|
|
113
70
|
});
|
|
114
71
|
if (prepared.kind === "workflow") {
|
|
115
|
-
//
|
|
116
|
-
//
|
|
117
|
-
//
|
|
118
|
-
//
|
|
119
|
-
//
|
|
120
|
-
// contract — to be RE-bound against the child's declared `params:`
|
|
121
|
-
// (never round-tripped through the `with:` grammar: doing so would let a
|
|
122
|
-
// literal value shaped like `{from: ...}` be silently reinterpreted as a
|
|
123
|
-
// reference, code-review finding). Task source v4 rejects `with:` on any
|
|
124
|
-
// target but `uses: akm/command` (row B-28), so a workflow-target task
|
|
125
|
-
// can no longer author `with:` at all — the `{kind:"with"}` arm this
|
|
126
|
-
// ternary used to reach for a v3 task, or a v4 task with no `inputs:`,
|
|
127
|
-
// is unreachable from here and deleted (P4 §3.2.7, row B-30).
|
|
128
|
-
// `AuthoredChildInputs`'s `{kind:"with"}` member itself stays — the
|
|
129
|
-
// DIRECT composition path (`resolve-steps.ts`) still produces it.
|
|
72
|
+
// A task whose own target is a workflow composes it as a child. This
|
|
73
|
+
// task's effective inputs, already classified against its own contract,
|
|
74
|
+
// are re-bound against the child's `params:` — never round-tripped through
|
|
75
|
+
// the `with:` grammar, which would reinterpret a literal shaped like
|
|
76
|
+
// `{from: ...}` as a reference.
|
|
130
77
|
return childWorkflowDispatch({
|
|
131
78
|
source,
|
|
132
79
|
baseUnit,
|
|
@@ -150,13 +97,11 @@ export async function taskDispatch(source, baseUnit, refInput, context) {
|
|
|
150
97
|
};
|
|
151
98
|
const exec = freezeExecSpec(source, authoredExec, context);
|
|
152
99
|
const environment = Object.freeze([...taskLiterals, ...freezeEnvironment(source, authoredExec, context)]);
|
|
153
|
-
const executable = freezeExecutableIdentity(exec.command[0], { cwd: prepared.cwdIdentity.realCwd });
|
|
154
100
|
const target = Object.freeze({
|
|
155
101
|
kind: "shell",
|
|
156
102
|
contentHash: "",
|
|
157
103
|
exec,
|
|
158
104
|
cwdIdentity: prepared.cwdIdentity,
|
|
159
|
-
executable,
|
|
160
105
|
...gitIdentity(baseUnit, prepared.cwdIdentity.realRoot),
|
|
161
106
|
});
|
|
162
107
|
return withInputBindings({
|
|
@@ -168,7 +113,7 @@ export async function taskDispatch(source, baseUnit, refInput, context) {
|
|
|
168
113
|
}
|
|
169
114
|
return withInputBindings(scriptResult(source, baseUnit, prepared, context, taskLiterals), bindings);
|
|
170
115
|
}
|
|
171
|
-
/** Attach the frozen inputBindings
|
|
116
|
+
/** Attach the frozen inputBindings to whichever target shape taskDispatch produced. Absent, never [], when empty. */
|
|
172
117
|
function withInputBindings(resolved, bindings) {
|
|
173
118
|
if (bindings.length === 0)
|
|
174
119
|
return resolved;
|