implement-next-task
SkillFiles & storageDrive the autonomous 2.0.0 ESP32-S3-only async + FreeRTOS migration (epic TASK-865). Runs a continuous workflow that audits stuck/finishable backlog tasks, then drains every actionable async-esp32s3 task back-to-back (implement -> build/eval -> adversarial review -> commit/push -> Discord) without waiting between tasks, then runs ONE end-of-loop ADR-evaluation pass that drafts Proposed ADRs for the run's architectural decisions, and can fan out to parallel worktree lanes. Use for one drain run of the migration loop (cron or manual).
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the implement-next-task skill
What this skill tells your AI
The instructions your AI receives, as published by rvdbreemen/otgw-firmware in .claude/skills/implement-next-task/SKILL.md and read by ahel’s review.
Drives the autonomous 2.0.0 ESP32-S3-only async + FreeRTOS migration (epic TASK-865, ADR-123/128). The deterministic multi-agent engine is the workflow script; it is continuous and self-announcing — one invocation drains as many tasks as it can.
Run (single lane, default worktree)
Branch model changed 2026-06-20: the 2.0.0 async line was promoted to
dev(the formerfeature-2.0.0-esp32s3-async).devis the default working line and the default worktree (D:/Users/Robert/Documents/GitHub/RvdB/OTGW-firmware); the old async worktree is gone.otgw-1.x.xis the 1.x maintenance line;mainis always the latest public release.
Workflow({ scriptPath: "D:/Users/Robert/Documents/GitHub/RvdB/OTGW-firmware/.claude/workflows/implement-next-task.js" })
The engine, in one run:
- Audit — captures the run's start commit (
git rev-parse HEAD, the stablestartHead..HEADrange the ADR-Evaluation pass diffs later), then reads every In Progress / In Review async-esp32s3 task. Resets STUCK ones (abandoned partial edits from a transient abort) to To Do; moves FINISHABLE ones (all remaining ACs build/evaluator-verifiable, committed + green, no hardware AC) to Done; leaves correctly-In-Review (field-validation pending) ones alone. It decides this itself — no permission prompt. - Drain loop — repeatedly: Select the lowest actionable task (deps Done/In
Review; single-flight-guarded per worktree) -> Implement (coding agent, ACs +
CLAUDE rules) -> build (
python build.py) +evaluate.py --quick-> adversarial Review (one fix pass) -> Land (set status In Review / Done, bump prerelease ifsrc/**touched, commit, push — no ADR in the per-task commit) -> Announce (Discord, below). Then it advances to the next task immediately — it does NOT wait for the next tick. - ADR Evaluation (end of run) — after the drain loop exits (whether it drained
the backlog or
breaks on a transient failure), if any task landed this run a single pass reviews the whole-run diff (startHead..HEAD) plus the landed task bodies, dedups the architectural decisions across all tasks into one entry each, has the JS assign the next free ADR numbers (no LLM number-picking → no collision), drafts one Proposed ADR per decision (adr-kit:adr-generator, never Accepted), runs the self-accept governance guard over them, commits them in onedocs(adr): ... (TASK-865)commit (docs-only, no bump), pushes, and posts a maintainer-facing "N Proposed ADRs drafted for review" note to #dev-sat-mqtt. Each ADR's References section cites the contributing task ids + their commit hashes (the traceability that replaces riding the ADR inside the code commit). This is the only place the loop authors ADRs — moved out of the per-task path 2026-06-24 (TASK-928) so one evaluation sees cross-task decisions and the maintainer reviews a coherent batch instead of a per-task drip.- Process-death recovery. Every Land stamps the task note
ADR-PENDING; the ADR-Evaluation pass stampsADR-EVALUATED: <ADR-ids|none>ONLY on confirmed completion (ADRs drafted + committed, or nothing architectural to draft). If the pass dies (rate-limit) before stamping, theADR-PENDINGmarker survives in git, so the NEXT run's Audit returns the task inadrOrphansand this pass sweeps it up alongside its own tasks. Enumerate grepsdocs/adr/for the task ids first and skips any decision already documented, so a retry after a partial death never double-drafts. (The same marker drives the parallel-lane handoff: askipAdrEvallane leaves its tasksADR-PENDINGfor the integrating run to draw in.)
- Process-death recovery. Every Land stamps the task note
- Stop when nothing is actionable, on a transient agent death (rate limit — it
cleans up the task back to To Do and ends so a later run retries), or when a task
fails review twice (flags it for attention). The ADR-Evaluation pass still runs for
whatever did land before the stop, plus any
ADR-PENDINGorphans from a prior dead run.
Returns { done, completed: [...], count, endReason, adrsDrafted: [...] }. endReason
tells you whether it drained the backlog, hit a transient rate-limit, or needs
attention on a task; adrsDrafted lists the Proposed ADRs the end-of-run pass drafted
(awaiting maintainer acceptance).
Parallel lanes (args.skipAdrEval, set automatically alongside skipBump) defer the
ADR-Evaluation pass to serial integration so two lanes never race on ADR numbers; the
integrating run drafts the ADRs once after the merge.
Discord (alpha-channel policy, done INSIDE the loop)
2.0.0+ is the alpha line. Test/publish only in #alpha-testing and #dev-sat-mqtt; never #beta-testing. Per landed task the Announce phase posts:
- a one-line completion to #dev-sat-mqtt (
1105556725714649128): id, title, status, commit, prerelease tag; - if the task bumped the prerelease (a semver feature step), a short feature summary
to #alpha-testing (
1514720723980259460) — facts only; if it returns "Missing Access" it notes the bot lacks access and continues (no retry).
Parallel lanes (fan out when genuinely independent)
One worktree can only run one lane (shared git index + .pio). To run more tasks at
once, give each its own worktree + sub-branch and pin its task. Select reports
alsoActionable — other actionable tasks whose files are disjoint from the current
one — as parallel candidates. Dispatch a lane with args:
Workflow({ scriptPath: "<this script>", args: {
repo: "D:/Users/Robert/Documents/GitHub/RvdB/OTGW-firmware-esp32s3-async-2",
branch: "feature-2.0.0-esp32s3-async-b",
targetTask: "TASK-865.12", // pin (parallel lanes do not share live status)
skipBump: true // defer the bump; integrate + bump + tag serially at merge
}})
Parallel-lane setup: git worktree add <dir> -b <sub-branch> dev,
copy other-projects/ + src/libraries/OpenTherm + src/libraries/SimpleTelnet
into it (the other-projects submodule remote 404s, so copy from a populated
worktree), then launch with the args above. Integration is serial: when a
sub-branch lane finishes, merge it into dev, run
bin/bump-prerelease.sh once for it (the deferred semver tag), resolve any
version-banner conflicts, then announce. Then DELETE the merged sub-branch
immediately: git branch -d <sub-branch>, git push origin --delete <sub-branch>,
and git worktree remove <dir>. Never leave a merged sub-branch (or its worktree)
lying around — that is the -jsonemit / -chunked proliferation cleaned up 2026-06-19
(maintainer directive: one async branch). Caution: parallel lanes that touch
overlapping files (loop edits in OTGW-firmware.ino, platform_esp32.h, version
banners) conflict at merge — only fan out file-disjoint tasks.
Notes
- Field/hardware ACs are never self-certified -> those tasks end In Review; the maintainer accepts the Proposed ADRs and closes field-validation under the epic.
- Single lane (the default) commits and pushes DIRECTLY on
devinOTGW-firmware— NO sub-branch.devIS the 2.0.0 async line now (one-branch maintainer directive 2026-06-19, branch model change 2026-06-20). Sub-branches/worktrees exist ONLY for genuine parallel lanes and are deleted right after merge (see Parallel lanes above). Never touchotgw-1.x.x(1.x maintenance) ormain(public release). - Rate-limit storms: the engine ends a run on a transient agent death after cleaning up; just re-run (cron does this every 30 min). The abort-cleanup is itself an agent and can die under heavy limiting — the launching session then cleans up manually (revert partial edits + reset the task To Do).
Signals
- GitHub stars
- 203
- Forks
- 44
- Last commit
- Sep 2026
Advanced
- Catalog kind
- skill
- Gateway key
implement-next-task- Source
- github.com/rvdbreemen/otgw-firmware