Project Board Enforcement Overview The GitHub Project board is THE source of truth for all work state. Not labels. Not comments. Not memory. The project board. Core principle: If it's not in the project board with correct fields, it doesn't exist. This skill is called by other skills at gate points. It is not invoked directly. API Optimization Requirement CRITICAL: All read operations MUST use cached data from . The following environment variables MUST be set before using this skill: - - Cached project items JSON - - Cached project fields JSON - - Project node ID - - Status field ID - - Statu…

)\n ITEM_ID=$(echo \"$GH_CACHE_ITEMS\" | jq -r \".items[] | select(.content.number == $issue_num) | .id\")\n\n echo \"$ITEM_ID\"\n return 0\n}\n```\n\n### Set Project Status\n\n**Called at every status transition. 1 API call (uses cached IDs).**\n\n```bash\nset_project_status() {\n local item_id=$1\n local new_status=$2 # Backlog, Ready, In Progress, In Review, Done, Blocked\n\n # Use cached IDs (0 API calls for lookups)\n # GH_PROJECT_ID, GH_STATUS_FIELD_ID set by session-start\n\n # Get option ID from cache\n local option_id\n case \"$new_status\" in\n \"Backlog\") option_id=\"$GH_STATUS_BACKLOG_ID\" ;;\n \"Ready\") option_id=\"$GH_STATUS_READY_ID\" ;;\n \"In Progress\") option_id=\"$GH_STATUS_IN_PROGRESS_ID\" ;;\n \"In Review\") option_id=\"$GH_STATUS_IN_REVIEW_ID\" ;;\n \"Done\") option_id=\"$GH_STATUS_DONE_ID\" ;;\n \"Blocked\") option_id=\"$GH_STATUS_BLOCKED_ID\" ;;\n *)\n # Fallback: look up from cached fields (0 API calls)\n option_id=$(echo \"$GH_CACHE_FIELDS\" | jq -r \".fields[] | select(.name == \\\"Status\\\") | .options[] | select(.name == \\\"$new_status\\\") | .id\")\n ;;\n esac\n\n if [ -z \"$option_id\" ] || [ \"$option_id\" = \"null\" ]; then\n echo \"ERROR: Status '$new_status' not found in project.\"\n return 1\n fi\n\n # Single API call to update status\n gh project item-edit --project-id \"$GH_PROJECT_ID\" --id \"$item_id\" \\\n --field-id \"$GH_STATUS_FIELD_ID\" --single-select-option-id \"$option_id\"\n\n return $?\n}\n```\n\n### Set Project Type\n\n**Called when creating issues. 1 API call (uses cached IDs).**\n\n```bash\nset_project_type() {\n local item_id=$1\n local type=$2 # Feature, Bug, Chore, Research, Spike, Epic, Initiative\n\n # Get type field ID and option from cache (0 API calls)\n local type_field_id=$(echo \"$GH_CACHE_FIELDS\" | jq -r '.fields[] | select(.name == \"Type\") | .id')\n local option_id=$(echo \"$GH_CACHE_FIELDS\" | jq -r \".fields[] | select(.name == \\\"Type\\\") | .options[] | select(.name == \\\"$type\\\") | .id\")\n\n if [ -z \"$option_id\" ] || [ \"$option_id\" = \"null\" ]; then\n echo \"ERROR: Type '$type' not found in project.\"\n return 1\n fi\n\n # Single API call to update type\n gh project item-edit --project-id \"$GH_PROJECT_ID\" --id \"$item_id\" \\\n --field-id \"$type_field_id\" --single-select-option-id \"$option_id\"\n}\n```\n\n## State Queries via Project Board\n\n**All queries use cached data. 0 API calls.**\n\n### Get Issues by Status\n\n**USE THIS instead of label queries. 0 API calls (uses cache).**\n\n```bash\nget_issues_by_status() {\n local status=$1 # Ready, In Progress, etc.\n\n # Use cached data (0 API calls)\n echo \"$GH_CACHE_ITEMS\" | jq -r \".items[] | select(.status.name == \\\"$status\\\") | .content.number\"\n}\n\n# Examples:\n# get_issues_by_status \"Ready\"\n# get_issues_by_status \"In Progress\"\n# get_issues_by_status \"Blocked\"\n```\n\n### Get Issues by Type\n\n**0 API calls (uses cache).**\n\n```bash\nget_issues_by_type() {\n local type=$1 # Epic, Feature, etc.\n\n echo \"$GH_CACHE_ITEMS\" | jq -r \".items[] | select(.type.name == \\\"$type\\\") | .content.number\"\n}\n```\n\n### Get Epic Children\n\n**0 API calls (uses cache).**\n\n```bash\nget_epic_children() {\n local epic_num=$1\n\n echo \"$GH_CACHE_ITEMS\" | jq -r \".items[] | select(.epic == \\\"#$epic_num\\\") | .content.number\"\n}\n```\n\n### Count by Status\n\n**0 API calls (uses cache).**\n\n```bash\ncount_by_status() {\n local status=$1\n\n echo \"$GH_CACHE_ITEMS\" | jq \"[.items[] | select(.status.name == \\\"$status\\\")] | length\"\n}\n```\n\n## Gate Points\n\nThese are the points in workflows where project board verification is MANDATORY:\n\n| Workflow Point | Gate | Skill |\n|----------------|------|-------|\n| Before any work | Issue in project | issue-driven-development Step 1 |\n| After issue creation | Add to project, set fields | issue-prerequisite |\n| Starting work | Status → In Progress | issue-driven-development Step 6 |\n| Creating branch | Verify project membership | branch-discipline |\n| PR created | Status → In Review | pr-creation |\n| Work complete | Status → Done | issue-driven-development completion |\n| Blocked | Status → Blocked | error-recovery |\n| Epic created | Add epic to project, set Type=Epic | epic-management |\n| Child issue created | Add to project, link to parent | issue-decomposition |\n\n## Transition Rules\n\n**Valid transitions:**\n```\nBacklog → Ready → In Progress → In Review → Done\n ↓ ↓ ↓ ↓\n └────────┴──────────┴────────────┴──→ Blocked\n ↓\n (return to previous)\n```\n\n### Transition Enforcement\n\n```bash\nvalidate_transition() {\n local current=$1\n local target=$2\n\n case \"$current→$target\" in\n \"Backlog→Ready\"|\"Ready→In Progress\"|\"In Progress→In Review\"|\"In Review→Done\")\n return 0 ;;\n *\"→Blocked\")\n return 0 ;;\n \"Blocked→Backlog\"|\"Blocked→Ready\"|\"Blocked→In Progress\")\n return 0 ;;\n *)\n echo \"INVALID_TRANSITION: $current → $target\"\n return 1 ;;\n esac\n}\n```\n\n## Labels vs Project Board\n\n**WRONG:** Using labels for state (`status:in-progress`)\n**RIGHT:** Using project board Status field\n\nLabels are only for supplementary info: `epic`, `epic-[name]`, `spawned-from:#N`, `review-finding`\n\n## Sync Verification\n\nDetect drift by comparing git branches to project board status:\n- Issues with branches should be In Progress or In Review\n- In Progress issues should have active branches\n\nUse cached data (`GH_CACHE_ITEMS`) for 0 API calls. Example:\n\n```bash\n# Check if branch status matches project board\nstatus=$(echo \"$GH_CACHE_ITEMS\" | jq -r \".items[] | select(.content.number == $issue) | .status.name\")\n```\n\n## Error Messages\n\nAll project board errors provide actionable fixes:\n\n| Error Code | Message | Fix |\n|------------|---------|-----|\n| NOT_IN_PROJECT | Issue not in project board | `gh project item-add ...` |\n| NO_STATUS | Status field not set | Update Status field |\n| INVALID_TRANSITION | Invalid state change | Use valid transition |\n| PROJECT_NOT_FOUND | Project not accessible | Verify GITHUB_PROJECT_NUM |\n\n## Integration\n\nThis skill is called by:\n- `issue-driven-development` - All status transitions\n- `issue-prerequisite` - After issue creation\n- `epic-management` - Epic and child issue setup\n- `autonomous-orchestration` - State queries and updates\n- `session-start` - Sync verification\n- `work-intake` - Project readiness check\n\nThis skill requires cache from:\n- `github-api-cache` - Provides GH_CACHE_ITEMS, GH_CACHE_FIELDS, and field IDs\n\n## Checklist for Callers\n\nBefore proceeding past any gate:\n\n- [ ] **GitHub API cache initialized** (GH_CACHE_ITEMS, GH_CACHE_FIELDS set)\n- [ ] Issue exists in project (verified from cache, not API call)\n- [ ] Status field is set\n- [ ] Type field is set\n- [ ] Priority field is set (for new issues)\n- [ ] Epic linkage set (if child of epic)\n- [ ] Transition is valid (if changing status)\n\n## API Cost Summary\n\n| Operation | Before Caching | After Caching |\n|-----------|----------------|---------------|\n| verify_issue_in_project | 1 call | 0 calls |\n| verify_status_set | 1 call | 0 calls |\n| add_issue_to_project | 2 calls | 2 calls |\n| set_project_status | 4 calls | 1 call |\n| set_project_type | 3 calls | 1 call |\n| get_issues_by_status | 1 call | 0 calls |\n| count_by_status | 1 call | 0 calls |\n| verify_project_sync (10 branches) | 10 calls | 0 calls |\n---","attachment_filenames":[],"attachments":[],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"Project Board Enforcement","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Overview","type":"text"}]},{"type":"paragraph","content":[{"text":"The GitHub Project board is THE source of truth for all work state. Not labels. Not comments. Not memory. The project board.","type":"text"}]},{"type":"paragraph","content":[{"text":"Core principle:","type":"text","marks":[{"type":"strong"}]},{"text":" If it's not in the project board with correct fields, it doesn't exist.","type":"text"}]},{"type":"paragraph","content":[{"text":"This skill is called by other skills at gate points. It is not invoked directly.","type":"text","marks":[{"type":"strong"}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"API Optimization Requirement","type":"text"}]},{"type":"paragraph","content":[{"text":"CRITICAL:","type":"text","marks":[{"type":"strong"}]},{"text":" All read operations MUST use cached data from ","type":"text"},{"text":"github-api-cache","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]},{"type":"paragraph","content":[{"text":"The following environment variables MUST be set before using this skill:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"GH_CACHE_ITEMS","type":"text","marks":[{"type":"code_inline"}]},{"text":" - Cached project items JSON","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"GH_CACHE_FIELDS","type":"text","marks":[{"type":"code_inline"}]},{"text":" - Cached project fields JSON","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"GH_PROJECT_ID","type":"text","marks":[{"type":"code_inline"}]},{"text":" - Project node ID","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"GH_STATUS_FIELD_ID","type":"text","marks":[{"type":"code_inline"}]},{"text":" - Status field ID","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"GH_STATUS_*_ID","type":"text","marks":[{"type":"code_inline"}]},{"text":" - Status option IDs","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"If these are not set, invoke ","type":"text"},{"text":"session-start","type":"text","marks":[{"type":"code_inline"}]},{"text":" first to initialize the cache.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"The Rule","type":"text"}]},{"type":"paragraph","content":[{"text":"Every issue, epic, and initiative MUST be in the project board BEFORE work begins.","type":"text","marks":[{"type":"strong"}]}]},{"type":"paragraph","content":[{"text":"This is not optional. This is not a suggestion. This is a hard gate.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Required Environment","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# These MUST be set. Work cannot proceed without them.\necho $GITHUB_PROJECT # Full URL: https://github.com/users/USER/projects/N\necho $GITHUB_PROJECT_NUM # Just the number: N\necho $GH_PROJECT_OWNER # Owner: @me or org name","type":"text"}]},{"type":"paragraph","content":[{"text":"If any are missing, stop and configure them before proceeding.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Project Field Requirements","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Mandatory Fields","type":"text"}]},{"type":"paragraph","content":[{"text":"Every project MUST have these fields configured:","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Field","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Type","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Required Values","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Status","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Single select","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Backlog, Ready, In Progress, In Review, Done, Blocked","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Type","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Single select","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Feature, Bug, Chore, Research, Spike, Epic, Initiative","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Priority","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Single select","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Critical, High, Medium, Low","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Recommended Fields","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Field","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Type","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Purpose","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Verification","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Single select","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Not Verified, Failing, Partial, Passing","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Criteria Met","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Number","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Count of completed acceptance criteria","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Criteria Total","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Number","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Total acceptance criteria","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Last Verified","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Date","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"When verification last ran","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Epic","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Text","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Parent epic issue number","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Initiative","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Text","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Parent initiative issue number","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Verification Functions","type":"text"}]},{"type":"paragraph","content":[{"text":"All read operations use cached data (0 API calls). Only writes require API calls.","type":"text","marks":[{"type":"strong"}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Verify Issue in Project","type":"text"}]},{"type":"paragraph","content":[{"text":"GATE FUNCTION","type":"text","marks":[{"type":"strong"}]},{"text":" - Called before any work begins. ","type":"text"},{"text":"0 API calls (uses cache).","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"verify_issue_in_project() {\n local issue=$1\n\n # Get project item ID FROM CACHE (0 API calls)\n ITEM_ID=$(echo \"$GH_CACHE_ITEMS\" | jq -r \".items[] | select(.content.number == $issue) | .id\")\n\n if [ -z \"$ITEM_ID\" ] || [ \"$ITEM_ID\" = \"null\" ]; then\n echo \"BLOCKED: Issue #$issue is not in the project board.\"\n echo \"\"\n echo \"Add it with:\"\n echo \" gh project item-add $GITHUB_PROJECT_NUM --owner $GH_PROJECT_OWNER --url \\$(gh issue view $issue --json url -q .url)\"\n return 1\n fi\n\n echo \"$ITEM_ID\"\n return 0\n}","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Verify Status Field Set","type":"text"}]},{"type":"paragraph","content":[{"text":"GATE FUNCTION","type":"text","marks":[{"type":"strong"}]},{"text":" - Called before work proceeds past issue check. ","type":"text"},{"text":"0 API calls (uses cache).","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"verify_status_set() {\n local issue=$1\n local item_id=$2\n\n # Get current status FROM CACHE (0 API calls)\n STATUS=$(echo \"$GH_CACHE_ITEMS\" | jq -r \".items[] | select(.id == \\\"$item_id\\\") | .status.name\")\n\n if [ -z \"$STATUS\" ] || [ \"$STATUS\" = \"null\" ]; then\n echo \"BLOCKED: Issue #$issue has no Status set in project board.\"\n echo \"\"\n echo \"Set status before proceeding.\"\n return 1\n fi\n\n echo \"$STATUS\"\n return 0\n}","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Add Issue to Project","type":"text"}]},{"type":"paragraph","content":[{"text":"Called by issue-prerequisite after issue creation. 1 API call + cache refresh.","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"add_issue_to_project() {\n local issue_url=$1\n\n # Add to project (1 API call - unavoidable write)\n gh project item-add \"$GITHUB_PROJECT_NUM\" --owner \"$GH_PROJECT_OWNER\" --url \"$issue_url\"\n\n if [ $? -ne 0 ]; then\n echo \"ERROR: Failed to add issue to project.\"\n return 1\n fi\n\n # Refresh cache after adding (1 API call)\n export GH_CACHE_ITEMS=$(gh project item-list \"$GITHUB_PROJECT_NUM\" --owner \"$GH_PROJECT_OWNER\" --format json)\n\n # Get the item ID from refreshed cache\n local issue_num=$(echo \"$issue_url\" | grep -oE '[0-9]+

Project Board Enforcement Overview The GitHub Project board is THE source of truth for all work state. Not labels. Not comments. Not memory. The project board. Core principle: If it's not in the project board with correct fields, it doesn't exist. This skill is called by other skills at gate points. It is not invoked directly. API Optimization Requirement CRITICAL: All read operations MUST use cached data from . The following environment variables MUST be set before using this skill: - - Cached project items JSON - - Cached project fields JSON - - Project node ID - - Status field ID - - Statu…

)\n ITEM_ID=$(echo \"$GH_CACHE_ITEMS\" | jq -r \".items[] | select(.content.number == $issue_num) | .id\")\n\n echo \"$ITEM_ID\"\n return 0\n}","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Set Project Status","type":"text"}]},{"type":"paragraph","content":[{"text":"Called at every status transition. 1 API call (uses cached IDs).","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"set_project_status() {\n local item_id=$1\n local new_status=$2 # Backlog, Ready, In Progress, In Review, Done, Blocked\n\n # Use cached IDs (0 API calls for lookups)\n # GH_PROJECT_ID, GH_STATUS_FIELD_ID set by session-start\n\n # Get option ID from cache\n local option_id\n case \"$new_status\" in\n \"Backlog\") option_id=\"$GH_STATUS_BACKLOG_ID\" ;;\n \"Ready\") option_id=\"$GH_STATUS_READY_ID\" ;;\n \"In Progress\") option_id=\"$GH_STATUS_IN_PROGRESS_ID\" ;;\n \"In Review\") option_id=\"$GH_STATUS_IN_REVIEW_ID\" ;;\n \"Done\") option_id=\"$GH_STATUS_DONE_ID\" ;;\n \"Blocked\") option_id=\"$GH_STATUS_BLOCKED_ID\" ;;\n *)\n # Fallback: look up from cached fields (0 API calls)\n option_id=$(echo \"$GH_CACHE_FIELDS\" | jq -r \".fields[] | select(.name == \\\"Status\\\") | .options[] | select(.name == \\\"$new_status\\\") | .id\")\n ;;\n esac\n\n if [ -z \"$option_id\" ] || [ \"$option_id\" = \"null\" ]; then\n echo \"ERROR: Status '$new_status' not found in project.\"\n return 1\n fi\n\n # Single API call to update status\n gh project item-edit --project-id \"$GH_PROJECT_ID\" --id \"$item_id\" \\\n --field-id \"$GH_STATUS_FIELD_ID\" --single-select-option-id \"$option_id\"\n\n return $?\n}","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Set Project Type","type":"text"}]},{"type":"paragraph","content":[{"text":"Called when creating issues. 1 API call (uses cached IDs).","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"set_project_type() {\n local item_id=$1\n local type=$2 # Feature, Bug, Chore, Research, Spike, Epic, Initiative\n\n # Get type field ID and option from cache (0 API calls)\n local type_field_id=$(echo \"$GH_CACHE_FIELDS\" | jq -r '.fields[] | select(.name == \"Type\") | .id')\n local option_id=$(echo \"$GH_CACHE_FIELDS\" | jq -r \".fields[] | select(.name == \\\"Type\\\") | .options[] | select(.name == \\\"$type\\\") | .id\")\n\n if [ -z \"$option_id\" ] || [ \"$option_id\" = \"null\" ]; then\n echo \"ERROR: Type '$type' not found in project.\"\n return 1\n fi\n\n # Single API call to update type\n gh project item-edit --project-id \"$GH_PROJECT_ID\" --id \"$item_id\" \\\n --field-id \"$type_field_id\" --single-select-option-id \"$option_id\"\n}","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"State Queries via Project Board","type":"text"}]},{"type":"paragraph","content":[{"text":"All queries use cached data. 0 API calls.","type":"text","marks":[{"type":"strong"}]}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Get Issues by Status","type":"text"}]},{"type":"paragraph","content":[{"text":"USE THIS instead of label queries. 0 API calls (uses cache).","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"get_issues_by_status() {\n local status=$1 # Ready, In Progress, etc.\n\n # Use cached data (0 API calls)\n echo \"$GH_CACHE_ITEMS\" | jq -r \".items[] | select(.status.name == \\\"$status\\\") | .content.number\"\n}\n\n# Examples:\n# get_issues_by_status \"Ready\"\n# get_issues_by_status \"In Progress\"\n# get_issues_by_status \"Blocked\"","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Get Issues by Type","type":"text"}]},{"type":"paragraph","content":[{"text":"0 API calls (uses cache).","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"get_issues_by_type() {\n local type=$1 # Epic, Feature, etc.\n\n echo \"$GH_CACHE_ITEMS\" | jq -r \".items[] | select(.type.name == \\\"$type\\\") | .content.number\"\n}","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Get Epic Children","type":"text"}]},{"type":"paragraph","content":[{"text":"0 API calls (uses cache).","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"get_epic_children() {\n local epic_num=$1\n\n echo \"$GH_CACHE_ITEMS\" | jq -r \".items[] | select(.epic == \\\"#$epic_num\\\") | .content.number\"\n}","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Count by Status","type":"text"}]},{"type":"paragraph","content":[{"text":"0 API calls (uses cache).","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"count_by_status() {\n local status=$1\n\n echo \"$GH_CACHE_ITEMS\" | jq \"[.items[] | select(.status.name == \\\"$status\\\")] | length\"\n}","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Gate Points","type":"text"}]},{"type":"paragraph","content":[{"text":"These are the points in workflows where project board verification is MANDATORY:","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Workflow Point","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Gate","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Skill","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Before any work","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Issue in project","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"issue-driven-development Step 1","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"After issue creation","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Add to project, set fields","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"issue-prerequisite","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Starting work","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Status → In Progress","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"issue-driven-development Step 6","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Creating branch","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Verify project membership","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"branch-discipline","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"PR created","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Status → In Review","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"pr-creation","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Work complete","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Status → Done","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"issue-driven-development completion","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Blocked","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Status → Blocked","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"error-recovery","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Epic created","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Add epic to project, set Type=Epic","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"epic-management","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Child issue created","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Add to project, link to parent","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"issue-decomposition","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Transition Rules","type":"text"}]},{"type":"paragraph","content":[{"text":"Valid transitions:","type":"text","marks":[{"type":"strong"}]}]},{"type":"code_block","attrs":{"wrap":false,"language":""},"content":[{"text":"Backlog → Ready → In Progress → In Review → Done\n ↓ ↓ ↓ ↓\n └────────┴──────────┴────────────┴──→ Blocked\n ↓\n (return to previous)","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Transition Enforcement","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"validate_transition() {\n local current=$1\n local target=$2\n\n case \"$current→$target\" in\n \"Backlog→Ready\"|\"Ready→In Progress\"|\"In Progress→In Review\"|\"In Review→Done\")\n return 0 ;;\n *\"→Blocked\")\n return 0 ;;\n \"Blocked→Backlog\"|\"Blocked→Ready\"|\"Blocked→In Progress\")\n return 0 ;;\n *)\n echo \"INVALID_TRANSITION: $current → $target\"\n return 1 ;;\n esac\n}","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Labels vs Project Board","type":"text"}]},{"type":"paragraph","content":[{"text":"WRONG:","type":"text","marks":[{"type":"strong"}]},{"text":" Using labels for state (","type":"text"},{"text":"status:in-progress","type":"text","marks":[{"type":"code_inline"}]},{"text":") ","type":"text"},{"text":"RIGHT:","type":"text","marks":[{"type":"strong"}]},{"text":" Using project board Status field","type":"text"}]},{"type":"paragraph","content":[{"text":"Labels are only for supplementary info: ","type":"text"},{"text":"epic","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"epic-[name]","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"spawned-from:#N","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"review-finding","type":"text","marks":[{"type":"code_inline"}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Sync Verification","type":"text"}]},{"type":"paragraph","content":[{"text":"Detect drift by comparing git branches to project board status:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Issues with branches should be In Progress or In Review","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"In Progress issues should have active branches","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Use cached data (","type":"text"},{"text":"GH_CACHE_ITEMS","type":"text","marks":[{"type":"code_inline"}]},{"text":") for 0 API calls. Example:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Check if branch status matches project board\nstatus=$(echo \"$GH_CACHE_ITEMS\" | jq -r \".items[] | select(.content.number == $issue) | .status.name\")","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Error Messages","type":"text"}]},{"type":"paragraph","content":[{"text":"All project board errors provide actionable fixes:","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Error Code","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Message","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Fix","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"NOT_IN_PROJECT","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Issue not in project board","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"gh project item-add ...","type":"text","marks":[{"type":"code_inline"}]}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"NO_STATUS","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Status field not set","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Update Status field","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"INVALID_TRANSITION","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Invalid state change","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Use valid transition","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"PROJECT_NOT_FOUND","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Project not accessible","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Verify GITHUB_PROJECT_NUM","type":"text"}]}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Integration","type":"text"}]},{"type":"paragraph","content":[{"text":"This skill is called by:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"issue-driven-development","type":"text","marks":[{"type":"code_inline"}]},{"text":" - All status transitions","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"issue-prerequisite","type":"text","marks":[{"type":"code_inline"}]},{"text":" - After issue creation","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"epic-management","type":"text","marks":[{"type":"code_inline"}]},{"text":" - Epic and child issue setup","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"autonomous-orchestration","type":"text","marks":[{"type":"code_inline"}]},{"text":" - State queries and updates","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"session-start","type":"text","marks":[{"type":"code_inline"}]},{"text":" - Sync verification","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"work-intake","type":"text","marks":[{"type":"code_inline"}]},{"text":" - Project readiness check","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"This skill requires cache from:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"github-api-cache","type":"text","marks":[{"type":"code_inline"}]},{"text":" - Provides GH_CACHE_ITEMS, GH_CACHE_FIELDS, and field IDs","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Checklist for Callers","type":"text"}]},{"type":"paragraph","content":[{"text":"Before proceeding past any gate:","type":"text"}]},{"type":"checkbox_list","attrs":{"id":null},"content":[{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"GitHub API cache initialized","type":"text","marks":[{"type":"strong"}]},{"text":" (GH_CACHE_ITEMS, GH_CACHE_FIELDS set)","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Issue exists in project (verified from cache, not API call)","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Status field is set","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Type field is set","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Priority field is set (for new issues)","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Epic linkage set (if child of epic)","type":"text"}]}]},{"type":"checkbox_item","attrs":{"checked":false},"content":[{"type":"paragraph","content":[{"text":"Transition is valid (if changing status)","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"API Cost Summary","type":"text"}]},{"type":"table","attrs":{"layout":null},"content":[{"type":"tr","content":[{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Operation","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"Before Caching","type":"text"}]}]},{"type":"th","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"After Caching","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"verify_issue_in_project","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"1 call","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"0 calls","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"verify_status_set","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"1 call","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"0 calls","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"add_issue_to_project","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"2 calls","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"2 calls","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"set_project_status","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"4 calls","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"1 call","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"set_project_type","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"3 calls","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"1 call","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"get_issues_by_status","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"1 call","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"0 calls","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"count_by_status","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"1 call","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"0 calls","type":"text"}]}]}]},{"type":"tr","content":[{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"verify_project_sync (10 branches)","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"10 calls","type":"text"}]}]},{"type":"td","attrs":{"colspan":1,"rowspan":1,"colwidth":null,"alignment":""},"content":[{"type":"paragraph","content":[{"text":"0 calls","type":"text"}]}]}]}]},{"type":"hr","attrs":{"markup":"---"}}]},"metadata":{"date":"2026-06-05","name":"project-board-enforcement","model":"opus","author":"@skillopedia","source":{"stars":8,"repo_name":"claude-skills","origin_url":"https://github.com/troykelly/claude-skills/blob/HEAD/skills/project-board-enforcement/SKILL.md","repo_owner":"troykelly","body_sha256":"95542f3e1039b4eb33c43a04e637ee1e5234986c5b52b38ffc9f42b5443a1e0f","cluster_key":"f0916a3a8f9fdb1f489e4013dc9db500b0586fc045d7f03043e129bd24390927","clean_bundle":{"format":"clean-skill-bundle-v1","source":"troykelly/claude-skills/skills/project-board-enforcement/SKILL.md","bundle_sha256":"06aa480e189a35d6e11a20cbcd31264160056ad886e7961d18310a1c9b39f6d8","attachment_count":0,"text_attachments":0,"binary_attachments":0},"cluster_size":1,"skill_md_path":"skills/project-board-enforcement/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"finance-legal-compliance","category_label":"Finance"},"exact_dupes_collapsed_into_this":0},"version":"v1","category":"finance-legal-compliance","import_tag":"clean-skills-v1","description":"MANDATORY for all work - the project board is THE source of truth. This skill provides verification functions and gates that other skills MUST call. No work proceeds without project board compliance.","allowed-tools":["Bash","mcp__github__*"]}},"renderedAt":1782988450706}

Project Board Enforcement Overview The GitHub Project board is THE source of truth for all work state. Not labels. Not comments. Not memory. The project board. Core principle: If it's not in the project board with correct fields, it doesn't exist. This skill is called by other skills at gate points. It is not invoked directly. API Optimization Requirement CRITICAL: All read operations MUST use cached data from . The following environment variables MUST be set before using this skill: - - Cached project items JSON - - Cached project fields JSON - - Project node ID - - Status field ID - - Statu…