builds.maxConcurrent mixed an execution setting into the build
definitions as a reserved key. The limit now lives in the new executor
section (pinned like the builds section, enforced for all builds
regardless of trigger), default 1, without a compatibility alias — a
leftover builds.maxConcurrent key is rejected as an invalid build
definition. Recorded as a follow-up in ADR 0007.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ADR 0007: the YAML builds section (next to the reserved maxConcurrent
key) defines named builds (jobs) with onPush/atTimes triggers, branch
selectors (name globs, activeWithin age filter), and build-setting
overrides applied last over the merged branch config. The implicit
default build (onPush over all branches) preserves the previous
behavior; the section is pinned against the worktree layer.
Results record the job name; restart, retry, and startup recovery
re-run by it, resolving settings from the current config. A non-default
build records under the <branch>@<build> pool with its own row,
retention count, and permanent latest-green link.
branches.*.autoBuild stays as a deprecated alias (plain times only);
the unreleased-in-practice v0.9.13 per-slot buildCommand/name syntax is
removed again.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>