Given a GitHub issue number, plan and implement the work described in the issue. Operates iteratively - creates an implementation plan, responds to feedback, and only builds when the 'state:agent-ready' label is applied. Includes tests, documentation updates, and PR creation. Trigger keywords - build from issue, implement issue, work on issue, build issue, start issue.
71
88%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Low
Low-risk findings worth noting
Plan, iterate on feedback, and implement work described in a GitHub issue.
This skill operates as a stateful workflow — it can be run repeatedly against the same issue. Each invocation inspects the issue's labels, plan comment, and conversation history to determine the correct next action.
gh CLI must be authenticated (gh auth status)state:agent-ready Label Is Human-OnlyThe state:agent-ready label is a human gate. It signals that a human has reviewed the plan and authorized the agent to build. Under no circumstances should this skill or any agent:
state:agent-ready labelIf the label is not present, the agent must stop and wait. This is a non-negotiable safety control — it ensures a human explicitly authorizes every build.
This skill uses two distinct markers to identify its comments:
The implementation plan lives in a single comment that is edited in place as the plan evolves. It is identified by this marker on its first line:
> **🏗️ build-plan**All other comments (responses to human feedback, status updates, PR announcements) use this marker:
> **🏗️ build-from-issue-agent**These markers distinguish agent comments from human comments and from other skills (e.g., 🔒 security-review-agent, 🔧 security-fix-agent).
Each invocation follows this decision tree:
Fetch issue + comments
│
├─ No plan comment (🏗️ build-plan) found?
│ → Generate plan via principal-engineer-reviewer
│ → Post plan comment
│ → Add 'state:review-ready' label
│ → STOP
│
├─ Plan exists + new human comments since last agent response?
│ → Respond to each comment (quote context, address feedback)
│ → Update the plan comment if feedback requires plan changes
│ → STOP
│
├─ Plan exists + 'state:agent-ready' label + no 'state:in-progress' or 'state:pr-opened' label?
│ → Run scope check (warn if high complexity)
│ → Check for conflicting branches/PRs
│ → BUILD (Steps 6–14)
│
├─ 'state:in-progress' label present?
│ → Detect existing branch and resume if possible
│ → Otherwise report current state
│
├─ 'state:pr-opened' label present?
│ → Report that PR already exists, link to it
│ → STOP
│
└─ Plan exists + no new comments + no 'state:agent-ready'?
→ Report: "Plan is posted and awaiting review. No new comments to address."
→ STOPThe user provides an issue ID (e.g., #42 or 42). Strip any leading # and fetch:
gh issue view <id> --json number,title,body,state,labels,authorIf the issue is closed, report that and stop.
If the issue has the state:triage-needed label, report that the issue has not been triaged yet. Suggest using the triage-issue skill first to assess and classify the issue before planning implementation. Stop.
Fetch all comments:
gh issue view <id> --json comments --jq '.comments[] | {id: .id, body: .body, author: .author.login, createdAt: .createdAt, updatedAt: .updatedAt}'Classify each comment into one of:
> **🏗️ build-plan**> **🏗️ build-from-issue-agent**Record the plan comment's id (needed for editing via API) and its updatedAt timestamp.
Using the state machine above, determine what to do based on:
state:review-ready, state:agent-ready, state:in-progress, state:pr-opened)Follow the appropriate branch below.
If no plan comment exists, generate one.
Pass the issue title, description, labels, and any relevant code references to the principal-engineer-reviewer sub-agent. Use the Task tool:
Task tool with subagent_type="principal-engineer-reviewer"In the prompt, instruct the reviewer to:
feat (new feature), fix (bug fix), refactor, chore, perf, docs.docs/reference/gateway-config.mdx. If the change is surfaced through Helm or a compute-driver overview, also include docs/reference/sandbox-compute-drivers.mdx or the relevant deployment docs./proc filesystem access, binary execution, or inter-process visibility, flag whether it will behave differently on hosts running SELinux (enforcing) or AppArmor. In particular, tests that fork+exec into system binaries will fail on SELinux-enforcing hosts due to cross-label /proc/<pid>/exe access restrictions.Post the plan as a comment on the issue. This is the canonical plan comment that will be edited in place as the plan evolves.
gh issue comment <id> --body "$(cat <<'EOF'
> **🏗️ build-plan**
## Implementation Plan
**Issue type:** `<feat|fix|refactor|chore|perf|docs>`
**Complexity:** <Low|Medium|High>
**Confidence:** <High — clear path | Medium — some unknowns | Low — needs discussion>
### Summary
<2-3 sentences describing what will be built/changed and the approach>
### Scope
- `<file1>`: <what changes and why>
- `<file2>`: <what changes and why>
- ...
### Implementation Steps
1. <step 1 — independently testable>
2. <step 2>
3. ...
### Test Plan
- **Unit tests:** <what will be tested and where the tests live>
- **Integration tests:** <what will be tested, or "N/A" with rationale>
- **E2E tests:** <what will be tested, or "N/A" with rationale>
### Risks & Open Questions
- <risk or unknown that may need human input>
### Documentation Impact
- <docs expected per AGENTS.md, or "None expected">
---
*Revision 1 — initial plan*
EOF
)"state:review-ready Labelgh issue edit <id> --add-label "state:review-ready"Report to the user that the plan has been posted and is awaiting review. Stop.
If a plan exists and there are human comments newer than the last agent response, address them.
For each human comment that is newer than the most recent agent comment (plan updatedAt or conversation comment createdAt):
> blockquote syntax.gh issue comment <id> --body "$(cat <<'EOF'
> **🏗️ build-from-issue-agent**
> <quoted portion of human's comment>
<response addressing the feedback>
EOF
)"If any feedback requires changes to the plan, edit the existing plan comment rather than posting a new one. Use the GitHub API with the comment's node ID:
gh api graphql -f query='
mutation {
updateIssueComment(input: {id: "<comment-node-id>", body: "<updated body>"}) {
issueComment { id }
}
}
'Or use the REST API:
gh api repos/{owner}/{repo}/issues/comments/<comment-id> -X PATCH -f body="$(cat <<'EOF'
> **🏗️ build-plan**
## Implementation Plan
<... updated plan content ...>
---
*Revision <N> — <brief description of what changed>*
*Revision <N-1> — <previous change>*
*Revision 1 — initial plan*
EOF
)"Preserve the full revision history at the bottom so readers can track how the plan evolved.
Report to the user what feedback was addressed and whether the plan was updated. Stop.
If the plan exists and the state:agent-ready label is present (and neither state:in-progress nor state:pr-opened is set), proceed with implementation.
Read the plan comment and check the Complexity and Confidence fields.
If Complexity is High or Confidence is Low, warn the user:
"This issue is rated High complexity / Low confidence. The plan includes open questions that may need human decisions during implementation. Proceeding, but flagging this for your awareness."
Continue — do not hard-stop. The human chose to apply state:agent-ready.
Before creating a branch, check for conflicts:
git fetch origin
git branch -r | grep -i "<issue-id>"If a remote branch referencing this issue ID exists, report it and ask the user whether to continue on that branch or abort.
gh pr list --state open --search "Closes #<issue-id>" --json number,title,urlIf an open PR already references this issue, report it and stop. Do not create a competing PR.
Determine the branch prefix from the issue type in the plan:
| Issue type | Branch prefix |
|---|---|
feat | feat/ |
fix | fix/ |
refactor | refactor/ |
chore | chore/ |
perf | perf/ |
docs | docs/ |
Get the current username and create the branch:
USERNAME=$(gh api user --jq '.login')
git checkout main
git pull origin main
git checkout -b <prefix><issue-id>-<short-description>/$USERNAMEstate:in-progress Labelgh issue edit <id> --add-label "state:in-progress"Follow the implementation steps from the plan. Principles:
Read the relevant source files before making changes. Implement step by step per the plan's sequence.
Write tests as specified in the plan's Test Plan section. Follow the project's existing test conventions.
#[cfg(test)] blocks in Rust, test_*.py for Python)Use descriptive names that document intent:
test_pagination_returns_correct_page_counttest_rejects_negative_offset_parametertest_retry_succeeds_after_transient_failureVerification has two phases: unit tests + pre-commit, then E2E tests (if applicable). Run with up to 3 attempts per phase.
On each attempt:
# Run pre-commit checks (includes unit tests, linting, formatting)
mise run pre-commitIf verification fails:
If all 3 attempts fail, stop and report to the user:
Do not proceed to Phase 2 or PR creation if Phase 1 is not green.
Trigger: Run this phase if any files under e2e/ were added or modified in this build. Check with:
git diff --name-only main -- e2e/If there are no changes under e2e/, skip this phase entirely.
If E2E files were modified, run the relevant E2E lane for the driver touched by the change:
# Docker-backed gateway smoke E2E
mise run e2e:dockerUse mise run e2e:podman, mise run e2e:vm, or a Helm-backed Kubernetes E2E lane when the change targets those drivers.
E2E retry loop (up to 3 attempts):
If all 3 E2E attempts fail, stop and report to the user:
Do not proceed to PR creation if E2E verification is not green.
Review the documentation requirements in AGENTS.md and update any affected
docs as part of the implementation. Keep documentation changes scoped to the
behavior or subsystem that changed.
If the implementation changes gateway TOML parsing, [openshell.gateway]
fields, [openshell.drivers.<name>] fields, driver config defaults, or Helm
rendering of gateway.toml, update docs/reference/gateway-config.mdx in the
same branch. If the change affects user-facing compute-driver setup, also
update docs/reference/sandbox-compute-drivers.mdx or the relevant deployment
page.
Use the sync-agent-infra skill's maintenance map to identify related skill updates when the implementation changes behavior, commands, or development workflows. Run its full consistency check when the implementation adds, removes, or renames skills or crates; changes workflow relationships or skill coverage; modifies issue or PR templates; or changes agent cross-references. Fix any drift before committing.
Commit all changes using conventional commit format. The <type> comes from the issue type in the plan:
git add <files>
git commit -m "$(cat <<'EOF'
<type>(<scope>): <short description>
Closes #<issue-id>
<brief explanation of what was implemented>
EOF
)"Push:
git push -u origin HEADCreate the PR:
gh pr create \
--title "<type>(<scope>): <short description>" \
--body "$(cat <<'EOF'
> **🏗️ build-from-issue-agent**
## Summary
<1-3 sentences describing what was built and the approach taken>
## Related Issue
Closes #<issue-id>
## Changes
- `<file1>`: <what changed and why>
- `<file2>`: <what changed and why>
### Deviations from Plan
<any deviations from the approved plan, or "None — implemented as planned">
## Testing
- [x] `mise run pre-commit` passes
- [x] Unit tests added/updated
- [x] E2E tests added/updated (if applicable)
**Tests added:**
- **Unit:** <test file(s) and what they cover>
- **Integration:** <test file(s) and what they cover, or "N/A">
- **E2E:** <test file(s) and what they cover, or "N/A">
## Checklist
- [x] Follows Conventional Commits
- [x] Commits are signed off (DCO)
**Documentation updated:**
- `<doc path>`: <what was updated, or "None needed">
EOF
)"Display the PR URL so it's easily clickable:
Created PR [#<number>](https://github.com/OWNER/REPO/pull/<number>)gh issue comment <id> --body "$(cat <<'EOF'
> **🏗️ build-from-issue-agent**
## Implementation Complete
PR: [#<pr-number>](https://github.com/OWNER/REPO/pull/<pr-number>)
### What was built
<1-2 sentence summary>
### Tests
- Unit: <count> tests added
- Integration: <count or N/A>
- E2E: <count or N/A>
### Docs updated
- <list of updated docs, or "None needed">
The issue will auto-close when the PR is merged.
EOF
)"If E2E tests were run in Phase 2 of Step 10, post an attestation comment on the PR documenting that local E2E tests passed. This is necessary because E2E tests are not yet running in CI — this comment serves as the verification record for reviewers.
Collect the metadata before posting:
# Get the commit SHA that was tested
COMMIT_SHA=$(git rev-parse HEAD)
# Get the test output summary (last few lines of pytest output)
# This was captured during the Phase 2 run — include the pass/fail/skip countsPost the attestation:
gh pr comment <pr-number> --body "$(cat <<'EOF'
> **🏗️ build-from-issue-agent**
## E2E Test Attestation
Local E2E tests passed. CI does not currently run E2E tests, so this comment serves as the verification record.
| Field | Value |
|-------|-------|
| **Commit** | `<commit-sha>` |
| **Command** | `<selected e2e command>` |
| **Gateway mode** | `<docker / podman / vm / helm>` |
| **Result** | ✅ All passed |
### Test Summary<paste the pytest summary line, e.g.: "12 passed, 1 skipped in 45.32s">
### Tests Executed
- `<test_file.py>::<test_name>` — PASSED
- `<test_file.py>::<test_name>` — PASSED
- ...
EOF
)"Include every test that ran (not just the new ones) so the reviewer can see full coverage. If any tests were skipped, note them and explain why.
Remove state:in-progress and state:review-ready, add state:pr-opened:
gh issue edit <id> --remove-label "state:in-progress" --remove-label "state:review-ready" --add-label "state:pr-opened"Get the workflow run URL from the PR so the user can monitor CI:
BRANCH=$(gh pr view <pr-number> --json headRefName --jq '.headRefName')
gh run list --branch "$BRANCH" --limit 1 --json databaseId,status,urlReport the workflow run URL and suggest the user can use the watch-github-actions skill to monitor it.
If the state:in-progress label is present, the skill was previously started but may not have completed.
git branch -r | grep -i "<issue-id>"state:in-progress label and re-run).| Command | Description |
|---|---|
gh issue view <id> --json number,title,body,state,labels,author | Fetch full issue metadata |
gh issue view <id> --json comments | Fetch all comments on an issue |
gh issue comment <id> --body "..." | Post a comment on an issue |
gh api repos/{owner}/{repo}/issues/comments/<id> -X PATCH -f body="..." | Edit an existing comment |
gh issue edit <id> --add-label "..." | Add labels |
gh issue edit <id> --remove-label "..." | Remove labels |
gh pr list --state open --search "..." | Search for open PRs |
gh pr create --title "..." --body "..." | Create a pull request |
gh api user --jq '.login' | Get current GitHub username |
mise run pre-commit | Run pre-commit checks (includes unit tests, lint, format) |
mise run e2e:docker | Run smoke E2E against a standalone Docker-backed gateway |
mise run e2e:podman | Run smoke E2E against a Podman-backed gateway |
mise run e2e:vm | Run smoke E2E against the VM compute driver |
User says: "Build from issue #42"
🏗️ build-plan marker foundprincipal-engineer-reviewer for analysis🏗️ build-plan markerstate:review-ready labelUser says: "Check on issue #42"
User says: "Check issue #42"
User says: "Build issue #42"
state:agent-readyfeat/42-add-pagination/jmyersstate:in-progress labelmise run pre-commit passes on first attempte2e/)Closes #42state:in-progress + state:review-ready, add state:pr-openedUser says: "Build issue #42"
state:pr-opened label presentUser says: "Build issue #99"
state:agent-ready label presentdeced87
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.