Install
$ agentstack add skill-swell-agents-coding-skills-creating-block-issues ✓ 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
When this skill applies
The target repo is a Spec Kit project: .specify/ exists at repo root, and at least one specs/-/tasks.md is present with #### Block — PR-stack headings (the structure produced by /coding-skills:speckit-tasks and aligned with [implementing-blocks](../implementing-blocks/SKILL.md)). The repo has a GitHub origin remote.
This skill creates one tracking issue per Block, not per task. No epic, no per-task issues. Whoever picks up the issue (a human assignee or an automation pipeline that polls GitHub) runs the block-implement loop. The issue body is intentionally minimal (4 short bullets: pointer, heading, a 1-2 sentence summary, task IDs) and points at tasks.md as the source of truth; constitution, scars, conventions, and per-task acceptance criteria are NOT duplicated per issue (the assignee reads them from the file at implementation time).
If the repo is not a Spec Kit project, or tasks.md does not use the #### Block structure, fall back to manual gh issue create per the project's own issue conventions.
Issue template (load-bearing)
Every block-issue body MUST match this exact shape — keeping the body minimal is the contract. Drift between issue and tasks.md is what we are explicitly avoiding:
- **Spec:** `specs/-/tasks.md`
- **Block:** Block — (verbatim from the `####` heading in tasks.md)
- **What:**
- **Tasks:** T0NN-T0NN (tests), T0NN-T0NN (impl)
- **Notes:**
That is the entire body. No "ready criteria" recap, no scar list, no dispatch boilerplate. The What line is a hook for humans scanning the issue list (and for the dispatch daemon's logs), not a second spec: hard cap of 2 sentences, summarize rather than enumerate, and never let it contradict tasks.md — when in doubt, say less and let the pointer carry the detail.
Cross-block dependencies are NOT recorded in the body. They go through GitHub's native Issue Dependencies feature (right sidebar → Development / Dependencies → Blocked by). Body-field "Blocked by: #N" lines drift away from reality the moment an issue closes; the native graph stays accurate.
Labels
Every issue this skill creates carries the swa-impl-block label. The label is the dispatch signal a downstream coder-agent daemon polls for; an unlabeled block-issue silently never gets picked up. The skill auto-creates the label in the target repo if missing (color #0E8A16, description Spec Kit block-implement dispatch (coder-agent)).
Additional project-specific labels (ready, priority, milestone) are NOT applied here — add them after creation with gh issue edit --add-label or via the GitHub UI.
If a consuming repo wants a different dispatch label name (or none), it can override at invocation time by passing --label / --no-label through the wrapping /coding-skills:block-issues command. The default stays swa-impl-block.
Execution flow
- Resolve active feature. Read
.specify/feature.jsonforfeature_directory. If absent, fall back to the current branch's-prefix. Resolve tospecs//tasks.md. Abort with a clear error message if no Spec Kit feature is detectable.
- Verify GitHub remote. Run
git config --get remote.origin.url. Must be a GitHub URL (github.com:owner/repo.gitorhttps://github.com/owner/repo.git). Echo the resolved/back to the user before any state-changing operation. Never create issues in a repo whoseoriginURL was not just echoed.
- Parse tasks.md. Extract all
#### Block —headings. For each block:
- Block letter (A, B, C, ...).
- Short name (the part after
—). - Task ID ranges: tests subsection (from the block heading down to the next
####or###boundary in the "Tests for User Story" parent) + impl subsection (same scoping in the "Implementation for User Story" parent). - The What summary: compose 1-2 sentences from the parent user story's Goal line plus the block's own task texts (what gets built, why it exists). Do not copy the Goal verbatim when it spans multiple blocks — scope the sentence to this block's slice.
- Optional block-level Notes from the caller (CLI arg or skill input); skip the Notes line if nothing was provided.
3a. Coverage check (every task belongs to a block). Collect every - [ ] T\d{3} task ID in the file and verify each falls inside some block's heading-to-next-boundary range. Tasks outside any block (the classic case: a final "Polish & Cross-Cutting" phase with no #### Block heading) are an ERROR, not a silent skip — they would never get an issue and the feature ships without its closeout (scar: swell-storage-contracts 001 and 002 both needed manual post-hoc closeouts for exactly this). On uncovered tasks: report the orphaned IDs and ask the user whether to (a) fix tasks.md first by wrapping them in a ### Block : Closeout (PR-) heading (preferred; re-run after), or (b) proceed creating issues for covered blocks only, explicitly accepting the gap. Never proceed silently.
- Surface the plan before any write. Echo the parsed block list + the resolved
/+ the would-be issue titles to the user. If the caller passed--dry-run, stop here and also render each issue's body verbatim; do NOT proceed to issue creation.
- Check for existing block-issues. Run
gh issue list --search "Implement Block in:title" --state allfor each block. If any return a non-empty match, abort and report the existing issue numbers. Ask the user how to proceed (re-open via UI, skip the block, supersede with a new issue manually). Never overwrite or auto-close.
- Ensure dispatch label exists (unless
--no-labelwas passed). Resolve the label name (defaultswa-impl-block, override via--label). Rungh label list --searchto check. If absent, create it idempotently:
``bash gh label create swa-impl-block \ --description "Spec Kit block-implement dispatch (coder-agent)" \ --color "0E8A16" ``
If gh label create fails because the label already exists (race), proceed silently. If it fails for any other reason (permissions), abort before creating any issues.
- Create issues (one per block, in tasks.md order):
``bash gh issue create \ --title "Implement Block — " \ --body "" \ --label swa-impl-block ``
Omit --label only when --no-label was passed. Capture the returned issue number per block.
- Set Blocked-by relations via GraphQL (Mode 1 only; skip in Mode 2 since custom subsets have no pre-known dep graph). Parse the "Block Dependency Graph" or "Dependencies & Execution Order" section of tasks.md to extract
{blocked_issue: [blocking_issues...]}pairs. Then:
a. Fetch node IDs for every created issue in one batched query:
``bash gh api graphql -f query=' { repository(owner: "", name: "") { issue26: issue(number: ) { id } issue27: issue(number: ) { id } ... } }' --jq '.data.repository' ``
b. Fire addBlockedBy mutation per dep edge (issue node IDs, not numbers):
``bash gh api graphql -f query=' mutation { addBlockedBy(input: { issueId: "", blockingIssueId: "" }) { clientMutationId } }' ``
c. Error handling: if a single edge fails (already-exists, insufficient scope, network), report the specific failure and continue with remaining edges; do NOT abort the run. The failing edges fall back to the human-instructions block below. Common failure modes:
Resource not accessible by integration→ token lacksissues:writescope. Fall back to printing the human-readable Blocked-by instructions.An error occurred while validating the input: issue is already blocked by ...→ idempotent no-op; treat as success.
d. Fallback for unset / failed edges (only when at least one edge failed in step (b/c)): print the copy-pasteable instruction block so the user can finish via UI:
``` Could not auto-set the following Blocked-by relations (right sidebar → Development → Dependencies → Blocked by):
- Issue #: blocked by #
- Issue #: blocked by # and #
```
In the all-success path, skip this block entirely.
- Final report:
``` Created N block-issues for feature - in / (label: swa-impl-block): # Implement Block A — # Implement Block B — ...
Blocked-by relations set: K of M edges via addBlockedBy. (Or: "All M edges set successfully." / "K edges fell back to manual; see above.")
Next step:
- Apply any additional project-specific labels (
ready, priority, milestone) viagh issue edit --add-labelor the GitHub UI.
```
Activation modes
Two modes:
Mode 1: all-blocks (default)
Heading-driven. Creates one issue per #### Block — in tasks.md. Argument shape:
- Empty → use the active feature from
.specify/feature.json. Attaches the defaultswa-impl-blocklabel. - **`
** (e.g.001-uptime-settlement`) → override the active-feature resolution. --dry-run→ parse tasks.md and render the would-be issue bodies without callinggh. Always echo the parsed block list + dependency graph + resolved label in dry-run mode.--label→ override the default dispatch label name.--no-label→ skip label attachment entirely (issues created bare).
Mode 2: subset (single issue, custom scope)
Task-ID-driven. Creates exactly one issue covering an arbitrary subset of tasks — partial-block (e.g. Block A's SwellParameters half), cross-block (e.g. Fisher-Yates spanning Blocks B + C), or cross-phase (e.g. Phase 1 + Phase 2 + a Block A subset). The skill does NOT parse #### headings in this mode — the caller asserts the scope.
Triggered by the presence of --tasks. Required args:
--tasks→ comma-separated task IDs with range support:T008,T025-T027,T048. Skill expands ranges (T025-T027→T025,T026,T027) and validates each ID exists in tasks.md; aborts with the missing IDs if any.--title→ the GitHub issue title. Convention:Implement Block () —so existing-issue search still works. Examples:Implement Block A (SwellParameters) — epochEmission extension,Implement Block C (FisherYates) — Knuth shuffle library.
Optional args:
--notes→ free-form Notes line in the body. Use for human overrides not derivable from tasks.md (e.g. "MetaCertificateCodec deferred", "no upgrade ceremony per pre-deployment rule").--dry-run/--label/--no-label→ same semantics as Mode 1.
Mode-2 body shape:
- **Spec:** `specs/-/tasks.md`
- **Scope:**
- **What:**
- **Tasks:**
- **Notes:**
Mode-2 differences from Mode 1's execution flow:
- Skip step 3's heading parsing; use the explicit
--taskslist (the What line is composed from those tasks' texts instead of a Goal line). - Step 5 existing-issue check uses
--titleexact match instead of theImplement Blockpattern. - Skip step 8's dependency graph (the caller knows their cross-issue deps; the skill can't infer them from a custom subset).
- Final report shows a single issue, not a list.
Safety rules
- NEVER create issues in a repo whose
originURL was not just echoed to the user. - NEVER overwrite existing block-issues. If step 5 finds a match, abort and report.
- NEVER include the constitution, scars, dispatch boilerplate, or per-task acceptance criteria in the body. The template is the contract; deviation creates drift between issue and
tasks.md/CLAUDE.md. - NEVER attach labels other than the one resolved in step 6 (default
swa-impl-block, or whatever the caller passed via--label). Additional project-specific labels are the consuming project's PM-workflow concern — they go in viagh issue editafterward. - Echo every state-changing
gh issue create/gh label create/addBlockedByinvocation back to the user before running it. - NEVER silently drop a dep edge. If
addBlockedByfails for any edge, report it explicitly and surface that edge in the manual-fallback block.
Anti-patterns
- One issue per task. Wrong granularity for a PR-stack project — generates 50-100 issues for a single feature, swamps the project board, and forces the assignee to thread per-task issues into a per-Block PR anyway. For non-Spec-Kit projects, drive issue creation manually with
gh issue create. - Epic issue bundling all blocks. Adds a maintenance burden (the epic body has to be updated as blocks close) without giving a richer signal than the native GitHub Project view + Issue Dependencies graph already provide.
- Copying
CLAUDE.md/ constitution / scars into the body. Source of truth lives in the file, not the issue. Both humans and any automation readtasks.mdat implementation time; the issue body just points at it. - Inflating the What line into a mini-spec. Two sentences max, no FR/SC/DI identifiers, no task-by-task enumeration. The moment it needs a third sentence, the detail belongs in
tasks.md, not the issue. - Cross-block dependency lines in the body (e.g. "Blocked by: Block A"). Use GitHub's native Issue Dependencies feature instead — both humans and automation consume it from the sidebar. Body-field links drift when issues close.
- Stuffing the issue with extra labels. The single dispatch label (
swa-impl-blockby default) is the contract — it tells the downstream coder-agent the issue is ready to pick up. Priority, milestone,ready,area/*etc. are the consuming project's PM-workflow concern and go on after creation viagh issue edit. Baking multiple labels in here couples the skill to one project's workflow.
See also
- [
implementing-blocks](../implementing-blocks/SKILL.md) — the skill that consumes these issues (TDD + review + PR + CI fix loop, one Block per invocation).
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: swell-agents
- Source: swell-agents/coding-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.