| name | issue-prerequisite |
| description | Use before starting ANY work - hard gate ensuring a GitHub issue exists, creating one if needed through user questioning |
Issue Prerequisite
Overview
No work without a GitHub issue. This is a hard gate.
Core principle: Every task, regardless of size, must have a corresponding GitHub issue.
Announce at start: "I'm checking for a GitHub issue before proceeding with any work."
The Gate
┌─────────────────────────────────────┐
│ WORK REQUESTED │
└─────────────────┬───────────────────┘
│
▼
┌─────────────────┐
│ Issue provided? │
└────────┬────────┘
│
┌─────────┴─────────┐
│ │
Yes No
│ │
▼ ▼
┌─────────┐ ┌─────────────┐
│ Verify │ │ Ask user or │
│ issue │ │ create issue│
│ exists │ └──────┬──────┘
└────┬────┘ │
│ │
▼ ▼
┌──────────────────────────────┐
│ Issue confirmed? │
│ (exists and accessible) │
└─────────────┬────────────────┘
│
┌────────┴────────┐
│ │
Yes No
│ │
▼ ▼
PROCEED STOP
WITH WORK (Cannot proceed)
When Issue is Provided
Verify the issue exists and is accessible:
# Verify issue exists
gh issue view [ISSUE_NUMBER] --json number,title,state,body
# Check issue is in the correct repository
gh issue view [ISSUE_NUMBER] --json url
If issue doesn't exist or is inaccessible:
- Report error to user
- Do not proceed
When No Issue is Provided
Option 1: User has existing issue
Ask: "What's the GitHub issue number for this work?"
Option 2: Need to create issue
Gather information to create an issue:
I need to create a GitHub issue before starting this work.
**Please provide or confirm:**
1. **Title:** [What should this issue be called?]
2. **Description:** [What should this issue deliver?]
3. **Acceptance Criteria:**
- [ ] [First verifiable behavior]
- [ ] [Second verifiable behavior]
4. **Type:** Feature / Bug / Chore / Research / Spike
5. **Priority:** Critical / High / Medium / Low
Creating the Issue
Once information is gathered:
# Create the issue
ISSUE_URL=$(gh issue create \
--title "[Type] Title here" \
--body "## Description
[Description]
## Acceptance Criteria
- [ ] Criterion 1
- [ ] Criterion 2
## Verification Steps
1. Step 1
2. Step 2
## Technical Notes
[Any technical context]" 2>&1 | tail -1)
ISSUE_NUMBER=$(echo "$ISSUE_URL" | grep -oE '[0-9]+$')
echo "Created issue #$ISSUE_NUMBER"
Adding to Project Board (MANDATORY)
This step is NOT optional. It is a gate.
# Add to project - REQUIRED
gh project item-add "$GITHUB_PROJECT_NUM" --owner "$GH_PROJECT_OWNER" --url "$ISSUE_URL"
if [ $? -ne 0 ]; then
echo "ERROR: Failed to add issue to project. Cannot proceed."
echo "Issue #$ISSUE_NUMBER exists but is NOT tracked in project board."
exit 1
fi
# Get the item ID - REQUIRED for field updates
ITEM_ID=$(gh project item-list "$GITHUB_PROJECT_NUM" --owner "$GH_PROJECT_OWNER" \
--format json | jq -r ".items[] | select(.content.number == $ISSUE_NUMBER) | .id")
if [ -z "$ITEM_ID" ] || [ "$ITEM_ID" = "null" ]; then
echo "ERROR: Issue added but item ID not found. Cannot set fields."
exit 1
fi
echo "Issue #$ISSUE_NUMBER added to project with item ID: $ITEM_ID"
Setting Project Fields (MANDATORY)
All fields must be set before proceeding.
# Get project ID
PROJECT_ID=$(gh project list --owner "$GH_PROJECT_OWNER" --format json | \
jq -r ".projects[] | select(.number == $GITHUB_PROJECT_NUM) | .id")
# Get field IDs
STATUS_FIELD_ID=$(gh project field-list "$GITHUB_PROJECT_NUM" --owner "$GH_PROJECT_OWNER" \
--format json | jq -r '.fields[] | select(.name == "Status") | .id')
TYPE_FIELD_ID=$(gh project field-list "$GITHUB_PROJECT_NUM" --owner "$GH_PROJECT_OWNER" \
--format json | jq -r '.fields[] | select(.name == "Type") | .id')
PRIORITY_FIELD_ID=$(gh project field-list "$GITHUB_PROJECT_NUM" --owner "$GH_PROJECT_OWNER" \
--format json | jq -r '.fields[] | select(.name == "Priority") | .id')
# Get option IDs for the values we want to set
READY_OPTION_ID=$(gh project field-list "$GITHUB_PROJECT_NUM" --owner "$GH_PROJECT_OWNER" \
--format json | jq -r '.fields[] | select(.name == "Status") | .options[] | select(.name == "Ready") | .id')
TYPE_OPTION_ID=$(gh project field-list "$GITHUB_PROJECT_NUM" --owner "$GH_PROJECT_OWNER" \
--format json | jq -r ".fields[] | select(.name == \"Type\") | .options[] | select(.name == \"[TYPE]\") | .id")
PRIORITY_OPTION_ID=$(gh project field-list "$GITHUB_PROJECT_NUM" --owner "$GH_PROJECT_OWNER" \
--format json | jq -r ".fields[] | select(.name == \"Priority\") | .options[] | select(.name == \"[PRIORITY]\") | .id")
# Set Status = Ready
gh project item-edit --project-id "$PROJECT_ID" --id "$ITEM_ID" \
--field-id "$STATUS_FIELD_ID" --single-select-option-id "$READY_OPTION_ID"
# Set Type
gh project item-edit --project-id "$PROJECT_ID" --id "$ITEM_ID" \
--field-id "$TYPE_FIELD_ID" --single-select-option-id "$TYPE_OPTION_ID"
# Set Priority
gh project item-edit --project-id "$PROJECT_ID" --id "$ITEM_ID" \
--field-id "$PRIORITY_FIELD_ID" --single-select-option-id "$PRIORITY_OPTION_ID"
Verify Project Board Setup (GATE)
Do not proceed until verification passes.
# Verify all fields are set
VERIFY=$(gh project item-list "$GITHUB_PROJECT_NUM" --owner "$GH_PROJECT_OWNER" \
--format json | jq ".items[] | select(.content.number == $ISSUE_NUMBER)")
STATUS=$(echo "$VERIFY" | jq -r '.status.name')
TYPE=$(echo "$VERIFY" | jq -r '.type.name // "unset"')
if [ -z "$STATUS" ] || [ "$STATUS" = "null" ]; then
echo "GATE FAILED: Status not set for issue #$ISSUE_NUMBER"
exit 1
fi
echo "VERIFIED: Issue #$ISSUE_NUMBER is in project with Status=$STATUS"
Issue Quality Check
Before proceeding, verify the issue has:
| Required | Check |
|---|---|
| Clear title | Describes what will be delivered |
| Description | Explains the work |
| Acceptance criteria | At least one verifiable criterion |
| In GitHub Project | Added with correct status |
If any are missing, update the issue before proceeding.
"Too Small for an Issue" is False
Common objections and responses:
| Objection | Response |
|---|---|
| "It's just a typo fix" | Issues take 30 seconds. They provide a record. Create one. |
| "It's a one-liner" | One-liners can introduce bugs. Document them. |
| "I'll do it quickly" | Quick work is forgotten work. Track it. |
| "It's obvious what needs doing" | If it's obvious, the issue will be fast to write. |
No exceptions. Every change has an issue.
Minimum Viable Issue
For truly trivial work, this is the minimum:
Title: Fix typo in README.md
## Description
Fix typo: "teh" → "the"
## Acceptance Criteria
- [ ] Typo is corrected
That's 30 seconds. There's no excuse.
After Gate Passes
Once issue is confirmed:
- Note the issue number for all subsequent work
- Proceed to next step in
issue-driven-development - Reference issue in all commits and PR
Checklist
Before proceeding past this gate:
- Issue number identified
- Issue exists in GitHub
- Issue is accessible (correct repo, not archived)
- Issue has description
- Issue has at least one acceptance criterion
- Issue is in GitHub Project (VERIFIED with ITEM_ID)
- Status field is set (Ready or Backlog)
- Type field is set
- Priority field is set
Gate: Cannot proceed to issue-driven-development Step 2 without all checkboxes verified.
Skill: project-board-enforcement