akm-cli 0.9.17-alpha.3 → 0.9.17-alpha.4
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 +731 -0
- package/dist/akm +94 -196
- package/dist/cli/shared.js +6 -2
- package/dist/cli.js +22 -9
- 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 +2 -2
- package/dist/commands/health/checks.js +30 -75
- package/dist/commands/health/config-skew.js +38 -0
- package/dist/commands/health/egress.js +54 -0
- package/dist/commands/health/html-report.js +0 -38
- package/dist/commands/health/improve-metrics.js +123 -562
- 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 +11 -106
- package/dist/commands/health/types-improve.js +4 -19
- package/dist/commands/health/windows.js +64 -73
- package/dist/commands/health.js +122 -143
- package/dist/commands/improve/consolidate/chunking.js +25 -100
- package/dist/commands/improve/consolidate/sanitize.js +54 -149
- package/dist/commands/improve/consolidate.js +538 -1075
- 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 -1075
- package/dist/commands/improve/eligibility.js +126 -400
- package/dist/commands/improve/execution.js +3 -5
- package/dist/commands/improve/extract.js +487 -1046
- package/dist/commands/improve/feedback-valence.js +0 -25
- package/dist/commands/improve/improve-cli.js +29 -166
- package/dist/commands/improve/improve-result-file.js +10 -66
- package/dist/commands/improve/improve-strategies.js +12 -7
- package/dist/commands/improve/improve-usage-report.js +18 -64
- package/dist/commands/improve/improve.js +443 -1063
- package/dist/commands/improve/ledger.js +114 -0
- package/dist/commands/improve/locks.js +2 -8
- package/dist/commands/improve/loop-stages.js +459 -1172
- package/dist/commands/improve/memory/derived-ref.js +12 -77
- package/dist/commands/improve/memory/memory-belief.js +14 -118
- package/dist/commands/improve/memory/memory-improve.js +4 -3
- package/dist/commands/improve/outcome-loop.js +28 -156
- package/dist/commands/improve/planner.js +5 -10
- package/dist/commands/improve/preparation.js +851 -2339
- package/dist/commands/improve/proactive-maintenance.js +34 -101
- package/dist/commands/improve/reflect-noise.js +104 -280
- package/dist/commands/improve/reflect.js +621 -1367
- package/dist/commands/improve/salience.js +46 -232
- package/dist/commands/improve/session-asset.js +19 -100
- package/dist/commands/improve/stage.js +323 -0
- package/dist/commands/proposal/drain.js +251 -644
- package/dist/commands/proposal/proposal-cli.js +3 -18
- package/dist/commands/proposal/proposal-types.js +20 -41
- package/dist/commands/proposal/proposal.js +1 -2
- package/dist/commands/proposal/propose.js +134 -160
- package/dist/commands/proposal/repository.js +502 -1487
- 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 +13 -89
- package/dist/commands/read/curate.js +63 -413
- package/dist/commands/read/search-cli.js +16 -33
- package/dist/commands/read/search.js +17 -23
- package/dist/commands/read/show.js +2 -13
- package/dist/commands/sources/bundle-cli.js +25 -2
- package/dist/commands/sources/bundle-config-ops.js +7 -0
- package/dist/commands/sources/dangerous-env-audit.js +1 -2
- package/dist/commands/sources/info.js +2 -11
- 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/stash-cli.js +1 -1
- package/dist/commands/tasks/explain.js +10 -13
- package/dist/commands/tasks/tasks-cli.js +9 -8
- package/dist/commands/tasks/tasks.js +326 -930
- package/dist/commands/tasks/validate.js +42 -21
- package/dist/commands/workflow/plan.js +22 -29
- package/dist/commands/workflow-cli.js +4 -4
- package/dist/core/adapter/adapters/akm-adapter.js +0 -1
- package/dist/core/adapter/adapters/akm-lint.js +2 -3
- package/dist/core/adapter/adapters/akm-metadata.js +11 -12
- package/dist/core/adapter/adapters/akm-workflow-adapter.js +1 -1
- package/dist/core/adapter/execution-source.js +17 -29
- package/dist/core/asset/resolve-ref.js +1 -1
- package/dist/core/bundle-id.js +42 -5
- package/dist/core/bundle-rename.js +291 -0
- package/dist/core/config/config-io.js +1 -2
- package/dist/core/config/config-schema.js +1 -33
- package/dist/core/config/config-walker.js +1 -1
- package/dist/core/config/config.js +163 -68
- 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 +21 -95
- package/dist/core/config/schema/improve.js +4 -42
- 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-lock.js +76 -173
- package/dist/core/logs-db.js +2 -2
- package/dist/core/paths.js +0 -27
- 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 +108 -61
- package/dist/core/state-db-scope.js +2 -4
- package/dist/core/state-db.js +126 -692
- package/dist/core/type-presentation.js +1 -9
- package/dist/core/write-source.js +293 -1012
- 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/graph-db.js +106 -46
- package/dist/indexer/ensure-index.js +44 -85
- package/dist/indexer/graph/graph-extraction.js +340 -562
- package/dist/indexer/graph/graph-related.js +130 -0
- 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 +139 -151
- package/dist/indexer/indexer.js +524 -846
- package/dist/indexer/materialize-embeddings.js +60 -397
- package/dist/indexer/passes/memory-inference.js +81 -90
- package/dist/indexer/passes/metadata.js +132 -200
- package/dist/indexer/read-preflight.js +0 -7
- package/dist/indexer/scan/doc-to-entry.js +1 -3
- package/dist/indexer/scan/drain-dir.js +1 -1
- package/dist/indexer/search/db-search.js +181 -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 +2 -7
- 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/embedders/deterministic.js +2 -3
- package/dist/llm/embedders/profile.js +71 -0
- package/dist/llm/embedders/remote.js +10 -15
- package/dist/llm/graph-extract.js +3 -12
- package/dist/llm/index-passes.js +3 -5
- package/dist/llm/memory-infer.js +1 -2
- package/dist/llm/metadata-enhance.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 +2 -34
- package/dist/output/shapes/passthrough.js +1 -9
- package/dist/{indexer/search/ranking-types.js → output/text/bundle-rename.js} +4 -1
- package/dist/output/text/command-format.js +60 -23
- package/dist/output/text/helpers.js +1 -1
- package/dist/output/text/migrate.js +5 -14
- package/dist/output/text/proposal-format.js +1 -2
- 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 +43937 -93313
- package/dist/scripts/akm-migrate.js +43697 -93071
- 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/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 +0 -17
- 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 +168 -0
- package/dist/storage/repositories/index-connection.js +34 -70
- package/dist/storage/repositories/index-entries-repository.js +69 -111
- package/dist/storage/repositories/index-entry-mapper.js +1 -2
- package/dist/storage/repositories/index-entry-schema.js +83 -269
- package/dist/storage/repositories/index-fts-repository.js +86 -256
- package/dist/storage/repositories/index-llm-cache-repository.js +17 -0
- package/dist/storage/repositories/index-meta-repository.js +6 -4
- package/dist/storage/repositories/index-schema.js +192 -220
- 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 +35 -0
- package/dist/storage/repositories/registry-index-cache-repository.js +100 -0
- 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 +34 -27
- package/dist/tasks/activation-config.js +134 -62
- package/dist/tasks/backends/cron.js +129 -277
- package/dist/tasks/backends/exec-utils.js +2 -5
- package/dist/tasks/backends/launchd.js +125 -745
- package/dist/tasks/backends/schtasks.js +101 -620
- 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/scheduler-binding.js +18 -238
- package/dist/tasks/scheduler-invocation.js +52 -52
- package/dist/tasks/scheduler-lock.js +53 -0
- package/dist/tasks/scheduler-sync.js +361 -751
- package/dist/tasks/source/parse-task-source.js +160 -10
- package/dist/tasks/source/task-source-v3-frozen.js +3 -4
- package/dist/tasks/source/task-to-v4.js +2 -2
- 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 +41 -0
- package/docs/migration/v0.9.1-to-v0.9.2.md +19 -7
- package/docs/reference/cli.md +182 -125
- package/docs/reference/configuration.md +49 -56
- package/docs/reference/data-and-telemetry.md +19 -20
- package/docs/reference/tasks.md +86 -38
- 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 +87 -406
- 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 -146
- package/dist/commands/improve/distill/promote-memory.js +0 -329
- package/dist/commands/improve/distill/quality-gate.js +0 -500
- 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 -21
- 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/config/retired-experimental-keys-shim.js +0 -62
- 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 -441
- package/dist/indexer/graph/graph-boost.js +0 -427
- package/dist/indexer/graph/graph-dedup.js +0 -95
- package/dist/indexer/search/name-match.js +0 -35
- package/dist/indexer/search/ranking-contributors.js +0 -515
- 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/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/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 -78
- 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,15 @@
|
|
|
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
|
-
* Resolve the invoking harness/session identity for
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* surrounding agent harness already exposes via the environment.
|
|
12
|
-
*
|
|
13
|
-
* Resolution is best-effort and environment-driven:
|
|
14
|
-
* - harness: AKM_AGENT_HARNESS, else inferred from a harness session-id
|
|
15
|
-
* env var (`identityEnv`), else from a harness presence flag
|
|
16
|
-
* (`presenceEnv`).
|
|
17
|
-
* - sessionId: AKM_SESSION_ID, else the harness-native session env var.
|
|
18
|
-
* Presence flags NEVER contribute a session id — their values
|
|
19
|
-
* (`CODEX_SANDBOX=seatbelt`, `GEMINI_CLI=1`) are modes/flags,
|
|
20
|
-
* not sessions, and must not be persisted as agent_session_id.
|
|
21
|
-
*
|
|
22
|
-
* Explicit values passed to `startWorkflowRun` always win over the environment.
|
|
23
|
-
*
|
|
24
|
-
* The harness-native markers are DERIVED from `HARNESS_REGISTRY` (plan §"Kill
|
|
25
|
-
* registry drift", P2): each harness declares its session-id env vars via
|
|
26
|
-
* `identityEnv` and its presence-only flags via `presenceEnv`, so adding a
|
|
27
|
-
* harness never touches this module. Only the `AKM_*` explicit-override vars
|
|
28
|
-
* are non-registry (they are akm's own, not any harness's) and stay hardcoded
|
|
29
|
-
* here.
|
|
30
|
-
*
|
|
31
|
-
* @module workflows/agent-identity
|
|
5
|
+
* Resolve the invoking harness/session identity for a run from the
|
|
6
|
+
* environment (best-effort, no background work): the harness from
|
|
7
|
+
* `AKM_AGENT_HARNESS`, else a harness session-id env var, else a presence
|
|
8
|
+
* flag; the session id from `AKM_SESSION_ID`, else the harness-native session
|
|
9
|
+
* var (presence flags never supply one). The markers derive from
|
|
10
|
+
* `HARNESS_REGISTRY`. Explicit `startWorkflowRun` values always win.
|
|
32
11
|
*/
|
|
33
12
|
import { HARNESS_REGISTRY } from "../../integrations/harnesses/index.js";
|
|
34
|
-
/**
|
|
35
|
-
* Derive a marker table from one registry env-var field, ordered by canonical
|
|
36
|
-
* id. The sort keeps the pre-derivation precedence byte-identical ('claude'
|
|
37
|
-
* before 'opencode' — the old if/else chain's order) and independent of
|
|
38
|
-
* `HARNESS_REGISTRY` declaration order, which is pinned for JSON-schema enum
|
|
39
|
-
* stability, not detection precedence.
|
|
40
|
-
*/
|
|
13
|
+
/** A marker table from one registry env-var field, ordered by canonical id (the detection precedence). */
|
|
41
14
|
function deriveMarkers(pick) {
|
|
42
15
|
return HARNESS_REGISTRY.filter((h) => (pick(h)?.length ?? 0) > 0)
|
|
43
16
|
.map((h) => ({ harnessId: h.id, envKeys: pick(h) ?? [] }))
|
|
@@ -65,12 +38,7 @@ export function resolveAgentIdentity(env = process.env) {
|
|
|
65
38
|
// Explicit override always wins.
|
|
66
39
|
let harness = firstNonEmpty(env, ["AKM_AGENT_HARNESS"]);
|
|
67
40
|
if (!harness) {
|
|
68
|
-
//
|
|
69
|
-
// (registry `identityEnv` markers). A concrete session id is the
|
|
70
|
-
// strongest evidence of the invoking harness/session context, so it
|
|
71
|
-
// outranks any
|
|
72
|
-
// presence flag — e.g. opencode launched inside a codex sandbox
|
|
73
|
-
// (OPENCODE_SESSION_ID + CODEX_SANDBOX) attributes to opencode.
|
|
41
|
+
// A harness session id outranks any presence flag (opencode inside a codex sandbox is opencode).
|
|
74
42
|
for (const marker of SESSION_MARKERS) {
|
|
75
43
|
if (firstNonEmpty(env, marker.envKeys)) {
|
|
76
44
|
harness = marker.harnessId;
|
|
@@ -13,9 +13,7 @@
|
|
|
13
13
|
*
|
|
14
14
|
* This module must stay IMPORT-CYCLE-FREE with `./runs.ts` (which imports
|
|
15
15
|
* it): `WORKFLOW_EVIDENCE_TRUNCATED_MARKER`'s value is therefore reproduced
|
|
16
|
-
* locally rather than imported
|
|
17
|
-
* rather than import" idiom `ir/schema-v4.ts` already uses for
|
|
18
|
-
* `CHILD_WORKFLOW_DECODE_MAX_DEPTH`.
|
|
16
|
+
* locally rather than imported.
|
|
19
17
|
*/
|
|
20
18
|
import { validateJsonSchemaSubset } from "../../core/json-schema.js";
|
|
21
19
|
import { parseReference, resolveReferenceString } from "../program/expressions.js";
|
|
@@ -25,8 +23,7 @@ function projectStepOutput(evidence) {
|
|
|
25
23
|
}
|
|
26
24
|
/**
|
|
27
25
|
* Resolve a plan's declared `outputs:` from a run's PERSISTED step rows, in
|
|
28
|
-
* declaration order (
|
|
29
|
-
* sorted-unique, `ir/schema-v4.ts`'s `decodeWorkflowOutputs`). Every failure
|
|
26
|
+
* declaration order (compile sorts `outputs` keys by name). Every failure
|
|
30
27
|
* mode is collected (not stopped-at-first) so a completion failure names
|
|
31
28
|
* every offending output at once.
|
|
32
29
|
*/
|
|
@@ -73,7 +70,7 @@ export function resolveWorkflowRunOutputs(plan, steps) {
|
|
|
73
70
|
/**
|
|
74
71
|
* What a completed run EXPORTS: the resolved declared outputs, or
|
|
75
72
|
* `{runId, status}` metadata when the plan declared none. The `{runId,
|
|
76
|
-
* status}` form is synthesized on read and never stored
|
|
73
|
+
* status}` form is synthesized on read and never stored.
|
|
77
74
|
*/
|
|
78
75
|
export function workflowRunExportedResult(row) {
|
|
79
76
|
if (row.outputs_json) {
|
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
// This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
// file, You can obtain one at https://mozilla.org/MPL/2.0/.
|
|
4
|
+
/**
|
|
5
|
+
* Reading a run row's frozen plan: the ONE plan decoder and its tolerant
|
|
6
|
+
* row-level wrapper.
|
|
7
|
+
*
|
|
8
|
+
* {@link decodeWorkflowPlan} accepts every plan shape a release has stored —
|
|
9
|
+
* irVersion 4 and 5 (with their `sourceReadSet` and host-identity fields) as
|
|
10
|
+
* well as the current one — and keeps keys it does not know rather than
|
|
11
|
+
* refusing them. It rejects only a plan it cannot run: no steps, a unit with
|
|
12
|
+
* no frozen target, a request that does not decode. `plan_ir_version` and
|
|
13
|
+
* `plan_hash` are informational columns: neither gates execution. A plan that
|
|
14
|
+
* cannot be decoded comes back from {@link readRunPlan} as a `problem`
|
|
15
|
+
* sentence and the caller decides the remedy (the engine abandons such a run
|
|
16
|
+
* instead of throwing) — except for a plan a NEWER akm froze, which is `newer`
|
|
17
|
+
* and whose problem names upgrading akm as the remedy.
|
|
18
|
+
*/
|
|
19
|
+
import { UsageError } from "../../core/errors.js";
|
|
20
|
+
import { warnOnce } from "../../core/warn.js";
|
|
21
|
+
import { decodeResolvedExecutionRequest } from "../../execution/resolved-request.js";
|
|
22
|
+
import { decodeFrozenRunnerSpec } from "../../integrations/agent/runner.js";
|
|
23
|
+
import { WORKFLOW_PLAN_VERSION, } from "../plan.js";
|
|
24
|
+
export function readRunPlan(row) {
|
|
25
|
+
if (!row.plan_json)
|
|
26
|
+
return { ok: false, newer: false, problem: `Workflow run ${row.id} has no frozen workflow plan.` };
|
|
27
|
+
const version = row.plan_ir_version ?? null;
|
|
28
|
+
try {
|
|
29
|
+
const plan = decodeWorkflowPlan(JSON.parse(row.plan_json), {
|
|
30
|
+
...(row.workflow_ref ? { workflowRef: row.workflow_ref } : {}),
|
|
31
|
+
});
|
|
32
|
+
if (version !== null && version !== WORKFLOW_PLAN_VERSION) {
|
|
33
|
+
warnOnce(`workflow-plan-version:${row.id}`, `Workflow run ${row.id} was frozen as plan irVersion ${version}; running it with the current engine ` +
|
|
34
|
+
`(irVersion ${WORKFLOW_PLAN_VERSION}).`);
|
|
35
|
+
}
|
|
36
|
+
return { ok: true, plan };
|
|
37
|
+
}
|
|
38
|
+
catch (cause) {
|
|
39
|
+
const detail = cause instanceof Error ? cause.message : String(cause);
|
|
40
|
+
if (version !== null && version > WORKFLOW_PLAN_VERSION) {
|
|
41
|
+
return {
|
|
42
|
+
ok: false,
|
|
43
|
+
newer: true,
|
|
44
|
+
problem: `Workflow run ${row.id} was frozen by a newer akm (plan irVersion ${version}) and this akm cannot decode it: ` +
|
|
45
|
+
`${detail}. Upgrade akm to continue this run.`,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
const frozenAs = version === null ? "" : ` (frozen as plan irVersion ${version})`;
|
|
49
|
+
return {
|
|
50
|
+
ok: false,
|
|
51
|
+
newer: false,
|
|
52
|
+
problem: `Workflow run ${row.id} has a frozen plan this akm cannot decode${frozenAs}: ${detail}.`,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
/** Project persisted spine rows from the plan at publication time. */
|
|
57
|
+
export function frozenStepRows(plan) {
|
|
58
|
+
return plan.steps.map((step) => ({
|
|
59
|
+
stepId: step.stepId,
|
|
60
|
+
stepTitle: step.title,
|
|
61
|
+
instructions: step.root
|
|
62
|
+
? step.root.kind === "map"
|
|
63
|
+
? step.root.template.instructions
|
|
64
|
+
: step.root.instructions
|
|
65
|
+
: routeInstructions(step.route),
|
|
66
|
+
completionJson: step.gate.criteria.length > 0 ? JSON.stringify(step.gate.criteria) : null,
|
|
67
|
+
sequenceIndex: step.sequenceIndex,
|
|
68
|
+
}));
|
|
69
|
+
}
|
|
70
|
+
function routeInstructions(route) {
|
|
71
|
+
const branches = Object.entries(route.when)
|
|
72
|
+
.sort(([left], [right]) => (left < right ? -1 : left > right ? 1 : 0))
|
|
73
|
+
.map(([match, stepId]) => `"${match}" -> ${stepId}`);
|
|
74
|
+
if (route.defaultStepId !== undefined)
|
|
75
|
+
branches.push(`default -> ${route.defaultStepId}`);
|
|
76
|
+
return `Route on ${route.input}: ${branches.join(", ")}.`;
|
|
77
|
+
}
|
|
78
|
+
/** Decode a stored plan (any release's) into the one plan type. */
|
|
79
|
+
export function decodeWorkflowPlan(input, options = {}) {
|
|
80
|
+
const raw = record(input, "plan");
|
|
81
|
+
if (!Array.isArray(raw.steps) || raw.steps.length === 0)
|
|
82
|
+
fail("steps must be a non-empty array");
|
|
83
|
+
const steps = raw.steps.map((value, index) => decodeStep(value, index));
|
|
84
|
+
if (raw.outputs !== undefined) {
|
|
85
|
+
for (const [name, entry] of Object.entries(record(raw.outputs, "outputs"))) {
|
|
86
|
+
string(record(entry, `outputs.${name}`).from, `outputs.${name}.from`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
const sourceHash = typeof raw.sourceHash === "string" ? raw.sourceHash : legacySourceHash(raw.sourceReadSet, options.workflowRef);
|
|
90
|
+
return {
|
|
91
|
+
...raw,
|
|
92
|
+
irVersion: typeof raw.irVersion === "number" ? raw.irVersion : WORKFLOW_PLAN_VERSION,
|
|
93
|
+
title: typeof raw.title === "string" ? raw.title : "",
|
|
94
|
+
...(sourceHash ? { sourceHash } : {}),
|
|
95
|
+
steps,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
/** Plans frozen before irVersion 6 recorded the source hash inside `sourceReadSet`. */
|
|
99
|
+
function legacySourceHash(readSet, workflowRef) {
|
|
100
|
+
if (!workflowRef || !Array.isArray(readSet))
|
|
101
|
+
return undefined;
|
|
102
|
+
for (const entry of readSet) {
|
|
103
|
+
const identity = entry?.identity;
|
|
104
|
+
if (identity?.ref === workflowRef && typeof identity.hash === "string")
|
|
105
|
+
return identity.hash;
|
|
106
|
+
}
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
109
|
+
function decodeStep(value, index) {
|
|
110
|
+
const step = record(value, `step ${index}`);
|
|
111
|
+
const stepId = string(step.stepId, `step ${index} stepId`);
|
|
112
|
+
const route = step.route === undefined ? undefined : decodeRoute(step.route, stepId);
|
|
113
|
+
const root = step.root === undefined ? undefined : decodeNode(step.root, stepId);
|
|
114
|
+
if (!root && !route)
|
|
115
|
+
fail(`step ${stepId} has neither a frozen root nor a route`);
|
|
116
|
+
return {
|
|
117
|
+
...step,
|
|
118
|
+
stepId,
|
|
119
|
+
title: typeof step.title === "string" ? step.title : stepId,
|
|
120
|
+
sequenceIndex: index,
|
|
121
|
+
...(root ? { root } : {}),
|
|
122
|
+
...(route ? { route } : {}),
|
|
123
|
+
gate: decodeGate(step.gate, stepId),
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
function decodeRoute(value, stepId) {
|
|
127
|
+
const route = record(value, `step ${stepId} route`);
|
|
128
|
+
string(route.input, `step ${stepId} route.input`);
|
|
129
|
+
const when = record(route.when, `step ${stepId} route.when`);
|
|
130
|
+
for (const target of Object.values(when))
|
|
131
|
+
string(target, `step ${stepId} route target`);
|
|
132
|
+
return route;
|
|
133
|
+
}
|
|
134
|
+
function decodeNode(value, stepId) {
|
|
135
|
+
const node = record(value, `step ${stepId} root`);
|
|
136
|
+
if (node.kind !== "map")
|
|
137
|
+
return decodeUnit(node, stepId);
|
|
138
|
+
string(node.over, `step ${stepId} map.over`);
|
|
139
|
+
return {
|
|
140
|
+
...node,
|
|
141
|
+
concurrency: positiveInteger(node.concurrency) ?? 1,
|
|
142
|
+
reducer: node.reducer === "vote" ? "vote" : "collect",
|
|
143
|
+
template: decodeUnit(record(node.template, `step ${stepId} map template`), stepId),
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
function decodeUnit(node, stepId) {
|
|
147
|
+
const id = string(node.id, `step ${stepId} unit id`);
|
|
148
|
+
const label = `unit ${id}`;
|
|
149
|
+
if (node.frozenTarget === undefined)
|
|
150
|
+
fail(`${label} has no frozen target`);
|
|
151
|
+
return {
|
|
152
|
+
...node,
|
|
153
|
+
kind: "unit",
|
|
154
|
+
id,
|
|
155
|
+
instructions: typeof node.instructions === "string" ? node.instructions : "",
|
|
156
|
+
onError: node.onError === "continue" ? "continue" : "fail",
|
|
157
|
+
isolation: node.isolation === "worktree" ? "worktree" : "none",
|
|
158
|
+
frozenTarget: decodeTarget(node.frozenTarget, label),
|
|
159
|
+
environment: Array.isArray(node.environment)
|
|
160
|
+
? node.environment.map((binding, index) => decodeEnvironmentBinding(binding, `${label} environment[${index}]`))
|
|
161
|
+
: [],
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
function decodeGate(value, stepId) {
|
|
165
|
+
const gate = value === undefined ? {} : record(value, `step ${stepId} gate`);
|
|
166
|
+
const criteria = Array.isArray(gate.criteria)
|
|
167
|
+
? gate.criteria.filter((item) => typeof item === "string" && item.length > 0)
|
|
168
|
+
: [];
|
|
169
|
+
return {
|
|
170
|
+
kind: "gate",
|
|
171
|
+
id: typeof gate.id === "string" ? gate.id : `${stepId}.gate`,
|
|
172
|
+
stepId,
|
|
173
|
+
criteria,
|
|
174
|
+
maxLoops: positiveInteger(gate.maxLoops) ?? 1,
|
|
175
|
+
frozenJudge: criteria.length > 0 && gate.frozenJudge !== null && gate.frozenJudge !== undefined
|
|
176
|
+
? decodeCommandTarget(record(gate.frozenJudge, `gate ${stepId} judge`), `gate ${stepId} judge`)
|
|
177
|
+
: null,
|
|
178
|
+
};
|
|
179
|
+
}
|
|
180
|
+
function decodeTarget(value, label) {
|
|
181
|
+
const target = record(value, `${label} frozenTarget`);
|
|
182
|
+
const inputBindings = decodeInputBindings(target.inputBindings, label);
|
|
183
|
+
const gitCommitOid = typeof target.gitCommitOid === "string" ? target.gitCommitOid : undefined;
|
|
184
|
+
const optional = {
|
|
185
|
+
...(gitCommitOid ? { gitCommitOid } : {}),
|
|
186
|
+
...(inputBindings ? { inputBindings } : {}),
|
|
187
|
+
};
|
|
188
|
+
switch (target.kind) {
|
|
189
|
+
case "command":
|
|
190
|
+
return decodeCommandTarget(target, label);
|
|
191
|
+
case "shell":
|
|
192
|
+
return {
|
|
193
|
+
kind: "shell",
|
|
194
|
+
contentHash: string(target.contentHash, `${label} contentHash`),
|
|
195
|
+
exec: decodeExec(target.exec, label),
|
|
196
|
+
cwdIdentity: record(target.cwdIdentity, `${label} cwdIdentity`),
|
|
197
|
+
...optional,
|
|
198
|
+
};
|
|
199
|
+
case "script":
|
|
200
|
+
return {
|
|
201
|
+
kind: "script",
|
|
202
|
+
ref: string(target.ref, `${label} script ref`),
|
|
203
|
+
contentHash: string(target.contentHash, `${label} contentHash`),
|
|
204
|
+
exec: decodeExec(target.exec, label),
|
|
205
|
+
interpreter: string(target.interpreter, `${label} interpreter`),
|
|
206
|
+
extension: string(target.extension, `${label} extension`),
|
|
207
|
+
bytesBase64: typeof target.bytesBase64 === "string" ? target.bytesBase64 : fail(`${label} has no script bytes`),
|
|
208
|
+
byteLength: typeof target.byteLength === "number" ? target.byteLength : 0,
|
|
209
|
+
cwdIdentity: record(target.cwdIdentity, `${label} cwdIdentity`),
|
|
210
|
+
materialization: "ephemeral-0700-delete",
|
|
211
|
+
...optional,
|
|
212
|
+
};
|
|
213
|
+
case "child-workflow":
|
|
214
|
+
return {
|
|
215
|
+
kind: "child-workflow",
|
|
216
|
+
ref: string(target.ref, `${label} child ref`),
|
|
217
|
+
planHash: string(target.planHash, `${label} planHash`),
|
|
218
|
+
frozenPlan: decodeWorkflowPlan(target.frozenPlan),
|
|
219
|
+
contentHash: string(target.contentHash, `${label} contentHash`),
|
|
220
|
+
via: target.via === "task" ? "task" : "direct",
|
|
221
|
+
...(typeof target.taskRef === "string" ? { taskRef: target.taskRef } : {}),
|
|
222
|
+
...(inputBindings ? { inputBindings } : {}),
|
|
223
|
+
};
|
|
224
|
+
default:
|
|
225
|
+
return fail(`${label} has an unsupported frozen target kind ${JSON.stringify(target.kind)}`);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
function decodeCommandTarget(target, label) {
|
|
229
|
+
let request;
|
|
230
|
+
let runner;
|
|
231
|
+
try {
|
|
232
|
+
request = decodeResolvedExecutionRequest(target.request);
|
|
233
|
+
runner = decodeFrozenRunnerSpec(target.runner);
|
|
234
|
+
}
|
|
235
|
+
catch (cause) {
|
|
236
|
+
fail(`${label} request: ${cause instanceof Error ? cause.message : String(cause)}`);
|
|
237
|
+
}
|
|
238
|
+
const inputBindings = decodeInputBindings(target.inputBindings, label);
|
|
239
|
+
const concurrency = positiveInteger(target.concurrency);
|
|
240
|
+
return {
|
|
241
|
+
kind: "command",
|
|
242
|
+
ref: typeof target.ref === "string" ? target.ref : null,
|
|
243
|
+
contentHash: typeof target.contentHash === "string" ? target.contentHash : "",
|
|
244
|
+
request,
|
|
245
|
+
runner,
|
|
246
|
+
...(concurrency !== undefined ? { concurrency } : {}),
|
|
247
|
+
...(target.cwdIdentity && typeof target.cwdIdentity === "object"
|
|
248
|
+
? { cwdIdentity: target.cwdIdentity }
|
|
249
|
+
: {}),
|
|
250
|
+
...(typeof target.gitCommitOid === "string" ? { gitCommitOid: target.gitCommitOid } : {}),
|
|
251
|
+
...(inputBindings ? { inputBindings } : {}),
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
function decodeExec(value, label) {
|
|
255
|
+
const exec = record(value, `${label} exec`);
|
|
256
|
+
const command = exec.command;
|
|
257
|
+
if (!Array.isArray(command) || command.length === 0 || !command.every((arg) => typeof arg === "string")) {
|
|
258
|
+
fail(`${label} exec.command must be a non-empty argv`);
|
|
259
|
+
}
|
|
260
|
+
const timeoutMs = exec.timeoutMs;
|
|
261
|
+
if (timeoutMs !== null && typeof timeoutMs !== "number")
|
|
262
|
+
fail(`${label} exec.timeoutMs must be a number or null`);
|
|
263
|
+
return exec;
|
|
264
|
+
}
|
|
265
|
+
function decodeInputBindings(value, label) {
|
|
266
|
+
if (!Array.isArray(value) || value.length === 0)
|
|
267
|
+
return undefined;
|
|
268
|
+
return value.map((raw, index) => {
|
|
269
|
+
const binding = record(raw, `${label} inputBindings[${index}]`);
|
|
270
|
+
const name = string(binding.name, `${label} inputBindings[${index}].name`);
|
|
271
|
+
if (binding.kind === "reference") {
|
|
272
|
+
return {
|
|
273
|
+
kind: "reference",
|
|
274
|
+
name,
|
|
275
|
+
from: string(binding.from, `${label} inputBindings[${index}].from`),
|
|
276
|
+
schema: (binding.schema ?? {}),
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
return { kind: "literal", name, value: binding.value };
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
function decodeEnvironmentBinding(value, label) {
|
|
283
|
+
const binding = record(value, label);
|
|
284
|
+
if (binding.kind === "literal") {
|
|
285
|
+
return { kind: "literal", name: string(binding.name, label), value: String(binding.value ?? "") };
|
|
286
|
+
}
|
|
287
|
+
if (binding.kind === "pass-through")
|
|
288
|
+
return { kind: "pass-through", name: string(binding.name, label) };
|
|
289
|
+
if (binding.kind !== "env-ref")
|
|
290
|
+
fail(`${label} has an unsupported kind`);
|
|
291
|
+
const strings = (items) => Array.isArray(items) ? items.filter((item) => typeof item === "string") : [];
|
|
292
|
+
return {
|
|
293
|
+
kind: "env-ref",
|
|
294
|
+
ref: string(binding.ref, `${label} ref`),
|
|
295
|
+
owner: record(binding.owner, `${label} owner`),
|
|
296
|
+
keys: strings(binding.keys),
|
|
297
|
+
secretNames: strings(binding.secretNames),
|
|
298
|
+
precedence: typeof binding.precedence === "number" ? binding.precedence : 0,
|
|
299
|
+
};
|
|
300
|
+
}
|
|
301
|
+
function positiveInteger(value) {
|
|
302
|
+
return Number.isSafeInteger(value) && value >= 1 ? value : undefined;
|
|
303
|
+
}
|
|
304
|
+
function string(value, label) {
|
|
305
|
+
if (typeof value !== "string" || value.length === 0)
|
|
306
|
+
fail(`${label} must be a non-empty string`);
|
|
307
|
+
return value;
|
|
308
|
+
}
|
|
309
|
+
function record(value, label) {
|
|
310
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
311
|
+
fail(`${label} must be an object`);
|
|
312
|
+
return value;
|
|
313
|
+
}
|
|
314
|
+
function fail(message) {
|
|
315
|
+
throw new UsageError(`Invalid frozen workflow plan: ${message}.`, "INVALID_JSON_ARGUMENT");
|
|
316
|
+
}
|