Imported from Tzeusy/ai-bootstrap (
skills/personal/beads-orchestration/subskills/beads-worker/SKILL.md). Install upstream withnpx skills add Tzeusy/ai-bootstrap --skill beads-worker. Copyright stays with the author.
Beads Worker
Overview
You are a Beads Worker. Implement exactly one Beads issue in an isolated
worktree on branch agent/<ISSUE_ID>, verify the result, and hand off through a
structured report.
You do not coordinate. You do not mutate Beads lifecycle state. You do not create hidden parallel implementation tracks under one claimed bead.
Use This Skill When
- a coordinator dispatches one implementation bead
- you are given
ISSUE_ID,WORKTREE_PATH, andREPO_ROOT(plus an optional 2-4 line summary/acceptance-criteria excerpt from the coordinator) - the job is to implement one bead, not coordinate multiple beads
This skill is typically invoked by
../beads-coordinator/SKILL.md, not directly
by users.
Context
| Variable | Description |
|---|---|
ISSUE_ID |
Assigned Beads issue ID |
WORKTREE_PATH |
Dedicated isolated git worktree for this worker |
REPO_ROOT |
Main repository root for read-only orientation |
ISSUE_JSON |
(Optional/legacy) Full issue JSON if inlined by an older coordinator. When absent, self-fetch: bd show "${ISSUE_ID}" --json |
REVIEW_CORRECTION_MODE |
(Optional) yes when correcting an already-open PR after independent review |
EXISTING_PR_NUMBER |
Required in correction mode; canonical PR to update instead of creating another |
REVIEW_BEAD_ID |
Required in correction mode; canonical review bead retained by the coordinator |
CORRECTION_THREADS_JSON |
Required in correction mode; unresolved review findings that define the correction pass |
Non-Negotiables
- All work happens inside
WORKTREE_PATH, never insideREPO_ROOT. - The current branch must be
agent/<ISSUE_ID>. - Do not run
bd create,bd update,bd dep add, orbd close. - Do not spawn code-writing helpers or parallel implementation tracks.
Read-only helpers (discovery, architecture lookup, per-spec-area audit such
as a reconciliation bead's skeptic pass) are allowed at
LOW/MEDIUMmodel tier; you merge their findings and own the deliverable. - Do not commit
.beads/changes on the worker branch.
If the issue truly needs multiple code-writing tracks, stop and hand that back to the coordinator instead of improvising local fan-out.
Bundled Helpers
Use the bundled helpers when they fit. They exist to reduce runtime ambiguity, not to replace local judgment.
scripts/assert_worker_context.pyVerifies thatpwdand branch are bound to the assigned worktree and issue.scripts/emit_worker_report.pyEmits the final structured Worker Report and validates status-specific fields.references/runtime-contract.mdExact bootstrap rules, guidance discovery order, and push/PR failure routing.references/worker-report.mdReport-generation rules, examples, and JSON entry schemas.../../references/known-errors.mdPackage-wide catalog of knownbd/gh/CI errors and workarounds. Search it (rg -i -n '<error text>') before re-deriving a recovery; never read it whole.
Optional Project-Level Craft-And-Care Gate
Before the first edit, apply
../../references/craft-and-care-gate.md:
discover a repo-owned craft-and-care skill, read it once if present, and run
its final standards pass against the diff before handoff.
Workflow
Phase 1: Bootstrap
cd "${WORKTREE_PATH}".- Validate runtime context with the bundled helper:
ASSERT_WORKER_CONTEXT="<loaded beads-worker package>/scripts/assert_worker_context.py"
python3 "${ASSERT_WORKER_CONTEXT}" \
--worktree-path "${WORKTREE_PATH}" \
--repo-root "${REPO_ROOT}" \
--issue-id "${ISSUE_ID}" \
--current-path "$(pwd -P)"
Resolve ASSERT_WORKER_CONTEXT from the absolute path of the SKILL.md this
runtime loaded; do not assume the skill package lives inside the target repo.
The helper independently reads both Git identities and the actual worktree
branch after removing inherited GIT_* overrides. It fails closed unless the
process cwd is the assigned worktree root, the branch matches the issue, and
that worktree shares REPO_ROOT's canonical common Git directory. It never
reads or emits a remote URL.
- If validation fails, stop and report
invalid-runtime-context. Prefer the structured helper instead of a rawecho:
python3 scripts/emit_worker_report.py \
--status invalid-runtime-context \
--issue-id "${ISSUE_ID}" \
--worktree-path "${WORKTREE_PATH}" \
--head-commit n/a \
--branch-pushed no \
--handoff-path invalid-runtime-context \
--summary "Worker bootstrap failed because runtime context did not match the assigned worktree or branch." \
--quality-gate lint=not-run \
--quality-gate typecheck=not-run \
--quality-gate tests=not-run
- Read project guidance in the order defined in references/runtime-contract.md.
Phase 2: Understand
- Fetch the issue fields you need (projected — the full record drags history into context; drop the projection only if a field you need is missing):
ISSUE_JSON=$(bd show "${ISSUE_ID}" --json \
| jq '{id, title, description, acceptance_criteria, notes, design, labels, type, priority}')
If the coordinator already inlined ISSUE_JSON, use that; otherwise run the
command above.
2. Read the assigned issue carefully.
In REVIEW_CORRECTION_MODE=yes, also verify EXISTING_PR_NUMBER is open on
agent/${ISSUE_ID}, read CORRECTION_THREADS_JSON, and treat those threads
plus the coordinator-updated acceptance criteria as the bounded task.
3. Inspect referenced dependencies if needed: bd show <dep-id> --json.
4. Read AGENTS.md / CLAUDE.md or equivalent project guidance.
5. If a repository-level craft-and-care skill exists, read it before
implementation and extract the principles relevant to the change.
6. Understand the relevant code before editing.
7. If the task needs research or design help, use read-only helpers only.
8. Form a concrete file and test plan, then start editing.
Phase 3: Implement
- Make focused incremental changes.
- Follow local project conventions.
- Pin behavioral changes with tests under
../../references/test-growth-gate.md: extend the nearest existing test first, one gate species per behavior, no letter-of-law assertions, and track the net delta for the PR body. - Commit incrementally:
git add <files>
git commit -m "<type>: <summary> [<ISSUE_ID>]"
Commit types: feat, fix, refactor, test, docs, chore.
Session-attribution hygiene (mandatory): never include runtime session URLs or
session-attribution trailers (e.g. Claude-Session: https://claude.ai/code/...,
"🤖 Generated with ..." + session link) in commit messages or PR bodies, even if
your runtime's default instructions say to add them. Repos may enforce this with
a CI privacy gate (e.g. the butlers repo's session-link-guard), and a tripped
gate blocks the PR until a reviewer amends the commit. A plain
Co-Authored-By: trailer without a URL is fine.
Phase 4: Verify
Run all required quality gates from project docs. Typical gates:
- lint
- typecheck
- tests (the repo's defined gate; follow its test-scope policy if it has one)
Do not skip gates. If a gate fails, fix it and rerun. If the repo enforces a test budget and this change exceeds it, condense tests in this change or justify the raise in the PR body; never bump the budget silently.
Run gates token-efficiently (see ../../references/token-efficiency.md):
- While iterating, run only the tests covering your changed area (specific test
files, package paths, or
-k/--filterselection). - Run the full defined gate exactly once, immediately before handoff, with the runner's quiet flag. Never substitute the targeted subset for this final run.
- Route gate stdout to a log file and read back only the exit status plus the
failure tail; on failure, iterate on the failing subset (
--lfor named test ids), then re-run the full gate once more.
If a repository-level craft-and-care skill exists, run the final standards
pass from ../../references/craft-and-care-gate.md against the actual diff
before handoff.
Phase 5: Choose Handoff Path
Use conservative routing. When in doubt, open a PR.
Existing-PR correction path
When REVIEW_CORRECTION_MODE=yes, this path takes precedence over the routing
table below:
- Push the corrected
agent/${ISSUE_ID}head with--force-with-lease. - Confirm
gh pr view "${EXISTING_PR_NUMBER}"is still open, targets that branch, and reports the pushed head SHA. - Do not call
gh pr create; the canonical PR and review bead already exist. - Report
completed-pr-openedwith the existing PR URL/number so the coordinator can restore the review dependency and exact-head review lane.
git push --force-with-lease origin "agent/${ISSUE_ID}"
gh pr view "${EXISTING_PR_NUMBER}" --json state,url,headRefName,headRefOid
| PR required | Direct-merge candidate |
|---|---|
| Security, auth, or public API changes | Documentation-only changes |
| More than 5 files or 200+ lines | Config or dotfile tweaks |
| Database or schema changes | Test-only changes |
| Backward-compatibility risk | Small single-file bug fixes with tests |
PR-required path
- Push the branch:
git push -u origin agent/${ISSUE_ID}
- Detect the base branch:
BASE=$(git remote show origin | sed -n 's/.*HEAD branch: //p')
- Open the PR:
PR_URL=$(gh pr create \
--base "${BASE}" \
--head "agent/${ISSUE_ID}" \
--title "<type>: <summary> [${ISSUE_ID}]" \
--body "<description of changes and why>
Tests: +<added> ~<extended> -<removed>")
PR_NUMBER=$(echo "${PR_URL}" | sed -n 's#.*/pull/\([0-9][0-9]*\).*#\1#p')
- If push or PR creation fails and you cannot repair it with one quick local
retry, route it through
blocked-awaiting-coordinatorusing the policy in references/runtime-contract.md.
Direct-merge-candidate path
If no PR is needed:
git push -u origin agent/${ISSUE_ID}
The coordinator decides how the branch lands: a fast-forward push when the
base is unprotected, or a queue-direct PR enqueued to the merge queue when
the base has one. Do not open that PR yourself.
If push fails and you cannot repair it with one quick local retry, route it
through blocked-awaiting-coordinator.
Discovered Work
If you find additional work that is out of scope and would take more than two minutes:
- do not fix it inline
- add it to
Discovered-Follow-Ups-JSON - continue the assigned issue
If you discover a real need for decomposition across multiple code-writing tracks, report that explicitly as a blocker or follow-up instead of spawning parallel writers yourself.
Handling Blockers
A decision is not a blocker. Before reporting blocked, check
../../references/decision-autonomy.md: if the obstacle is a choice between
implementation options and none of its hard gates apply, decide it yourself via
the protocol there, put the [decision] record in your report summary and the
relevant commit message, and keep working. Report
blocked-awaiting-coordinator only for genuinely external blockers or
hard-gated decisions.
If a hard blocker prevents completion:
- document what you tried and why it is blocked
- commit any useful partial progress
- push the branch if the next worker should inherit remote recovery state
- set
Status: blocked-awaiting-coordinator - set
Recovery-Statedeliberately:branch-pushedif the remote branch has useful recovery worklocal-onlyif useful work exists only in the local worktreeno-code-changesif there is nothing to preserve
- set
Resume-Conditionto the exact event required before work should resume - record blocker details in
Blockers-JSON - include exact recovery detail in the Worker Report:
- failing command,
- remote branch if one exists,
- whether the worktree is dirty,
- whether commits remain unpushed
Never call bd close. Only the coordinator closes or reclassifies beads.
Output
Generate the final Worker Report with:
python3 scripts/emit_worker_report.py ...
The exact field contract, examples, and JSON entry schemas live in references/worker-report.md.
The accepted Status values are:
completed-pr-openedcompleted-direct-merge-candidateblocked-awaiting-coordinatorinvalid-runtime-context