Skip to content

awf v0.3.0

Choose a tag to compare

@github-actions github-actions released this 07 Jul 16:54

A workflow-format release. It renames several author-facing keys (migrate per
the BREAKING list below), adds container-less run: steps and native stall
detection with retry-as-continue, and tightens validation. The workflow-format
version (version: 1) is unchanged, but existing workflows must apply the key
migrations to keep validating.

BREAKING (v0.3.0 format)

  • reduce's quorum over: is renamed to field:. The per-branch boolean
    field a quorum counts is now declared as reduce: { quorum: <k>, field: <field> }.
    Migration: rename over: to field: under reduce.quorum only — a map's
    own over: (the fan-out worklist) is unrelated and unchanged.
  • The top-level workflow input: schema is renamed to input_schema:.
    Migration: rename the workflow's top-level input: key to input_schema:
    {{ input.<field> }} template references and a call step's own input:
    (the instance binding passed to a subworkflow) are unrelated and unchanged.
  • prune's keep: top(<k>) is now keep: <k>. The function-call-shaped
    wrapper is removed since top-k was always the only mode. Migration: replace
    keep: top(<k>) with the plain integer keep: <k>.
  • A signal where: clause now requires the {{ }} envelope, and correlates
    against the payload via a signal.<field> root.
    The old bare-identifier
    form (an implicit substitute-into-string-then-parse against the payload,
    with a string-quoting hazard) is removed. Migration: wrap the clause in
    {{ }} and prefix payload fields with signal. — e.g.
    where: 'candidate_id == "{{ hyp.id }}"' becomes
    where: "{{ signal.candidate_id == hyp.id }}". Every other root (input.*,
    step.*, run.*, an as: binding, …) resolves against the surrounding
    engine scope exactly as in if/loop/gate conditions, and the value is
    compared as typed data — no more quoting workaround for strings.

Added

  • output_artifact is no longer containerless-only. Any agent step that
    declares output_schema — container-backed or containerless — may now also
    declare output_artifact: <name> to publish its typed output as a
    content-addressed artifact. The requires-output_schema and
    mutually-exclusive-with-output_files rules (AWF3014) are unchanged.
  • map's over: accepts a literal YAML sequence. In addition to a
    {{ }} expression evaluated at runtime, over: may now be an author-fixed
    literal sequence (e.g. over: [a, b, c]) — a static, digest-pinned
    parameter sweep known before the run, as opposed to a runtime-sized
    worklist.
  • Container-less run: steps (bare shell). A run: code step may now omit
    container:; it executes host-side under the native sandbox (auto-selected
    when the workflow declares no image), so a hello-world needs no image or
    digest procurement. A bare run: is rejected under --backend docker
    (AWF1065) — declare a container: or run native.
  • map's concurrency: is optional (default 1, serial). Omitting it runs
    the map serially; an explicit value <= 0 is now rejected (AWF1012).
  • Native stall detection + retry-as-continue. An idle watchdog cancels an
    agent step that goes silent longer than timeout.idle (distinct from the
    wall-clock timeout), turning a wedged agent into a retryable failure. The
    openai/codex live adapter forwards codex's reasoning-summary heartbeat and
    gets a generous default idle (~300s); every other adapter is opt-in, and
    AWF3016 warns when idle: is set on an adapter that surfaces no liveness
    signal. On a stall, a persistent-session step resumes the same conversation
    thread — retry: { recovery: continue }, the default for session adapters —
    instead of restarting from scratch; recovery: restart is the escape hatch
    (AWF1064 rejects any other value at validation time).
  • awf validate strictly rejects unknown workflow/step keys (AWF1062). A
    stray or typo'd key anywhere in a workflow document — previously silently
    tolerated — is now a hard validation error.
  • awf validate strictly rejects bare-integer durations (AWF1063). A
    timeout or retry.initial/retry.max value must be a quoted duration
    string (e.g. "300s", not 300) — a bare integer previously parsed as
    nanoseconds with no error, causing the step to time out instantly.

Changed

  • Breaking (native backend): run workdirs moved from work/ to work/<run-id>/
    to isolate concurrent native runs. A native run started before this change
    cannot be resumed after upgrading (its workdir path moved). Docker runs are
    unaffected (already run-id namespaced). Start affected native runs fresh.