akm-cli 0.9.0-rc.1 → 0.9.0-rc.2
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 +223 -9
- package/SECURITY.md +23 -24
- package/dist/assets/help/help-improve.md +10 -10
- package/dist/assets/hints/cli-hints-full.md +44 -10
- package/dist/assets/hints/cli-hints-short.md +6 -2
- package/dist/assets/{profiles → improve-strategies}/default.json +1 -0
- package/dist/assets/{profiles → improve-strategies}/graph-refresh.json +1 -1
- package/dist/assets/{profiles → improve-strategies}/proactive-maintenance.json +2 -3
- package/dist/assets/{profiles → improve-strategies}/reflect-distill.json +3 -4
- package/dist/assets/stash-skeleton/README.md +28 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/agent.md +6 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/command.md +6 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/fact.md +12 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/knowledge.md +11 -1
- package/dist/assets/stash-skeleton/facts/conventions/assets/lesson.md +6 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/memory.md +9 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/script.md +7 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/skill.md +7 -0
- package/dist/assets/stash-skeleton/facts/conventions/assets/workflow.md +6 -0
- package/dist/assets/stash-skeleton/facts/conventions/backlinks.md +98 -0
- package/dist/assets/stash-skeleton/facts/conventions/domains.md +63 -0
- package/dist/assets/stash-skeleton/facts/conventions/organization.md +127 -0
- package/dist/assets/tasks/core/backup.yml +1 -0
- package/dist/assets/tasks/core/extract.yml +1 -0
- package/dist/assets/tasks/core/improve.yml +1 -0
- package/dist/assets/tasks/core/index-refresh.yml +1 -0
- package/dist/assets/tasks/core/sync.yml +1 -0
- package/dist/assets/tasks/core/version-check.yml +1 -0
- package/dist/assets/tasks/graph-refresh-weekly.yml +4 -4
- package/dist/assets/templates/html/health.html +5 -1
- package/dist/cli/config-migrate.js +31 -138
- package/dist/cli/config-validate.js +10 -8
- package/dist/cli.js +48 -14
- package/dist/commands/agent/agent-dispatch.js +17 -16
- package/dist/commands/agent/agent-support.js +0 -24
- package/dist/commands/agent/contribute-cli.js +5 -15
- package/dist/commands/backup-cli.js +54 -0
- package/dist/commands/config-cli.js +45 -159
- package/dist/commands/env/secret.js +8 -5
- package/dist/commands/health/checks.js +130 -83
- package/dist/commands/health/html-report.js +4 -0
- package/dist/commands/health/improve-metrics.js +30 -32
- package/dist/commands/health/llm-usage.js +19 -19
- package/dist/commands/health/md-report.js +4 -0
- package/dist/commands/health/metrics.js +2 -1
- package/dist/commands/health/surfaces.js +5 -4
- package/dist/commands/health.js +1 -1
- package/dist/commands/improve/consolidate/chunking.js +2 -2
- package/dist/commands/improve/consolidate.js +28 -25
- package/dist/commands/improve/distill/promote-memory.js +5 -12
- package/dist/commands/improve/distill/quality-gate.js +5 -7
- package/dist/commands/improve/distill.js +16 -5
- package/dist/commands/improve/eligibility.js +22 -12
- package/dist/commands/improve/extract-cli.js +47 -19
- package/dist/commands/improve/extract.js +110 -62
- package/dist/commands/improve/improve-cli.js +38 -16
- package/dist/commands/improve/improve-result-file.js +30 -24
- package/dist/commands/improve/improve-strategies.js +137 -0
- package/dist/commands/improve/improve.js +60 -30
- package/dist/commands/improve/locks.js +66 -45
- package/dist/commands/improve/loop-stages.js +75 -33
- package/dist/commands/improve/memory/memory-belief.js +79 -7
- package/dist/commands/improve/memory/memory-contradiction-detect.js +12 -4
- package/dist/commands/improve/preparation.js +71 -73
- package/dist/commands/improve/procedural.js +3 -2
- package/dist/commands/improve/recombine.js +2 -1
- package/dist/commands/improve/reflect.js +119 -214
- package/dist/commands/improve/shared.js +11 -5
- package/dist/commands/lint/base-linter.js +152 -42
- package/dist/commands/mv-cli.js +809 -0
- package/dist/commands/proposal/proposal-cli.js +18 -8
- package/dist/commands/proposal/propose.js +64 -69
- package/dist/commands/read/knowledge.js +436 -4
- package/dist/commands/read/remember-cli.js +39 -2
- package/dist/commands/read/search-cli.js +6 -1
- package/dist/commands/registry-cli.js +29 -14
- package/dist/commands/remember.js +2 -0
- package/dist/commands/sources/init.js +13 -14
- package/dist/commands/sources/schema-repair.js +2 -4
- package/dist/commands/sources/source-add.js +62 -73
- package/dist/commands/sources/source-manage.js +50 -46
- package/dist/commands/sources/stash-cli.js +41 -4
- package/dist/commands/tasks/default-tasks.js +12 -12
- package/dist/commands/tasks/tasks-cli.js +7 -3
- package/dist/commands/tasks/tasks.js +113 -18
- package/dist/commands/wiki-cli.js +9 -10
- package/dist/core/asset/frontmatter.js +12 -2
- package/dist/core/common.js +5 -3
- package/dist/core/config/config-io.js +28 -17
- package/dist/core/config/config-schema.js +358 -66
- package/dist/core/config/config-types.js +3 -3
- package/dist/core/config/config-version.js +29 -0
- package/dist/core/config/config-walker.js +98 -27
- package/dist/core/config/config.js +132 -266
- package/dist/core/config/deep-merge.js +41 -0
- package/dist/core/config/engine-semantics.js +32 -0
- package/dist/core/errors.js +2 -2
- package/dist/core/extra-params.js +61 -0
- package/dist/core/file-lock.js +201 -56
- package/dist/core/improve-result.js +178 -0
- package/dist/core/maintenance-barrier.js +119 -0
- package/dist/core/migration-backup.js +416 -0
- package/dist/core/paths.js +3 -0
- package/dist/core/redaction.js +358 -0
- package/dist/core/state/migrations.js +17 -2
- package/dist/core/state-db.js +44 -1
- package/dist/indexer/db/db.js +116 -1
- package/dist/indexer/graph/graph-extraction.js +28 -16
- package/dist/indexer/index-writer-lock.js +31 -24
- package/dist/indexer/index-written-assets.js +15 -6
- package/dist/indexer/indexer.js +47 -2
- package/dist/indexer/passes/memory-inference.js +10 -6
- package/dist/indexer/passes/metadata.js +250 -0
- package/dist/indexer/search/db-search.js +111 -44
- package/dist/indexer/search/fts-query.js +41 -0
- package/dist/indexer/search/ranking-contributors.js +48 -0
- package/dist/indexer/search/ranking.js +36 -23
- package/dist/indexer/search/search-fields.js +11 -1
- package/dist/integrations/agent/builder-shared.js +7 -0
- package/dist/integrations/agent/builders.js +5 -52
- package/dist/integrations/agent/config.js +3 -143
- package/dist/integrations/agent/detect.js +17 -2
- package/dist/integrations/agent/engine-resolution.js +202 -0
- package/dist/integrations/agent/index.js +1 -2
- package/dist/integrations/agent/model-aliases.js +7 -2
- package/dist/integrations/agent/profiles.js +6 -99
- package/dist/integrations/agent/runner-dispatch.js +76 -13
- package/dist/integrations/agent/runner.js +76 -207
- package/dist/integrations/agent/spawn.js +4 -6
- package/dist/integrations/harnesses/aider/agent-builder.js +2 -3
- package/dist/integrations/harnesses/aider/index.js +0 -1
- package/dist/integrations/harnesses/amazonq/agent-builder.js +2 -3
- package/dist/integrations/harnesses/amazonq/index.js +0 -1
- package/dist/integrations/harnesses/claude/agent-builder.js +2 -3
- package/dist/integrations/harnesses/claude/index.js +0 -2
- package/dist/integrations/harnesses/codex/agent-builder.js +2 -3
- package/dist/integrations/harnesses/codex/index.js +0 -1
- package/dist/integrations/harnesses/copilot/agent-builder.js +2 -3
- package/dist/integrations/harnesses/copilot/index.js +0 -1
- package/dist/integrations/harnesses/gemini/agent-builder.js +2 -3
- package/dist/integrations/harnesses/gemini/index.js +0 -1
- package/dist/integrations/harnesses/index.js +1 -24
- package/dist/integrations/harnesses/opencode/agent-builder.js +2 -3
- package/dist/integrations/harnesses/opencode/index.js +0 -6
- package/dist/integrations/harnesses/opencode-sdk/harness.js +1 -6
- package/dist/integrations/harnesses/opencode-sdk/sdk-runner.js +274 -191
- package/dist/integrations/harnesses/openhands/agent-builder.js +2 -3
- package/dist/integrations/harnesses/openhands/index.js +0 -1
- package/dist/integrations/harnesses/pi/agent-builder.js +2 -3
- package/dist/integrations/harnesses/pi/index.js +0 -1
- package/dist/integrations/harnesses/types.js +1 -32
- package/dist/integrations/lockfile.js +32 -21
- package/dist/llm/client.js +48 -14
- package/dist/llm/feature-gate.js +15 -47
- package/dist/llm/graph-extract.js +1 -1
- package/dist/llm/index-passes.js +8 -42
- package/dist/llm/memory-infer-impl.js +1 -1
- package/dist/llm/usage-persist.js +4 -0
- package/dist/llm/usage-telemetry.js +35 -5
- package/dist/output/shapes/helpers.js +2 -1
- package/dist/output/shapes/passthrough.js +2 -0
- package/dist/output/text/helpers.js +3 -1
- package/dist/schemas/akm-config.json +11013 -8600
- package/dist/schemas/akm-task.json +87 -0
- package/dist/schemas/akm-workflow.json +57 -13
- package/dist/scripts/migrate-storage.js +8591 -509
- package/dist/scripts/migrations/import-fs-improve-runs-to-db.js +8623 -484
- package/dist/setup/detected-engines.js +142 -0
- package/dist/setup/engine-config.js +89 -0
- package/dist/setup/setup.js +236 -132
- package/dist/setup/steps/connection.js +61 -32
- package/dist/setup/steps/platforms.js +4 -4
- package/dist/setup/steps.js +3 -2
- package/dist/storage/database.js +13 -1
- package/dist/storage/engines/sqlite-migrations.js +1 -0
- package/dist/storage/repositories/improve-runs-repository.js +5 -5
- package/dist/storage/repositories/task-history-repository.js +78 -0
- package/dist/storage/repositories/workflow-runs-repository.js +9 -8
- package/dist/tasks/parser.js +138 -52
- package/dist/tasks/runner.js +71 -75
- package/dist/tasks/schema.js +1 -1
- package/dist/tasks/validator.js +11 -6
- package/dist/wiki/wiki.js +9 -8
- package/dist/workflows/authoring/workflow-program-template.yaml +3 -3
- package/dist/workflows/concurrency-policy.js +15 -0
- package/dist/workflows/db.js +65 -13
- package/dist/workflows/exec/brief.js +18 -24
- package/dist/workflows/exec/frozen-judge.js +47 -0
- package/dist/workflows/exec/native-executor.js +124 -65
- package/dist/workflows/exec/report.js +93 -33
- package/dist/workflows/exec/run-workflow.js +38 -25
- package/dist/workflows/exec/scheduler.js +12 -41
- package/dist/workflows/exec/step-work.js +91 -35
- package/dist/workflows/ir/compile.js +13 -26
- package/dist/workflows/ir/freeze.js +243 -0
- package/dist/workflows/ir/plan-hash.js +40 -5
- package/dist/workflows/ir/schema.js +542 -1
- package/dist/workflows/parser.js +7 -0
- package/dist/workflows/program/parser.js +132 -23
- package/dist/workflows/program/project.js +3 -4
- package/dist/workflows/program/schema.js +2 -2
- package/dist/workflows/resource-limits.js +20 -0
- package/dist/workflows/runtime/plan-classifier.js +187 -0
- package/dist/workflows/runtime/runs.js +54 -47
- package/dist/workflows/runtime/workflow-asset-loader.js +0 -22
- package/dist/workflows/validator.js +25 -0
- package/docs/data-and-telemetry.md +2 -2
- package/docs/migration/release-notes/0.6.0.md +1 -1
- package/docs/migration/release-notes/0.7.0.md +5 -4
- package/docs/migration/v0.8-to-v0.9.md +401 -0
- package/package.json +4 -2
- package/schemas/akm-config.json +16638 -0
- package/schemas/akm-task.json +87 -0
- package/schemas/akm-workflow.json +372 -0
- package/dist/commands/improve/improve-profiles.js +0 -168
- package/dist/core/config/config-migration.js +0 -602
- package/dist/core/deep-merge.js +0 -38
- package/dist/llm/call-ai.js +0 -62
- package/dist/setup/legacy-config.js +0 -106
- package/docs/README.md +0 -104
- /package/dist/assets/{profiles → improve-strategies}/catchup.json +0 -0
- /package/dist/assets/{profiles → improve-strategies}/consolidate.json +0 -0
- /package/dist/assets/{profiles → improve-strategies}/frequent.json +0 -0
- /package/dist/assets/{profiles → improve-strategies}/memory-focus.json +0 -0
- /package/dist/assets/{profiles → improve-strategies}/quick.json +0 -0
- /package/dist/assets/{profiles → improve-strategies}/recombine-only.json +0 -0
- /package/dist/assets/{profiles → improve-strategies}/synthesize.json +0 -0
- /package/dist/assets/{profiles → improve-strategies}/thorough.json +0 -0
|
@@ -4,24 +4,28 @@
|
|
|
4
4
|
import { randomUUID } from "node:crypto";
|
|
5
5
|
import { parseAssetRef } from "../../core/asset/asset-ref.js";
|
|
6
6
|
import { canonicalizeWorkflowName } from "../../core/asset/asset-spec.js";
|
|
7
|
-
import {
|
|
7
|
+
import { loadConfig } from "../../core/config/config.js";
|
|
8
8
|
import { NotFoundError, UsageError } from "../../core/errors.js";
|
|
9
9
|
import { appendEvent } from "../../core/events.js";
|
|
10
10
|
import { warn } from "../../core/warn.js";
|
|
11
11
|
import { withWorkflowRunsRepo, } from "../../storage/repositories/workflow-runs-repository.js";
|
|
12
12
|
import { getCurrentWorkflowScopeKey } from "../authoring/scope-key.js";
|
|
13
|
+
import { frozenSummaryJudge } from "../exec/frozen-judge.js";
|
|
13
14
|
import { detectSecretShapedParams } from "../exec/param-secrets.js";
|
|
14
15
|
import { collectProgramWarnings } from "../ir/compile.js";
|
|
16
|
+
import { compileResolveFreezeWorkflow } from "../ir/freeze.js";
|
|
15
17
|
import { validateWorkflowParams } from "../ir/params.js";
|
|
16
18
|
import { canonicalPlanJson, computePlanHash } from "../ir/plan-hash.js";
|
|
19
|
+
import { decodeWorkflowPlanV3, WORKFLOW_IR_VERSION } from "../ir/schema.js";
|
|
17
20
|
import { validateStepSummary } from "../validate-summary.js";
|
|
18
21
|
import { resolveAgentIdentity } from "./agent-identity.js";
|
|
19
22
|
import { evaluateCheckin } from "./checkin.js";
|
|
23
|
+
import { assertWorkflowSpineMatchesPlan, classifyWorkflowRunPlan, frozenStepRows, requireAbandonableWorkflowPlan, requireExecutableWorkflowPlan, } from "./plan-classifier.js";
|
|
20
24
|
import { evaluateStaleUnits } from "./unit-checkin.js";
|
|
21
|
-
import {
|
|
25
|
+
import { loadWorkflowAsset, resolveWorkflowEntryId } from "./workflow-asset-loader.js";
|
|
22
26
|
/** Clip bound for a unit's `result_json` on the `--units` diagnostic surface. */
|
|
23
27
|
const UNIT_DIAGNOSTIC_CLIP = 2000;
|
|
24
|
-
function toUnitDiagnostic(row, stale) {
|
|
28
|
+
function toUnitDiagnostic(row, stale, plannedEngine) {
|
|
25
29
|
let diagnostic = null;
|
|
26
30
|
if (row.result_json !== null) {
|
|
27
31
|
// `result_json` is a JSON-encoded value: a bare JSON string for a free-text
|
|
@@ -55,6 +59,10 @@ function toUnitDiagnostic(row, stale) {
|
|
|
55
59
|
staleIdleMs: stale ? (Number.isFinite(stale.idleMs) ? stale.idleMs : null) : null,
|
|
56
60
|
claimHolder: row.claim_holder,
|
|
57
61
|
claimExpiresAt: row.claim_expires_at,
|
|
62
|
+
engine: row.engine ?? null,
|
|
63
|
+
runtimeKind: row.engine && (row.runner === "llm" || row.runner === "agent" || row.runner === "sdk") ? row.runner : null,
|
|
64
|
+
platform: plannedEngine?.kind === "agent" ? plannedEngine.platform : null,
|
|
65
|
+
...(!row.engine && row.runner ? { legacyRunnerSelector: row.runner } : {}),
|
|
58
66
|
};
|
|
59
67
|
}
|
|
60
68
|
export async function startWorkflowRun(ref, params = {}, options) {
|
|
@@ -63,7 +71,7 @@ export async function startWorkflowRun(ref, params = {}, options) {
|
|
|
63
71
|
// persist it on the run row in the same transaction as the insert. Every
|
|
64
72
|
// later invocation executes this snapshot — the asset file is never re-read
|
|
65
73
|
// for an in-flight run; re-planning is an explicit new run.
|
|
66
|
-
const plan =
|
|
74
|
+
const plan = decodeWorkflowPlanV3(compileResolveFreezeWorkflow(asset, loadConfig()).plan);
|
|
67
75
|
// Non-fatal WARNINGS (redesign addendum): a YAML program's untyped-step and
|
|
68
76
|
// undeclared-param advisories surface as `warn()` lines at start (stderr,
|
|
69
77
|
// consistent with the repo's other author-facing warnings) without blocking
|
|
@@ -89,7 +97,7 @@ export async function startWorkflowRun(ref, params = {}, options) {
|
|
|
89
97
|
const now = new Date().toISOString();
|
|
90
98
|
const runId = randomUUID();
|
|
91
99
|
const scopeKey = getCurrentWorkflowScopeKey();
|
|
92
|
-
const currentStepId =
|
|
100
|
+
const currentStepId = plan.steps[0]?.stepId ?? null;
|
|
93
101
|
const workflowEntryId = resolveWorkflowEntryId(asset.sourcePath, asset.ref);
|
|
94
102
|
// Capture the agent harness + session driving this run. Explicit options
|
|
95
103
|
// win; otherwise fall back to best-effort environment detection. This is
|
|
@@ -128,17 +136,17 @@ export async function startWorkflowRun(ref, params = {}, options) {
|
|
|
128
136
|
agentSessionId,
|
|
129
137
|
checkinArmedAt: now,
|
|
130
138
|
});
|
|
131
|
-
repo.insertSteps(
|
|
139
|
+
repo.insertSteps(frozenStepRows(plan).map((step) => ({
|
|
132
140
|
runId,
|
|
133
|
-
stepId: step.
|
|
134
|
-
stepTitle: step.
|
|
141
|
+
stepId: step.stepId,
|
|
142
|
+
stepTitle: step.stepTitle,
|
|
135
143
|
instructions: step.instructions,
|
|
136
|
-
completionJson: step.
|
|
137
|
-
sequenceIndex: step.sequenceIndex
|
|
144
|
+
completionJson: step.completionJson,
|
|
145
|
+
sequenceIndex: step.sequenceIndex,
|
|
138
146
|
})));
|
|
139
147
|
// Same transaction as the insert: a run row never exists without its
|
|
140
148
|
// frozen plan (rows with NULL plan_json are pre-006 legacy runs).
|
|
141
|
-
repo.setRunPlan(runId, planJson, planHash);
|
|
149
|
+
repo.setRunPlan(runId, planJson, planHash, WORKFLOW_IR_VERSION);
|
|
142
150
|
});
|
|
143
151
|
const result = await getWorkflowStatus(runId);
|
|
144
152
|
// #13: params are declared non-secret (they are copied verbatim into every
|
|
@@ -176,7 +184,9 @@ export async function getWorkflowStatus(runId, opts) {
|
|
|
176
184
|
// uses (`now` injected for deterministic tests) so a dead driver's claimed
|
|
177
185
|
// `running` unit surfaces as stale here too, not just as raw `running`.
|
|
178
186
|
const staleById = new Map(evaluateStaleUnits(rows, opts.now ?? Date.now()).map((u) => [u.unitId, u]));
|
|
179
|
-
|
|
187
|
+
const classified = classifyWorkflowRunPlan(run);
|
|
188
|
+
const engines = classified.support === "supported" ? classified.plan.execution?.engines : undefined;
|
|
189
|
+
detail.units = rows.map((row) => toUnitDiagnostic(row, staleById.get(row.unit_id), row.engine ? engines?.[row.engine] : undefined));
|
|
180
190
|
}
|
|
181
191
|
return detail;
|
|
182
192
|
});
|
|
@@ -207,6 +217,8 @@ export async function getNextWorkflowStep(specifier, params) {
|
|
|
207
217
|
return withWorkflowRunsRepo(async (repo) => {
|
|
208
218
|
const { run, autoStarted } = await resolveRunSpecifier(repo, specifier, params);
|
|
209
219
|
const steps = readWorkflowRunSteps(repo, run.id);
|
|
220
|
+
const plan = requireExecutableWorkflowPlan(run);
|
|
221
|
+
assertWorkflowSpineMatchesPlan(plan, run, steps);
|
|
210
222
|
return { ...projectNextResult(run, steps), ...(autoStarted ? { autoStarted: true } : {}) };
|
|
211
223
|
});
|
|
212
224
|
}
|
|
@@ -255,6 +267,8 @@ export async function snapshotRunForDriver(runId) {
|
|
|
255
267
|
return withWorkflowRunsRepo((repo) => repo.transaction(() => {
|
|
256
268
|
const run = readWorkflowRun(repo, runId);
|
|
257
269
|
const steps = readWorkflowRunSteps(repo, run.id);
|
|
270
|
+
const plan = requireExecutableWorkflowPlan(run);
|
|
271
|
+
assertWorkflowSpineMatchesPlan(plan, run, steps);
|
|
258
272
|
const units = repo.getUnitsForRun(run.id);
|
|
259
273
|
return { next: projectNextResult(run, steps), run, units };
|
|
260
274
|
}));
|
|
@@ -262,11 +276,13 @@ export async function snapshotRunForDriver(runId) {
|
|
|
262
276
|
export async function resumeWorkflowRun(runId) {
|
|
263
277
|
return withWorkflowRunsRepo((repo) => {
|
|
264
278
|
const run = readWorkflowRun(repo, runId);
|
|
279
|
+
const plan = requireExecutableWorkflowPlan(run);
|
|
280
|
+
const steps = readWorkflowRunSteps(repo, run.id);
|
|
281
|
+
assertWorkflowSpineMatchesPlan(plan, run, steps);
|
|
265
282
|
if (run.status === "completed") {
|
|
266
283
|
throw new UsageError(`Workflow run ${run.id} is already completed and cannot be resumed.`);
|
|
267
284
|
}
|
|
268
285
|
if (run.status === "active") {
|
|
269
|
-
const steps = readWorkflowRunSteps(repo, run.id);
|
|
270
286
|
return buildWorkflowRunDetail(run, steps);
|
|
271
287
|
}
|
|
272
288
|
// blocked or failed → flip back to active and re-open the current step so
|
|
@@ -279,8 +295,8 @@ export async function resumeWorkflowRun(runId) {
|
|
|
279
295
|
repo.markRunActive(run.id, now);
|
|
280
296
|
});
|
|
281
297
|
const updated = { ...run, status: "active", updated_at: now };
|
|
282
|
-
const
|
|
283
|
-
return buildWorkflowRunDetail(updated,
|
|
298
|
+
const refreshedSteps = readWorkflowRunSteps(repo, run.id);
|
|
299
|
+
return buildWorkflowRunDetail(updated, refreshedSteps);
|
|
284
300
|
});
|
|
285
301
|
}
|
|
286
302
|
/**
|
|
@@ -292,6 +308,11 @@ export async function resumeWorkflowRun(runId) {
|
|
|
292
308
|
export async function abandonWorkflowRun(runId) {
|
|
293
309
|
return withWorkflowRunsRepo((repo) => {
|
|
294
310
|
const run = readWorkflowRun(repo, runId);
|
|
311
|
+
requireAbandonableWorkflowPlan(run);
|
|
312
|
+
const classified = classifyWorkflowRunPlan(run);
|
|
313
|
+
const existingSteps = readWorkflowRunSteps(repo, run.id);
|
|
314
|
+
if (classified.support === "supported")
|
|
315
|
+
assertWorkflowSpineMatchesPlan(classified.plan, run, existingSteps);
|
|
295
316
|
if (run.status === "completed" || run.status === "failed") {
|
|
296
317
|
throw new UsageError(`Workflow run ${run.id} is already ${run.status}.`);
|
|
297
318
|
}
|
|
@@ -324,6 +345,9 @@ export async function completeWorkflowStep(input) {
|
|
|
324
345
|
// the write transaction — a slow/hung LLM must never hold a db write lock.
|
|
325
346
|
const preflight = await withWorkflowRunsRepo((repo) => {
|
|
326
347
|
const run = readWorkflowRun(repo, input.runId);
|
|
348
|
+
const plan = requireExecutableWorkflowPlan(run);
|
|
349
|
+
const steps = readWorkflowRunSteps(repo, run.id);
|
|
350
|
+
assertWorkflowSpineMatchesPlan(plan, run, steps);
|
|
327
351
|
if (run.status !== "active") {
|
|
328
352
|
throw new UsageError(`Workflow run ${run.id} is ${run.status} and cannot be updated.`);
|
|
329
353
|
}
|
|
@@ -338,7 +362,10 @@ export async function completeWorkflowStep(input) {
|
|
|
338
362
|
if (run.current_step_id !== existing.step_id) {
|
|
339
363
|
throw new UsageError(`Step "${input.stepId}" is not the current step for workflow run ${run.id}. Complete "${run.current_step_id}" first.`);
|
|
340
364
|
}
|
|
341
|
-
|
|
365
|
+
const stepPlan = plan.steps.find((step) => step.stepId === input.stepId);
|
|
366
|
+
if (!stepPlan)
|
|
367
|
+
throw new NotFoundError(`Step "${input.stepId}" was not found in workflow run ${run.id}.`);
|
|
368
|
+
return { existing, plan, stepPlan };
|
|
342
369
|
});
|
|
343
370
|
const summary = input.summary?.trim();
|
|
344
371
|
// #506: completing a step requires a summary of the work done.
|
|
@@ -349,9 +376,11 @@ export async function completeWorkflowStep(input) {
|
|
|
349
376
|
// completionCriteria via the configured LLM. Fail-open when no criteria or no
|
|
350
377
|
// judge. Only a well-formed `complete: false` blocks completion.
|
|
351
378
|
if (input.status === "completed" && summary) {
|
|
352
|
-
const criteria =
|
|
353
|
-
const judge = input.summaryJudge === undefined
|
|
354
|
-
|
|
379
|
+
const criteria = preflight.stepPlan.gate.criteria;
|
|
380
|
+
const judge = input.summaryJudge === undefined
|
|
381
|
+
? frozenSummaryJudge(preflight.plan, preflight.stepPlan.gate.judge)
|
|
382
|
+
: input.summaryJudge;
|
|
383
|
+
const verdict = await validateStepSummary({ stepTitle: preflight.stepPlan.title, completionCriteria: criteria, summary }, judge ?? undefined, { required: input.requireGate === true });
|
|
355
384
|
if (!verdict.complete) {
|
|
356
385
|
// Re-arm the check-in so a subsequent stall is still nudged, but leave the
|
|
357
386
|
// step pending and return corrective feedback instead of completing.
|
|
@@ -375,6 +404,9 @@ export async function completeWorkflowStep(input) {
|
|
|
375
404
|
let refreshedSteps = [];
|
|
376
405
|
repo.transaction(() => {
|
|
377
406
|
const run = readWorkflowRun(repo, input.runId);
|
|
407
|
+
const plan = requireExecutableWorkflowPlan(run);
|
|
408
|
+
const spine = readWorkflowRunSteps(repo, run.id);
|
|
409
|
+
assertWorkflowSpineMatchesPlan(plan, run, spine);
|
|
378
410
|
if (run.status !== "active") {
|
|
379
411
|
throw new UsageError(`Workflow run ${run.id} is ${run.status} and cannot be updated.`);
|
|
380
412
|
}
|
|
@@ -500,6 +532,7 @@ function buildWorkflowRunDetail(run, steps) {
|
|
|
500
532
|
};
|
|
501
533
|
}
|
|
502
534
|
function toWorkflowRunSummary(run) {
|
|
535
|
+
const plan = classifyWorkflowRunPlan(run);
|
|
503
536
|
return {
|
|
504
537
|
id: run.id,
|
|
505
538
|
workflowRef: run.workflow_ref,
|
|
@@ -514,6 +547,8 @@ function toWorkflowRunSummary(run) {
|
|
|
514
547
|
params: parseJsonObject(run.params_json),
|
|
515
548
|
agentHarness: run.agent_harness ?? null,
|
|
516
549
|
agentSessionId: run.agent_session_id ?? null,
|
|
550
|
+
planIrVersion: plan.irVersion,
|
|
551
|
+
executionSupport: plan.support,
|
|
517
552
|
// Surface the engine lease (holder id + expiry — never workflow-authored
|
|
518
553
|
// content) so `workflow next`/`status` show who is driving the run.
|
|
519
554
|
...(run.engine_lease_holder && run.engine_lease_until
|
|
@@ -579,34 +614,6 @@ function deriveRunState(steps) {
|
|
|
579
614
|
.at(-1);
|
|
580
615
|
return { status: "completed", currentStepId: null, completedAt: completedAt ?? null };
|
|
581
616
|
}
|
|
582
|
-
/**
|
|
583
|
-
* Build the default summary-validation judge from the configured LLM, or return
|
|
584
|
-
* `null` when no LLM is configured (gate is then skipped — fail-open). Lazily
|
|
585
|
-
* imports the client/config so the workflow engine has no hard LLM dependency.
|
|
586
|
-
*
|
|
587
|
-
* Exported for the engine loop (`exec/run-workflow.ts`), which wraps the judge
|
|
588
|
-
* to journal engine-driven gate evaluations as unit rows (addendum R2).
|
|
589
|
-
*/
|
|
590
|
-
export function buildDefaultSummaryJudge() {
|
|
591
|
-
let llm;
|
|
592
|
-
try {
|
|
593
|
-
const config = loadConfig();
|
|
594
|
-
llm = getDefaultLlmConfig(config);
|
|
595
|
-
}
|
|
596
|
-
catch {
|
|
597
|
-
return null;
|
|
598
|
-
}
|
|
599
|
-
if (!llm)
|
|
600
|
-
return null;
|
|
601
|
-
const resolved = llm;
|
|
602
|
-
return async ({ system, user }) => {
|
|
603
|
-
const { chatCompletion } = await import("../../llm/client.js");
|
|
604
|
-
return chatCompletion(resolved, [
|
|
605
|
-
{ role: "system", content: system },
|
|
606
|
-
{ role: "user", content: user },
|
|
607
|
-
]);
|
|
608
|
-
};
|
|
609
|
-
}
|
|
610
617
|
function parseJsonObject(value) {
|
|
611
618
|
if (!value)
|
|
612
619
|
return undefined;
|
|
@@ -12,31 +12,9 @@ import { resolveSourcesForOrigin } from "../../registry/origin-resolve.js";
|
|
|
12
12
|
import { resolveAssetPath } from "../../sources/resolve.js";
|
|
13
13
|
import { withIndexDb } from "../../storage/repositories/index-db.js";
|
|
14
14
|
import { formatWorkflowErrors } from "../authoring/authoring.js";
|
|
15
|
-
import { compileWorkflowPlan, compileWorkflowProgram } from "../ir/compile.js";
|
|
16
15
|
import { parseWorkflow } from "../parser.js";
|
|
17
16
|
import { parseWorkflowProgram } from "../program/parser.js";
|
|
18
17
|
import { isWorkflowProgramPath, projectProgramParameters, projectProgramStepDefinitions } from "../program/project.js";
|
|
19
|
-
/**
|
|
20
|
-
* Compile a loaded workflow asset into the plan graph that gets frozen on the
|
|
21
|
-
* run row. YAML programs compile via `compileWorkflowProgram` with full
|
|
22
|
-
* expression validation; markdown documents compile via `compileWorkflowPlan`
|
|
23
|
-
* (linear workflows — the stable contract — produce the same linear plan as
|
|
24
|
-
* today). Exactly one of `program` / `document` is set by this loader.
|
|
25
|
-
*/
|
|
26
|
-
export function compileWorkflowAssetPlan(asset) {
|
|
27
|
-
if (asset.program) {
|
|
28
|
-
const compiled = compileWorkflowProgram(asset.program);
|
|
29
|
-
if (!compiled.ok) {
|
|
30
|
-
throw new UsageError(formatWorkflowErrors(asset.path, compiled.errors));
|
|
31
|
-
}
|
|
32
|
-
return compiled.plan;
|
|
33
|
-
}
|
|
34
|
-
if (asset.document) {
|
|
35
|
-
return compileWorkflowPlan(asset.document);
|
|
36
|
-
}
|
|
37
|
-
// Unreachable for assets produced by loadWorkflowAsset; guards hand-built ones.
|
|
38
|
-
throw new UsageError(`Workflow asset ${asset.ref} carries neither a parsed document nor a program to compile.`);
|
|
39
|
-
}
|
|
40
18
|
/**
|
|
41
19
|
* Resolve a `workflow:<name>` ref to a fully-projected {@link WorkflowAsset}.
|
|
42
20
|
*
|
|
@@ -1,12 +1,37 @@
|
|
|
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
|
+
/**
|
|
5
|
+
* Cross-cutting semantic checks over an assembled WorkflowDocument draft.
|
|
6
|
+
*
|
|
7
|
+
* The parser handles per-line shape checks; this module runs rules that need
|
|
8
|
+
* the whole document or the raw frontmatter at once: duplicate step IDs,
|
|
9
|
+
* step-id format, and the frontmatter key whitelist.
|
|
10
|
+
*/
|
|
11
|
+
import { utf8Bytes, WORKFLOW_MAX_INSTRUCTION_BYTES, WORKFLOW_MAX_PARAMS, WORKFLOW_MAX_STEPS } from "./resource-limits.js";
|
|
4
12
|
const STEP_ID_REGEX = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
5
13
|
const ALLOWED_FRONTMATTER_KEYS = new Set(["description", "tags", "params", "name", "updated", "when_to_use"]);
|
|
6
14
|
export function runSemanticChecks(draft, frontmatterData, frontmatterEndLine, errors) {
|
|
7
15
|
checkFrontmatterKeys(frontmatterData, frontmatterEndLine, errors);
|
|
8
16
|
checkStepIdFormat(draft, errors);
|
|
9
17
|
checkDuplicateStepIds(draft, errors);
|
|
18
|
+
checkResourceLimits(draft, errors);
|
|
19
|
+
}
|
|
20
|
+
function checkResourceLimits(draft, errors) {
|
|
21
|
+
if (draft.steps.length > WORKFLOW_MAX_STEPS) {
|
|
22
|
+
errors.push({ line: 1, message: `Workflow must contain at most ${WORKFLOW_MAX_STEPS} steps.` });
|
|
23
|
+
}
|
|
24
|
+
if ((draft.parameters?.length ?? 0) > WORKFLOW_MAX_PARAMS) {
|
|
25
|
+
errors.push({ line: 1, message: `Workflow must contain at most ${WORKFLOW_MAX_PARAMS} parameters.` });
|
|
26
|
+
}
|
|
27
|
+
for (const step of draft.steps) {
|
|
28
|
+
if (utf8Bytes(step.instructions.text) > WORKFLOW_MAX_INSTRUCTION_BYTES) {
|
|
29
|
+
errors.push({
|
|
30
|
+
line: step.instructions.source.start,
|
|
31
|
+
message: `Step "${step.id}" instructions exceed the 256 KiB resource limit.`,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
}
|
|
10
35
|
}
|
|
11
36
|
function checkFrontmatterKeys(data, fmEndLine, errors) {
|
|
12
37
|
for (const key of Object.keys(data)) {
|
|
@@ -26,7 +26,7 @@ AKM writes to these locations on your machine. All paths follow [XDG Base Direct
|
|
|
26
26
|
|
|
27
27
|
| Path | Contents | Safe to delete? |
|
|
28
28
|
|---|---|---|
|
|
29
|
-
| `config.json` | Your AKM configuration:
|
|
29
|
+
| `config.json` | Your AKM configuration: engines, strategies, stash paths, and feature settings | **No** — deleting resets all settings |
|
|
30
30
|
|
|
31
31
|
Override: set `AKM_CONFIG_DIR` or `XDG_CONFIG_HOME`.
|
|
32
32
|
|
|
@@ -109,7 +109,7 @@ An append-only log of every mutating action you perform with AKM. Events are sto
|
|
|
109
109
|
| `select` | `akm show` after a search returning the same ref | `ref`, `entryId` |
|
|
110
110
|
| `promoted` | `akm proposal accept <id>` | `ref` |
|
|
111
111
|
| `rejected` | `akm proposal reject <id>` | `ref` |
|
|
112
|
-
| `reflect_invoked` | Start of reflect phase in `akm improve` | `ref`,
|
|
112
|
+
| `reflect_invoked` | Start of reflect phase in `akm improve` | `ref`, engine |
|
|
113
113
|
| `reflect_completed` | Reflect phase produced a proposal | `ref` |
|
|
114
114
|
| `improve_reflect_outcome` | Per-asset reflect result | `ref`, `ok`, `durationMs`, `reason` |
|
|
115
115
|
| `propose_invoked` | `akm propose` | `ref` |
|
|
@@ -90,7 +90,7 @@ vault | wiki | enable | disable | completions | upgrade | save | help |
|
|
|
90
90
|
hints
|
|
91
91
|
|
|
92
92
|
Full migration guides:
|
|
93
|
-
- https://github.com/itlackey/akm/blob/main/docs/
|
|
93
|
+
- https://github.com/itlackey/akm/blob/main/docs/archive/pre-1.0-migration.md (pre-1.0
|
|
94
94
|
architecture refactor — read this first if you are coming from 0.5.x or
|
|
95
95
|
an earlier 0.6 pre-release)
|
|
96
96
|
- https://github.com/itlackey/akm/blob/main/docs/migration/v0.5-to-v0.6.md
|
|
@@ -13,7 +13,7 @@ grammar continue to match the v1 architecture spec
|
|
|
13
13
|
pre-releases — the formal freeze itself happens at 1.0 GA.
|
|
14
14
|
|
|
15
15
|
If you are coming from 0.6.x, the
|
|
16
|
-
[
|
|
16
|
+
[archived pre-1.0 migration plan](../../archive/pre-1.0-migration.md) covers the historical per-surface delta and is the
|
|
17
17
|
canonical upgrade reference. This file is the executive summary of
|
|
18
18
|
what's new in 0.7.0.
|
|
19
19
|
|
|
@@ -47,7 +47,8 @@ akm proposal reject <id> --reason "…" # archive with reason
|
|
|
47
47
|
Multiple proposals for the same `ref` coexist without filesystem
|
|
48
48
|
collisions. Auto-accept is gated per-source via the source config
|
|
49
49
|
(`autoAcceptProposals: true`); the default is off and requires a
|
|
50
|
-
writable source. See
|
|
50
|
+
writable source. See the archived pre-1.0 migration spec §11 at
|
|
51
|
+
`docs/archive/pre-1.0-migration.md`.
|
|
51
52
|
|
|
52
53
|
### `akm reflect`, `akm propose`, `akm distill` — new CLI surfaces (#225, #226, #227)
|
|
53
54
|
|
|
@@ -141,7 +142,7 @@ The bench technical reference lives in
|
|
|
141
142
|
- Earlier 0.7.x pre-release work (#220–#223) finalised the registry
|
|
142
143
|
curation surface removal, classification pipeline rewrites, and
|
|
143
144
|
error envelope shape that 0.7.0 ships. Operators upgrading from a
|
|
144
|
-
0.6.x baseline should read [
|
|
145
|
+
0.6.x baseline should read the [archived pre-1.0 plan](../../archive/pre-1.0-migration.md) for
|
|
145
146
|
the per-surface migration recipe.
|
|
146
147
|
|
|
147
148
|
### CLI surface as of 0.7.0
|
|
@@ -257,7 +258,7 @@ akm proposal accept <id>
|
|
|
257
258
|
|
|
258
259
|
## Full migration guides
|
|
259
260
|
|
|
260
|
-
- [
|
|
261
|
+
- [Archived pre-1.0 migration plan](../../archive/pre-1.0-migration.md) — per-surface delta from any 0.6.x
|
|
261
262
|
baseline. The canonical reference for upgrading.
|
|
262
263
|
- [v0.5 → v0.6](../v0.5-to-v0.6.md) — the older terminology cut and
|
|
263
264
|
registry schema v3.
|