akm docs

Migration notes for akm v0.9.2

Exact-prefix additive state.db upgrades remain automatic. The released historical migration 018 is classified separately because it removes retired dead-lane state: ordinary commands stop before it. Run akm upgrade --force; after executable replacement AKM writes and verifies a sibling state.db.pre-018-drop-dead-lane-schema.<UTC-digits>.<UUID>.bak snapshot, then applies the immutable migration. The exact ledger recheck, snapshot, and 018 transaction share one SQLite writer-exclusion window. There is no general database migration command.

A newly created state.db still bootstraps automatically, but only when this invocation atomically created and retained ownership of that exact inode. An already-existing file with no applied migration IDs is not fresh, whether its schema_migrations table is absent or empty: ordinary commands reject it without writing. akm upgrade --force first verifies a descriptor-bound state.db.pre-001-initial-schema.<UTC-digits>.<UUID>.bak snapshot. The same writer-exclusion transaction then initializes the ledger and applies migrations 001–002, so an old-schema writer cannot commit data between the recovery snapshot and migration 002's rebuild. Snapshot readers and targets are bound to their held inodes, not swappable pathnames. A failed snapshot path is reported and never removed by cleanup code.

Task sources now use task source v4. Normal execution rejects task-v3 and task-v2 files with TASK_SCHEMA_VERSION_UNSUPPORTED; preview the repository-wide conversion with akm migrate apply --dry-run, review every changed, skipped, or blocked result, then run akm migrate apply — it now runs both the v2→v3 and v3→v4 generations in one pass. The migrator validates each replacement before it backs up and replaces a source, and ambiguous cases (an argv array with no safe shell equivalent, a with: block with no v4 equivalent, an ambiguous scheduling source, and similar) remain blocked for manual review. Task source v4 adds typed inputs: with defaults, a single bounded output: schema, optional schedule:, and per-schedule-binding enablement. See Task sources and The migration procedure.

Task run history's target.kind result field also changed vocabulary: "prompt" is now "command" (an agent/LLM dispatch), and the old shared "command" split into "shell" and "script". akm task history reads both generations of existing rows correctly, forever, keyed on a per-row targetVocab marker — but a pre-0.9.2 akm's decoder does not recognize that marker and throws reading a row this release (or later) wrote, so upgrade once and don't downgrade below 0.9.2 for a given state.db. See Task history result vocabulary.

Workflows now accept peer Markdown (.md) and GitHub-shaped YAML (.yml) sources through source IR v1. Runs freeze durable plan irVersion 5, the only executable plan format. Pre-irVersion-5 stored plans cannot resume, next, complete, or run — status, list, and abandon keep working, and akm workflow abandon <id> followed by a fresh akm workflow run <ref> recovers a blocked run; no data is lost. A resume does not re-read the authored workflow, configuration, or asset index. Scheduled fires are new starts, so they read the current source and create a fresh freeze. .yml also rejects inherit_env; use exact named environment bindings and pass_env names instead. See Workflow cutover.

A workflow step can now compose another workflow as a child — directly (uses: workflows/<ref>) or through a task whose own target is a workflow — bounded by composition depth, cycle detection, and aggregate embedded-plan size, all checked at freeze before the parent run is published. Running the step drives the child to completion inline, in the parent's own process: cancellation propagates because it is the same process, the child is independently resumable, and akm workflow status on the parent renders a children: tree. A workflow may also declare outputs: — a run-level export resolved once from persisted step evidence at completion, which a composing parent step promotes as its own output. See Child workflows and Workflow outputs.

A workflow step's with: on a uses: tasks/<ref> target now binds the task's declared inputs: — literal values or {from: "steps.<id>.output…"} references resolved just before dispatch (the reference grammar also accepts {from: "params.<name>"}, but a composing step's own document can never declare params:, so that form is not reachable in this release) — instead of being silently dropped. A with: on a task with no inputs:, or on a commands//scripts/ target (never binding surfaces), is now rejected at freeze rather than discarded. See with: on a task-composed step now binds — or rejects.

Three recognized-but-limited constructs are removed outright in 0.9.2: the GitHub Action uses: locator (owner/repo[/path]@ref) is no longer recognized anywhere — it was always rejected before dispatch in every prior release, so this deletes the recognition, not a working capability; multi-job GitHub-shaped YAML is rejected at the source adapter instead of parsing clean and being refused later in two different places — split a multi-job document into single-job workflows composed with a child-workflow step; and the second task scheduling syntax (akm.schedule / a task's top-level on:) is gone along with task v3, leaving task source v4's optional top-level schedule: as the one canonical form. See GitHub Action locators are no longer recognized anywhere and Multi-job YAML is rejected at the adapter boundary.

Two new read-only introspection verbs: akm workflow plan <ref> (secret-free by construction) compiles, resolves, and freezes a workflow without publishing a run, printing the canonical step graph, target/child expansion, and input bindings; akm task explain <ref> prints a task's resolved target, declared and supplied inputs: (secret-shaped values redacted on a best-effort heuristic basis), and schedule bindings — its default and --format json output are the same raw JSON. See New commands.

Task-source, workflow-source, and composition failures now report phase-specific UsageError codes (TASK_SOURCE_INVALID, TASK_SCHEMA_VERSION_UNSUPPORTED, TARGET_REF_INVALID, WORKFLOW_SOURCE_INVALID, COMPOSITION_INVALID, INPUT_BINDING_INVALID, TASK_TARGET_UNSUPPORTED, WORKFLOW_OUTPUT_INVALID, WORKFLOW_IR_VERSION_UNSUPPORTED) instead of the generic INVALID_FLAG_VALUE; exit codes are unchanged. See Diagnostics.

akm command run --dry-run performs authorization and adapter lowering but does not dispatch or materialize credentials. It writes no authored source or durable state and records no usage, events, or accounting. Safe provenance and lowering notices omit resolved, prompt, command, environment, and credential values. --verbose writes those safe diagnostics to stderr without changing the command result on stdout. akm health adds offline selected-model-aliases and configured-engines advisories; their evidence does not disclose endpoint values, exact model IDs, credential values, or provider output.

improve.strategies.<name>.processes.triage.judgment now accepts a boolean or an object. Set judgment: false to disable the tier explicitly. A newly authored object defaults to enabled, while unknown object keys are rejected. The standalone proposal command's --judgment option remains an explicit invocation override and does not rewrite strategy configuration.

See the long-form guide for complete task examples, workflow boundaries, compatibility details, and upgrade checks.