Install
$ agentstack add skill-aberson-claude-skills-build-queue ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Build Queue
/build-queue --queue runs an unattended overnight orchestration of multiple phase plans. Each queue item gets the full /plan-expedite -> /build-phase chain. Halts are converted to GitHub issues, not retries — the operator triages in the morning from the summary report.
Constraints
Execution model: autonomous, queue-driven, halt-then-proceed (HEAVY). This skill exists so the operator can stage 3-5 pending phase plans, kick off /build-queue before bed, and wake up to a triage list. The whole point is that no halt — even a reviewer-gate failure on a code step — pulls the operator out of bed. Therefore:
- Halt-then-proceed, not halt-then-retry. This is the load-bearing design choice. When any queue item halts (via the
/build-phasehalt contract — see [.claude/rules/code-quality.md§ "Build-phase halt contract"](../../rules/code-quality.md)), this skill does NOT auto-retry, does NOT mutate the plan, does NOT try a different approach. It captures the halt context, files a single GitHub issue on the plan's repo titled[build-queue parked] :, marks the queue item asPARKED, and proceeds to the next item. Auto-retry would fight the halt contract (5 legitimate halts, anything else is a defect) and burn tokens on undiagnosable failures. The operator's morning triage IS the retry decision.
- Sequential, never parallel. Queue items run one at a time. Parallel
/build-phaseon different plans has burned tokens in the past (memory:feedback_parallel_buildphase_same_plan). The queue's whole value is honest, sequential, surviveable execution.
- Kill-switch is the only mid-run control. Between queue items, this skill checks for a
.build-queue-killswitchfile in the queue file's directory. If present (any contents, any size), it stops cleanly after the current item: writes a partial morning summary noting the kill-switch was hit, persists state for resume, and exits. The operator creates it withtouch /.build-queue-killswitch. The skill never asks "should I continue?" — the file is the answer.
- Final output is the morning summary, verbatim. When the queue drains (or the kill-switch stops it), the morning summary IS the final output. It is also written to
.build-queue-report-.mdnext to the queue file for later reference.
This is by strong operator preference; treat any deviation as a defect.
When to use
- 3+ phase plans are staged across one or more projects and can ship overnight unattended.
- The operator has time to triage parked items in the morning but does not want to babysit reviewer gates at 3am.
- Plans have already been through
/plan-expediteonce (issues minted) OR are fresh and want the full prep chain —/build-queuecalls/plan-expediteper item, so either is fine.
When NOT to use
- Single phase: use
/build-phasedirectly (or/plan-expedite+/build-phaseif not yet prepped). - Plans with
Type: waitsteps as the only remaining work —/build-phasewill halt on wait steps and/build-queuewill park them; nothing useful happens overnight. - Mid-day interactive work where the operator wants to react to each halt — the park-then-proceed posture is wrong for that mode.
- When the queue's plans are not yet through
/plan-reviewand/plan-wrap— let/plan-expedite(invoked per-item by this skill) handle it.
Arguments
| Arg | Required | Default | Description | |---|---|---|---| | --queue | yes | -- | Path to queue file (see "Queue file format" below) | | --dry-run | no | -- | Parse queue + print resolved item list + exit. No /plan-expedite or /build-phase calls. | | --resume | no | -- | Resume from a prior partial run. Skips queue items already marked DONE or PARKED in .build-queue-state. |
No other flags. Per-item flags (which /build-phase to run, phase number, etc.) live in the queue file, not on the /build-queue invocation.
Queue file format
Plain text. One queue item per non-blank, non-comment line. Comments start with #.
# Each line: [--phase N] [extra build-phase flags]
# Plan paths resolve relative to the queue file's directory if not absolute.
documentation/phase-g-plan.md
documentation/phase-2.1-plan.md --phase 1
../toybox/documentation/phase-n-plan.md
../alpha4gate/documentation/phase-4.7-plan.md --phase 2 --steps 1,2,3
Parse rules:
- Lines starting with
#are comments; ignored. - Blank lines ignored.
- First whitespace-separated token is the plan path; everything else is forwarded to
/build-phaseas flags. - A plan path containing whitespace must be wrapped in double quotes (rare on this workspace).
- Order = execution order. No reordering.
At Step 0 pre-flight, resolve every plan path to an absolute path and verify the file exists. Any missing plan path is a queue-level pre-flight error: print all missing paths and exit without running anything. (Halting mid-queue on a typo would waste the night.)
Steps
Step 0: Pre-flight
Before invoking any sub-skill, do all of the following. Halt the entire run on any failure here — these are setup errors that compound if ignored.
- Kill-switch check. If
.build-queue-killswitchexists in the queue file's directory at startup, printkill-switch present at startup; refusing to run. rm to clear.and exit. The operator may have forgotten it from a prior session.
- Parse queue file. Apply the parse rules above. Emit a resolved table of
(item-index, abs-plan-path, forwarded-flags).
- Verify plan files exist. For each resolved plan path, check the file exists and is readable. Collect all failures; if any, print the full list and exit.
- State file check. Look for
.build-queue-statein the queue file's directory (schema below). If--resumewas passed:
- If the file exists AND its
queue_pathmatches AND itsqueue_mtimematches the current queue file's mtime (1-second tolerance): use the existing state, skip items already marked DONE or PARKED. - If the file exists BUT the queue file has been edited since: discard and start fresh (print a warning).
- If the file does not exist: start fresh.
- If
--resumewas NOT passed and the state file exists: rename it to.build-queue-state.prior-and start fresh. (Resume is opt-in to avoid silent surprises.)
- Dry-run exit. If
--dry-runwas passed, print the resolved item list (including which items would be skipped under--resume) and exit without invoking any sub-skill.
Step 1: Per-item loop
For each queue item in order (skipping those already DONE or PARKED under --resume):
- Kill-switch poll (between items). Check for
.build-queue-killswitch. If present: write a partial morning summary noting the kill-switch was hit before item N, persist state, exit.
cdto plan's project root. This is the directory containing the plan file. All subsequentghand worktree calls must run from here, not from the queue file's directory. (ghrepo context — see [.claude/rules/windows-shell.md](../../rules/windows-shell.md).)
- Invoke
/plan-expeditevia the Skill tool withargs: "--plan ".
- Success: proceed to step 4.
- Halt: park this item (see "Park procedure" below). Proceed to next item.
- Invoke
/build-phasevia the Skill tool withargs: "--plan ".
- Success: append the DONE entry below to
.build-queue-state'sitems[]. Proceed to next item. - Halt: park this item (PARKED entry shape below). Proceed to next item.
- State file update. After each item (DONE or PARKED), rewrite
.build-queue-state(exact filename, in the queue file's directory) as a complete, valid JSON document — not an incremental append — BEFORE moving to the next item. The fullitems[]array (all entries so far) must be present. Each entry must includeitem,plan,verdict, andtimestampkeys; DONE entries additionally includecommitsandissues_closed; PARKED entries additionally includehalt_reasonandissue(number or null). If the process is killed mid-loop, the next--resumerun starts from the right place.
DONE entry appended to .build-queue-state:
``json {"item": 1, "plan": "C:/.../phase-g-plan.md", "verdict": "DONE", "timestamp": "2026-05-23T22:47:00Z", "commits": 7, "issues_closed": [41, 42, 43]} ``
PARKED entry appended to .build-queue-state:
``json {"item": 2, "plan": "C:/.../phase-2.1-plan.md", "verdict": "PARKED", "timestamp": "2026-05-23T23:18:00Z", "halt_reason": "Quality-gate hard fail", "issue": 99} ``
When narrating per-item completion in the run output, refer to the state file as .build-queue-state (exact filename — not "the state file" or "state was updated") and include the appended JSON entry verbatim, so the appended shape and the filename are both visible per item.
Park procedure (on any halt)
When /plan-expedite or /build-phase halts for any reason — halt contract, autofix failure, missing plan field, anything:
- Capture context. Grab:
- The halt message verbatim (from the sub-skill's final output).
- The plan path (absolute).
- The queue item index.
- Current branch + last commit on the worktree, if a worktree exists (
git worktree listshows it). - Timestamp.
- File a GitHub issue. From the plan's project root (cwd from Step 1.2), use
gh issue createwith--body-file(NOT inline--body— workspace rule). Title:[build-queue parked] :. Body:
```markdown ## Parked by /build-queue
- Queue item: of
- Plan:
- Timestamp:
- Worktree:
- Branch:
- Last commit:
## Halt output
## Resume
Triage this halt, then either:
- Fix and re-run the single plan:
/plan-expedite --planthen/build-phase --plan - Remove the item from the queue (or mark it DONE in the queue file via comment) and resume the overnight:
/build-queue --queue --resume
```
On gh failure (rate limit, auth, repo not found): print the captured context to stdout AND write it to .build-queue-park-item-.md next to the queue file. The item still gets marked PARKED in state — the issue filing is best-effort observability, not a halt condition.
- State file update. Append
{"item": N, "verdict": "PARKED", "plan": "", "halt_reason": "", "issue": , "timestamp": ""}toitems[].
- Proceed. Continue the loop. Do NOT halt the overnight run on a park — that's the whole design.
Step 2: Morning summary
After the loop drains (or the kill-switch stops it), emit the morning summary to stdout AND write it to .build-queue-report-.md in the queue file's directory.
# /build-queue summary
Queue:
Started:
Ended:
Duration:
Status:
## Items
| # | Plan | Verdict | Commits | Issues closed | Park issue |
|---|------|---------|---------|---------------|------------|
| 1 | phase-g-plan.md | DONE | 7 | #41, #42, #43 | -- |
| 2 | phase-2.1-plan.md | PARKED | 2 | #44 | #99 |
| 3 | phase-n-plan.md | DONE | 5 | #50, #51 | -- |
| 4 | phase-4.7-plan.md | SKIPPED (kill-switch) | -- | -- | -- |
## Triage list (parked items)
- #99 (phase-2.1, item 2): — see issue for context.
## Numbers
- Items attempted: 3 of 4
- Items DONE: 2
- Items PARKED: 1
- Items SKIPPED: 1 (kill-switch)
- Total commits landed: 12
- Total issues closed: 5
- Total park issues filed: 1
When there are zero parked items, the "Triage list" section is omitted. When there are zero DONE items, that's worth surfacing prominently at the top of the summary ("Status: COMPLETE (0 of N items DONE — investigate").
State file schema
.build-queue-state in the queue file's directory, JSON. Gitignored.
{
"queue_path": "queue.txt",
"queue_mtime": 1779200000.0,
"started": "2026-05-23T22:00:00Z",
"items": [
{
"item": 1,
"plan": "C:/.../phase-g-plan.md",
"verdict": "DONE",
"commits": 7,
"issues_closed": [41, 42, 43],
"timestamp": "2026-05-23T22:47:00Z"
},
{
"item": 2,
"plan": "C:/.../phase-2.1-plan.md",
"verdict": "PARKED",
"halt_reason": "Quality-gate hard fail (test count regressed)",
"issue": 99,
"timestamp": "2026-05-23T23:18:00Z"
}
],
"kill_switch_hit_before_item": null
}
Comparison uses 1-second tolerance for queue_mtime (same NTFS/FAT32 reasoning as /plan-expedite's state file).
Malformed state file under --resume: rename to .build-queue-state.malformed- and start fresh with a warning. Do NOT halt — this is observability state, not load-bearing.
Relationship to other skills
| Skill | Role | |---|---| | /plan-expedite | Invoked per-item to prep each plan (plan-review-autofix + plan-wrap-autofix + repo-sync + session-wrap) | | /build-phase | Invoked per-item to execute the plan's build steps; the halt contract here is the source of truth for what halts mean | | /loop | Different shape — /loop repeats one prompt on an interval; /build-queue drains a queue of distinct plans once | | /repo-update | Not invoked by this skill; each /build-phase step closes its own issue, but the post-phase docs+README+commit pass is left for the operator to run per-project in the morning |
Limitations
- One queue at a time per directory. Two
/build-queueruns on the same queue file have undefined behavior (state file races). Don't do that. - Per-item halts file an issue on the plan's repo — requires
gh auth statusto be valid for every distinct repo in the queue. Pre-flight does NOT verifygh authper repo; first halt on a non-authed repo falls back to the local.build-queue-park-item-N.mdfile. - No cross-item dependencies. If item 2's plan depends on item 1 landing first, that's an ordering responsibility of the operator (and the queue ordering preserves it). The skill does not detect dependency violations.
- No auto-rollback. If a
/build-phaselands partial commits then halts mid-step, those commits remain on the branch./build-phaseitself does not roll back;/build-queuedoes not either. The morning triage owns rollback decisions. - The morning summary's "commits landed" and "issues closed" counts come from
/build-phase's own state output, NOT a separategit logscan. If/build-phaselies or under-reports, the summary inherits that.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: aberson
- Source: aberson/claude-skills
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.