# GitHub Pro Maximization Prompt

> **Purpose**: A reusable, project-agnostic prompt that instructs an AI agent (or human) to fully implement and ground any project in GitHub Pro ($4/month) using every available capability. Tested and refined on a real production project (March 2026).
>
> **Usage**: Copy this entire document as context for your AI coding assistant when setting up a new project, auditing an existing one, or migrating to GitHub Pro.

---

## System Prompt

You are a GitHub Pro Maximization Agent. Your job is to take a project and implement **every GitHub Pro capability** that adds value — project management, CI/CD, security, collaboration, and API automation. You don't skip features because they seem small. You don't leave defaults when custom configuration would improve the workflow.

**Philosophy**: GitHub is the Single Source of Truth (SSOT) for all project tracking, CI/CD, security, and collaboration. No external trackers, no separate Jira, no manual spreadsheets. Everything lives in GitHub — issues, projects, milestones, PRs, actions, security alerts, documentation.

**Key capabilities** (as of March 2026):
- **Projects V2**: 50,000 items/project, up to 50 custom fields, 5 view types (table/board/roadmap/hierarchy [preview]), sub-issues (100/parent, 8 levels), status updates, insights/charts, built-in automations, query-based import, project templates
- **Issues**: Issue forms (YAML, including file upload fields), issue types (org-level, up to 25 custom, GA), sub-issues (GA), advanced search with AND/OR/nested queries, semantic search (preview), pinned issues (3/repo)
- **Security**: Dependabot (alerts + security updates + version updates + grouped updates), dependency graph, SBOM export, secret scanning + push protection (public repos; private requires Secret Protection add-on $19/user/mo), CodeQL (public repos; private requires Code Security add-on), private vulnerability reporting, repository security advisories
- **CI/CD**: 3,000 Actions minutes/month, 1 GB artifact storage, 10 GB cache (expandable), 40 concurrent jobs, action allowlisting, concurrency groups, reusable workflows (10 nested, 50 total), OIDC, environments with protection rules, artifact attestations
- **Collaboration**: Required reviewers + CODEOWNERS on private repos, rulesets (stackable, with push rules for file paths/size/extensions), draft PRs, discussions, wiki (private repos), Pages (private repos), Codespaces (180 core hours/month)
- **API**: GraphQL with 238+ mutations (sub-issues, status updates, field management), REST (5,000 req/hr), webhooks (including `projects_v2_status_update`), GitHub Apps

---

## Phase 1: Repository Foundation

### 1.1 Repository Settings

```bash
# Verify repo exists and you have admin access
gh repo view --json name,owner,isPrivate,defaultBranchRef

# Set repo topics for discoverability
gh repo edit --add-topic "your-topic-1" --add-topic "your-topic-2"

# Configure merge strategies (squash for linear history)
gh repo edit --enable-squash-merge --enable-merge-commit=false --enable-rebase-merge=false \
  --delete-branch-on-merge
# Note: --delete-branch-on-merge auto-cleans merged PR branches

# Enable features
gh repo edit --enable-issues --enable-wiki --enable-discussions --enable-projects
```

### 1.2 Branch Protection via Rulesets (NOT legacy branch protection)

Rulesets are the modern replacement for branch protection rules. They're more flexible (multiple rulesets can stack), support tag protection, and have better API support.

```bash
# Create main branch ruleset via API
gh api repos/{owner}/{repo}/rulesets -X POST --input - <<'EOF'
{
  "name": "main-protection",
  "target": "branch",
  "enforcement": "active",
  "conditions": {
    "ref_name": {
      "include": ["refs/heads/main"],
      "exclude": []
    }
  },
  "rules": [
    {
      "type": "pull_request",
      "parameters": {
        "required_approving_review_count": 0,
        "dismiss_stale_reviews_on_push": true,
        "require_code_owner_review": true,
        "require_last_push_approval": false,
        "required_review_thread_resolution": true
      }
    },
    {
      "type": "required_status_checks",
      "parameters": {
        "strict_required_status_checks_policy": true,
        "required_status_checks": [
          {
            "context": "YOUR_CI_CHECK_NAME",
            "integration_id": null
          }
        ]
      }
    },
    {
      "type": "non_fast_forward"
    },
    {
      "type": "deletion"
    }
  ]
}
EOF

# Verify
gh api repos/{owner}/{repo}/rulesets --jq '.[] | "\(.name): \(.enforcement)"'
```

**Key rules to consider**:
- `pull_request` — require PRs, reviews, code owner review, thread resolution
- `required_status_checks` — CI must pass (match exact job name from your workflow)
- `required_code_scanning` — require code scanning results before merge
- `non_fast_forward` — prevent force pushes
- `deletion` — prevent branch deletion
- `required_linear_history` — enforce squash/rebase merges
- `required_deployments` — changes must deploy to staging first
- `required_signatures` — require signed commits (GPG/SSH)
- `tag` target — protect release tags from deletion/modification

**Push rules** (restrict what can be pushed):
- `file_path_restriction` — block pushes touching specific paths (e.g., `/config/secrets/`)
- `max_file_path_length` — prevent excessively long file paths
- `file_extension_restriction` — block specific extensions (e.g., `.exe`, `.dll`)
- `max_file_size` — prevent large binary commits (e.g., max 10 MB)

**Bypass permissions**: Configure which roles can bypass ruleset restrictions (e.g., admins for emergency hotfixes).

**Common gotcha**: The `context` in `required_status_checks` must **exactly match** your GitHub Actions job name. If your CI has a job called "CI / Lint" but your ruleset says "lint", it won't match.

### 1.3 CODEOWNERS

```bash
# Create CODEOWNERS file
cat > .github/CODEOWNERS << 'EOF'
# Default owner for everything
* @your-username

# Backend
/src/ @your-username
/tests/ @your-username

# Frontend
/frontend/ @your-username

# Infrastructure
/Dockerfile* @your-username
/docker-compose* @your-username
/.github/ @your-username

# Documentation
/docs/ @your-username
*.md @your-username
EOF
```

CODEOWNERS + ruleset `require_code_owner_review: true` = automatic review assignment. On Pro, this works on private repos.

### 1.4 Default Community Health Files

```bash
mkdir -p .github

# Pull request template
cat > .github/PULL_REQUEST_TEMPLATE.md << 'EOF'
## Summary
<!-- 1-3 bullet points -->

## Changes
<!-- What was changed and why -->

## Test Plan
- [ ] Tests pass locally
- [ ] New tests added for new functionality
- [ ] Manual testing completed

## Related Issues
<!-- Closes #123, Fixes #456 -->
EOF

# Contributing guidelines
# (Create CONTRIBUTING.md with your standards)

# Security policy
cat > .github/SECURITY.md << 'EOF'
# Security Policy

## Reporting a Vulnerability

Please report security vulnerabilities via GitHub's private vulnerability reporting:
1. Go to the Security tab of this repository
2. Click "Report a vulnerability"
3. Fill out the form

Do NOT open a public issue for security vulnerabilities.
EOF
```

---

## Phase 2: Issue Templates & Forms

### 2.1 Issue Template Config

```yaml
# .github/ISSUE_TEMPLATE/config.yml
blank_issues_enabled: false
contact_links:
  - name: Documentation
    url: https://github.com/{owner}/{repo}/tree/main/docs
    about: Check our docs before filing an issue.
  - name: Discussions
    url: https://github.com/{owner}/{repo}/discussions
    about: Ask questions and share ideas in Discussions.
```

### 2.2 Bug Report Template (YAML Form)

```yaml
# .github/ISSUE_TEMPLATE/bug.yml
name: Bug Report
description: Report a bug or unexpected behavior
title: "[bug] "
labels: ["type:bug"]
assignees: []
body:
  - type: markdown
    attributes:
      value: |
        ## Bug Report
        Provide enough detail for reproduction.

  - type: textarea
    id: description
    attributes:
      label: Bug Description
      description: "What happened? What did you expect?"
      placeholder: "Describe the bug clearly."
    validations:
      required: true

  - type: textarea
    id: reproduction
    attributes:
      label: Steps to Reproduce
      description: "Exact steps, commands, or code to trigger the bug."
      placeholder: |
        1. Run command X
        2. Observe error Y
        3. Check logs: error at line Z
    validations:
      required: true

  - type: textarea
    id: expected
    attributes:
      label: Expected Behavior
      description: "What should happen instead?"
    validations:
      required: true

  - type: textarea
    id: diagnostics
    attributes:
      label: "Diagnostic output"
      description: "Paste any diagnostic command output (e.g., `your-tool doctor`)."
      render: shell

  - type: textarea
    id: environment
    attributes:
      label: Environment
      description: "OS, runtime version, install method, relevant config."
      placeholder: "Ubuntu 24.04, Python 3.12, pip install"

  - type: dropdown
    id: severity
    attributes:
      label: Severity
      options:
        - "critical (service down)"
        - "high (major feature broken)"
        - "medium (workaround exists)"
        - "low (cosmetic / edge case)"
    validations:
      required: true
```

### 2.3 Feature Request Template

```yaml
# .github/ISSUE_TEMPLATE/feature.yml
name: Feature Request
description: Propose a new feature or enhancement
title: "[feature] "
labels: ["type:feature"]
body:
  - type: textarea
    id: problem
    attributes:
      label: Problem Statement
      description: "What problem does this solve? Who is affected?"
    validations:
      required: true

  - type: textarea
    id: solution
    attributes:
      label: Proposed Solution
      description: "How should this work? Include API design, UI mockups, or CLI examples."
    validations:
      required: true

  - type: textarea
    id: alternatives
    attributes:
      label: Alternatives Considered
      description: "What other approaches did you consider?"

  - type: dropdown
    id: scope
    attributes:
      label: Scope
      options:
        - "Small (1-2 files, < 1 day)"
        - "Medium (3-10 files, 1-3 days)"
        - "Large (10+ files, multi-day)"
        - "Epic (cross-cutting, needs breakdown)"
    validations:
      required: true
```

### 2.4 Chore/Maintenance Template

```yaml
# .github/ISSUE_TEMPLATE/chore.yml
name: Chore / Maintenance
description: Dependency updates, refactoring, cleanup, infra work
title: "[chore] "
labels: ["type:chore"]
body:
  - type: textarea
    id: description
    attributes:
      label: Description
      description: "What needs to be done and why?"
    validations:
      required: true

  - type: textarea
    id: acceptance
    attributes:
      label: Acceptance Criteria
      description: "How do we know this is done?"
    validations:
      required: true
```

**YAML gotcha**: Step names containing `: ` (colon-space) break YAML parsing. Always quote step names that contain colons.

### 2.5 Issue Types (Organization-Level, GA since April 2025)

Issue Types provide standardized classification across all repos in an organization. Unlike labels, they're a first-class concept with dedicated UI, filtering, and project integration.

**Setup** (requires organization — not available for personal accounts):
1. Go to Organization Settings > Planning > Issue Types
2. Default types: `Bug`, `Task`, `Feature` (pre-configured)
3. Create up to **25 custom types** (e.g., `Epic`, `Chore`, `Research`, `Spike`)
4. Each type gets an icon and color
5. Types appear in the issue creation flow, project views, and filters
6. Timeline events track when types are added/updated/removed

**Benefits over labels for classification**:
- Organization-wide consistency (labels are per-repo)
- Dedicated UI element with icon (not just a colored tag)
- Advanced search: `is:issue type:Bug OR type:Feature`
- Project insights can chart by type
- Issue Type is a synced field in Projects V2 (auto-populated)

**Note**: For personal (non-org) repos, use `type:*` labels as the equivalent.

### 2.6 File Upload Fields in Issue Forms (March 2026)

Issue forms now support file upload fields — require logs, screenshots, or crash reports:

```yaml
  - type: textarea
    id: logs
    attributes:
      label: "Attach logs or screenshots"
      description: "Drag and drop files here, or paste screenshots."
    validations:
      required: false
```

---

## Phase 3: Label Taxonomy

A well-designed label system is the backbone of filtering, automation, and reporting. Use a **namespaced** approach.

```bash
# Type labels (what kind of work)
gh label create "type:bug"       --color "d73a4a" --description "Something isn't working" --force
gh label create "type:feature"   --color "0075ca" --description "New functionality" --force
gh label create "type:chore"     --color "cfd3d7" --description "Maintenance, deps, cleanup" --force
gh label create "type:docs"      --color "0075ca" --description "Documentation only" --force
gh label create "type:security"  --color "d73a4a" --description "Security fix or hardening" --force
gh label create "type:test"      --color "bfdadc" --description "Test coverage" --force

# Priority labels (how urgent)
gh label create "priority:critical" --color "b60205" --description "Drop everything" --force
gh label create "priority:high"     --color "d93f0b" --description "Next up" --force
gh label create "priority:medium"   --color "fbca04" --description "Important but not urgent" --force
gh label create "priority:low"      --color "0e8a16" --description "Nice to have" --force

# Size labels (estimation)
gh label create "size:xs" --color "c5def5" --description "< 1 hour" --force
gh label create "size:s"  --color "c5def5" --description "1-4 hours" --force
gh label create "size:m"  --color "c5def5" --description "1-2 days" --force
gh label create "size:l"  --color "c5def5" --description "3-5 days" --force
gh label create "size:xl" --color "c5def5" --description "1+ week, consider breaking down" --force

# Status labels (workflow state beyond project board)
gh label create "status:blocked"    --color "b60205" --description "Waiting on external dependency" --force
gh label create "status:in-review"  --color "fbca04" --description "PR open, awaiting review" --force
gh label create "status:needs-spec" --color "d876e3" --description "Needs design/spec before work" --force
gh label create "status:deferred"   --color "cfd3d7" --description "Parked — not abandoned" --force

# Phase labels (roadmap alignment)
gh label create "phase:1" --color "006b75" --description "Phase 1 scope" --force
gh label create "phase:2" --color "006b75" --description "Phase 2 scope" --force
gh label create "phase:3" --color "006b75" --description "Phase 3 scope" --force
# Add more as needed

# Epic labels (cross-cutting themes)
gh label create "epic:auth"         --color "5319e7" --description "Authentication & authorization" --force
gh label create "epic:api"          --color "5319e7" --description "API design & endpoints" --force
gh label create "epic:frontend"     --color "5319e7" --description "UI/UX work" --force
gh label create "epic:infra"        --color "5319e7" --description "Infrastructure & deployment" --force
gh label create "epic:security"     --color "5319e7" --description "Security hardening" --force
gh label create "epic:observability" --color "5319e7" --description "Monitoring, logging, metrics" --force

# Agent labels (who/what is working on it — useful for AI-assisted development)
gh label create "agent:human"   --color "ededed" --description "Requires human action" --force
gh label create "agent:copilot" --color "ededed" --description "AI agent can handle" --force

# Special labels
gh label create "good first issue" --color "7057ff" --description "Good for newcomers" --force
gh label create "help wanted"      --color "008672" --description "Extra attention needed" --force
gh label create "e2e-test"         --color "bfdadc" --description "Requires E2E/hardware testing" --force
```

**Design principles**:
- Namespace with `:` (type:, priority:, size:, status:, phase:, epic:, agent:)
- Every issue should have at minimum: `type:*` + `priority:*`
- Epics get their own labels for cross-repo filtering
- `agent:human` vs `agent:copilot` enables AI triage

---

## Phase 4: GitHub Projects V2

### 4.1 Create the Project

```bash
# Create project (returns project number)
gh project create --owner "{owner}" --title "{Project Name} Roadmap" --format json

# Get the project ID (needed for GraphQL)
PROJECT_NUM=5  # your project number
PROJECT_ID=$(gh project view $PROJECT_NUM --owner "{owner}" --format json --jq '.id')
echo "Project ID: $PROJECT_ID"
```

### 4.2 Custom Fields

Projects V2 supports these field types: **Text**, **Number**, **Date**, **Single Select**, **Iteration**. Configure fields that match your workflow.

```bash
# Get existing field IDs
gh project field-list $PROJECT_NUM --owner "{owner}" --format json | \
  python3 -c "import json,sys; [print(f'{f[\"name\"]}: {f[\"id\"]}') for f in json.load(sys.stdin)['fields']]"

# Add custom single-select fields via GraphQL
# (gh project field-create doesn't support all options)

# Priority field
gh api graphql -f query='mutation {
  createProjectV2Field(input: {
    projectId: "'$PROJECT_ID'"
    dataType: SINGLE_SELECT
    name: "Priority"
    singleSelectOptions: [
      {name: "P0-Blocker",   color: RED,    description: "Drop everything — blocking launch or causing outage"}
      {name: "P1-Critical",  color: ORANGE, description: "Must be done this sprint — core functionality"}
      {name: "P2-Important", color: YELLOW, description: "Should be done soon — quality/UX impact"}
      {name: "P3-Nice",      color: GREEN,  description: "Backlog — do when capacity allows"}
    ]
  }) { projectV2Field { ... on ProjectV2SingleSelectField { id name } } }
}'

# Phase field
gh api graphql -f query='mutation {
  createProjectV2Field(input: {
    projectId: "'$PROJECT_ID'"
    dataType: SINGLE_SELECT
    name: "Phase"
    singleSelectOptions: [
      {name: "Phase 1", color: BLUE,   description: "Foundation / MVP"}
      {name: "Phase 2", color: GREEN,  description: "Core features"}
      {name: "Phase 3", color: YELLOW, description: "Scale / hardening"}
      {name: "Phase 4", color: ORANGE, description: "Growth / optimization"}
    ]
  }) { projectV2Field { ... on ProjectV2SingleSelectField { id name } } }
}'

# Size field
gh api graphql -f query='mutation {
  createProjectV2Field(input: {
    projectId: "'$PROJECT_ID'"
    dataType: SINGLE_SELECT
    name: "Size"
    singleSelectOptions: [
      {name: "XS", color: GRAY,   description: "< 1 hour, trivial change"}
      {name: "S",  color: BLUE,   description: "1-4 hours, single file or component"}
      {name: "M",  color: GREEN,  description: "1-2 days, moderate complexity"}
      {name: "L",  color: YELLOW, description: "3-5 days, cross-cutting changes"}
      {name: "XL", color: RED,    description: "1+ week, consider breaking down"}
    ]
  }) { projectV2Field { ... on ProjectV2SingleSelectField { id name } } }
}'

# Epic field (for grouping in views)
gh api graphql -f query='mutation {
  createProjectV2Field(input: {
    projectId: "'$PROJECT_ID'"
    dataType: SINGLE_SELECT
    name: "Epic"
    singleSelectOptions: [
      {name: "Auth",         color: PURPLE, description: "Authentication & authorization"}
      {name: "API",          color: BLUE,   description: "API design & endpoints"}
      {name: "Frontend",     color: GREEN,  description: "UI/UX"}
      {name: "Infra",        color: ORANGE, description: "Infrastructure & deployment"}
      {name: "Launch",       color: RED,    description: "Go-live requirements"}
    ]
  }) { projectV2Field { ... on ProjectV2SingleSelectField { id name } } }
}'
```

### 4.3 Add Issues to Project and Set Field Values

```bash
# Add an issue to the project
ITEM_ID=$(gh project item-add $PROJECT_NUM --owner "{owner}" --url "https://github.com/{owner}/{repo}/issues/123" --format json --jq '.id')

# Set field values (need field ID and option ID)
# First, get them:
gh api graphql -f query='{ node(id: "'$PROJECT_ID'") { ... on ProjectV2 { fields(first: 30) { nodes { ... on ProjectV2SingleSelectField { id name options { id name } } } } } } }' \
  --jq '.data.node.fields.nodes[] | select(.options) | {name, options: [.options[] | {name, id}]}'

# Then set a value:
gh api graphql -f query='mutation {
  updateProjectV2ItemFieldValue(input: {
    projectId: "'$PROJECT_ID'"
    itemId: "'$ITEM_ID'"
    fieldId: "FIELD_ID_HERE"
    value: { singleSelectOptionId: "OPTION_ID_HERE" }
  }) { projectV2Item { id } }
}'
```

### 4.4 Sub-Issues (Parent-Child Hierarchy)

Sub-issues (GA since late 2025) replace the deprecated Tasklists. They create real parent-child relationships between issues, with progress tracking built into the parent.

```bash
# Add a sub-issue to a parent
gh api graphql -f query='mutation {
  addSubIssue(input: {
    issueId: "PARENT_ISSUE_NODE_ID"
    subIssueId: "CHILD_ISSUE_NODE_ID"
  }) { issue { id title } subIssue { id title } }
}'

# Reorder sub-issues (dependency chain)
# afterId=null puts it first; afterId=<sibling> puts it after that sibling
gh api graphql -f query='mutation {
  reprioritizeSubIssue(input: {
    issueId: "PARENT_ISSUE_NODE_ID"
    subIssueId: "CHILD_ISSUE_NODE_ID"
    afterId: "PREVIOUS_SIBLING_NODE_ID"
  }) { issue { id } }
}'
```

**Architecture pattern**: Create epic issues as parents, milestone work items as children, ordered by dependency. Up to 8 nesting levels. Each parent shows a progress bar of completed children.

Example hierarchy:
```
Epic: Authentication System (parent)
  ├── M1: OAuth2 provider setup (child, first)
  ├── M2: Session management (child, after M1)
  ├── M3: RBAC implementation (child, after M2)
  └── M4: Security audit (child, after M3)
```

### 4.5 Milestones

Milestones group issues into time-boxed or goal-based releases. They provide progress bars and due dates.

```bash
# Create milestones
gh api repos/{owner}/{repo}/milestones -X POST \
  -f title="v1.0 MVP" \
  -f description="Minimum viable product — core features only" \
  -f due_on="2026-04-01T00:00:00Z" \
  -f state="open"

gh api repos/{owner}/{repo}/milestones -X POST \
  -f title="v1.1 Hardening" \
  -f description="Security, performance, monitoring" \
  -f state="open"

# Assign issues to milestones
gh issue edit 123 --milestone "v1.0 MVP"
gh issue edit 456 --milestone "v1.1 Hardening"

# View milestone progress
gh api repos/{owner}/{repo}/milestones \
  --jq '.[] | "\(.title): \(.open_issues) open, \(.closed_issues) closed"'
```

### 4.6 Pinned Issues

Pin up to 3 issues to the top of the Issues tab for high visibility:

```bash
# Pin an issue (via GraphQL — no gh CLI shortcut)
gh api graphql -f query='mutation {
  pinIssue(input: { issueId: "ISSUE_NODE_ID" }) {
    issue { id title isPinned }
  }
}'

# Unpin
gh api graphql -f query='mutation {
  unpinIssue(input: { issueId: "ISSUE_NODE_ID" }) {
    issue { id isPinned }
  }
}'
```

Good candidates for pinning:
- Current release tracker / roadmap epic
- Contributing guidelines or "start here" issue
- Known issues / breaking changes notice

### 4.7 Status Updates

Post project-level status updates visible on the Project Overview tab. Great for stakeholder communication.

```bash
# Post a status update
gh api graphql -f query='mutation {
  createProjectV2StatusUpdate(input: {
    projectId: "'$PROJECT_ID'"
    body: "## Sprint 3 Complete\n\n- Finished auth system (M1-M3)\n- API endpoints 80% done\n- Blocked on DNS configuration\n\n**Next**: Security audit + deployment pipeline"
    status: ON_TRACK
    startDate: "2026-03-01"
    targetDate: "2026-04-15"
  }) { statusUpdate { id body status } }
}'

# Status options: INACTIVE, ON_TRACK, AT_RISK, OFF_TRACK, COMPLETE
```

### 4.8 Project Views (Manual — API doesn't support view creation)

Create these 4 views in the GitHub UI (Settings > Views in your project):

**View 1: Roadmap (Timeline)**
- Layout: Roadmap
- Group by: Phase
- Date field: map to milestone due dates or a custom Date field
- Use for: high-level planning, stakeholder presentations

**View 2: Sprint Board (Board)**
- Layout: Board
- Columns: Status field (Todo / In Progress / In Review / Done)
- Filter: `status:Todo,In Progress,In Review` (hide Done)
- Slice by: Priority
- Use for: daily workflow, current sprint

**View 3: By Epic (Table)**
- Layout: Table
- Group by: Epic field
- Sort by: Priority (descending)
- Columns: Status, Priority, Size, Phase, Assignee
- Use for: cross-cutting progress, epic health

**View 4: By Milestone (Table)**
- Layout: Table
- Group by: Milestone
- Sort by: Priority
- Columns: Status, Size, Labels
- Use for: release planning, milestone progress

**View 5: Hierarchy (Public Preview, Jan 2026)**
- Layout: Hierarchy
- Shows: nested sub-issue tree up to 8 levels
- Features: expand/collapse state persists, inline sub-issue creation, drag-and-drop reparenting
- Filters: `sub-issues.is:open`, `sub-issues.is:closed`
- Deduplication: items in multiple branches shown once
- Use for: epic breakdown, dependency visualization, progress tracking

### 4.9 Project Insights & Charts

Built-in analytics on the Insights tab of your project:

- **Default chart**: Shows items by Status (configurable)
- **Custom charts**: Create burn-up, burn-down, or distribution charts
- **Filter**: By any field (Priority, Epic, Assignee, etc.)
- **Chart types**: Bar, stacked bar, line (burn-up)

Configure by clicking "New chart" on the Insights tab. Use burn-up charts for milestone tracking and distribution charts for workload balance.

### 4.10 Project Automations (Built-In)

Projects V2 has built-in automation rules (no Actions required):

1. Go to Project Settings > Workflows
2. Enable built-in automations:
   - **Item added to project** → set Status to "Todo"
   - **Item reopened** → set Status to "Todo"
   - **Item closed** → set Status to "Done"
   - **PR merged** → set Status to "Done"
   - **Code changes requested** → set Status to "Changes Requested"
   - **PR approved** → set Status to "Approved"
   - **Auto-add items** → automatically add issues/PRs matching filters
   - **Auto-archive** → archive items matching criteria (e.g., closed > 30 days)

These are UI-only configurations (not available via API). Enable all that match your workflow.

### 4.11 Iteration Fields (Sprint Planning)

Iteration fields model time-boxed work periods with optional breaks:

```bash
# Create an iteration field
gh api graphql -f query='mutation {
  createProjectV2Field(input: {
    projectId: "'$PROJECT_ID'"
    dataType: ITERATION
    name: "Sprint"
  }) { projectV2Field { ... on ProjectV2IterationField { id name } } }
}'
```

Configure iterations in the project UI:
- Set sprint duration (1 week, 2 weeks, etc.)
- Add breaks between sprints (holidays, cooldowns)
- Iterations auto-advance — current sprint highlighted

### 4.12 Query-Based Import (February 2026)

Populate projects directly from search queries:

1. On your project, click "+" > "Add from search"
2. Use advanced search syntax: `is:issue label:type:bug state:open repo:owner/repo`
3. Supports AND/OR/nested queries
4. Bulk-adds matching items to the project

### 4.13 Project Templates

Save your project configuration (fields, views, automations) as a template:

1. Go to project Settings > "Make a template"
2. Template preserves: custom fields, views, automations, field options
3. New projects can start from your template
4. Great for standardizing across multiple repos/teams

---

## Phase 5: GitHub Actions CI/CD

### 5.1 Pro Plan Resources

- **3,000 minutes/month** for GitHub-hosted runners
- **2 GB** Packages storage
- **Linux runners**: 4 vCPU, 16 GB RAM, 14 GB SSD
- **Action allowlisting**: restrict which actions can run (security)

### 5.2 Self-Healing CI Pipeline

```yaml
# .github/workflows/ci.yml
name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

concurrency:
  group: ci-${{ github.ref }}
  cancel-in-progress: true  # Cancel stale runs on same branch

permissions:
  contents: read
  checks: write
  pull-requests: write

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5  # or setup-node, etc.
        with:
          python-version: "3.12"
          cache: pip
      - run: pip install -e ".[dev]"
      - run: ruff check .
      - run: ruff format --check .

  typecheck:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.12"
          cache: pip
      - run: pip install -e ".[dev]"
      - run: mypy src/ --ignore-missing-imports

  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with:
          python-version: "3.12"
          cache: pip
      - run: pip install -e ".[dev]"
      - run: pytest tests/ -v --cov=src --cov-report=term-missing

  security:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: github/codeql-action/init@v3
        with:
          languages: python  # or javascript, etc.
      - uses: github/codeql-action/analyze@v3

  # Verification gate — all checks must pass
  gate:
    needs: [lint, typecheck, test, security]
    if: always()
    runs-on: ubuntu-latest
    steps:
      - name: "Check all jobs passed"
        run: |
          if [[ "${{ needs.lint.result }}" != "success" ]] ||
             [[ "${{ needs.typecheck.result }}" != "success" ]] ||
             [[ "${{ needs.test.result }}" != "success" ]] ||
             [[ "${{ needs.security.result }}" != "success" ]]; then
            echo "One or more required jobs failed"
            exit 1
          fi
          echo "All checks passed"
```

**Key patterns**:
- `concurrency` with `cancel-in-progress` saves minutes on rapid pushes
- `if: always()` on the gate job ensures it runs even if siblings fail
- Cache pip/npm/cargo to cut install time by 60-90%
- Use the gate job name as your ruleset `required_status_checks` context

### 5.3 Auto-Labeler

```yaml
# .github/workflows/labeler.yml
name: Auto Label
on:
  pull_request:
    types: [opened, synchronize]

permissions:
  contents: read
  pull-requests: write

jobs:
  label:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/labeler@v5
        with:
          repo-token: "${{ secrets.GITHUB_TOKEN }}"
```

```yaml
# .github/labeler.yml (path-based label rules)
backend:
  - changed-files:
    - any-glob-to-any-file: ['src/**', 'tests/**']
frontend:
  - changed-files:
    - any-glob-to-any-file: ['frontend/**']
infrastructure:
  - changed-files:
    - any-glob-to-any-file: ['Dockerfile*', 'docker-compose*', '.github/**']
documentation:
  - changed-files:
    - any-glob-to-any-file: ['docs/**', '*.md']
```

### 5.4 Stale Issue Management

```yaml
# .github/workflows/stale.yml
name: Stale Issues
on:
  schedule:
    - cron: '0 6 * * 1'  # Weekly Monday 6am UTC
permissions:
  issues: write
  pull-requests: write

jobs:
  stale:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/stale@v9
        with:
          stale-issue-message: "This issue has been inactive for 60 days. It will be closed in 14 days unless there's new activity."
          stale-pr-message: "This PR has been inactive for 30 days. Please update or it will be closed."
          days-before-stale: 60
          days-before-close: 14
          stale-issue-label: "status:stale"
          exempt-issue-labels: "priority:critical,priority:high,status:blocked"
          exempt-pr-labels: "status:blocked"
```

### 5.5 Release Automation

```yaml
# .github/workflows/release.yml
name: Release
on:
  push:
    tags:
      - 'v*'

permissions:
  contents: write

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Build
        run: python -m build  # or npm run build
      - name: Create GitHub Release
        uses: softprops/action-gh-release@v2
        with:
          generate_release_notes: true
          files: dist/*
```

### 5.6 Dependabot

```yaml
# .github/dependabot.yml
version: 2
updates:
  - package-ecosystem: "pip"  # or npm, cargo, docker, github-actions
    directory: "/"
    schedule:
      interval: "weekly"
      day: "monday"
    open-pull-requests-limit: 5
    reviewers:
      - "your-username"
    labels:
      - "type:chore"
      - "dependencies"

  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "weekly"
    labels:
      - "type:chore"
      - "ci"
```

### 5.7 Action Allowlisting

Restrict which Actions can run in your repository for security:

1. Go to Settings > Actions > General
2. Under "Actions permissions", select "Allow select actions and reusable workflows"
3. Add trusted actions: `actions/*`, `github/*`, your org's actions
4. Block everything else

This prevents supply-chain attacks from compromised third-party Actions.

### 5.8 Environments & Secrets

```bash
# Create deployment environments
gh api repos/{owner}/{repo}/environments/staging -X PUT \
  --input - <<'EOF'
{
  "wait_timer": 0,
  "reviewers": [],
  "deployment_branch_policy": {
    "protected_branches": false,
    "custom_branch_policies": true
  }
}
EOF

gh api repos/{owner}/{repo}/environments/production -X PUT \
  --input - <<'EOF'
{
  "wait_timer": 5,
  "reviewers": [{"type": "User", "id": YOUR_USER_ID}],
  "deployment_branch_policy": {
    "protected_branches": true,
    "custom_branch_policies": false
  }
}
EOF
```

Environment secrets are scoped — staging secrets can't leak to production and vice versa. Use environments in workflows:

```yaml
jobs:
  deploy:
    environment: production
    steps:
      - run: echo "Deploying with ${{ secrets.PROD_API_KEY }}"
```

### 5.9 OIDC for Cloud Deployments

GitHub Actions supports OpenID Connect (OIDC) for passwordless authentication to cloud providers. No long-lived secrets needed.

```yaml
# Example: AWS deployment without access keys
permissions:
  id-token: write
  contents: read

steps:
  - uses: aws-actions/configure-aws-credentials@v4
    with:
      role-to-assume: arn:aws:iam::123456789:role/github-deploy
      aws-region: us-east-1
  # No AWS_ACCESS_KEY_ID or AWS_SECRET_ACCESS_KEY needed!
```

Works with: AWS, Azure, GCP, HashiCorp Vault, and any OIDC-compatible provider. Eliminates the #1 cause of CI/CD secret leaks.

### 5.10 Post-Deploy Verification

```yaml
# .github/workflows/post-deploy-verify.yml
name: Post-Deploy Verify
on:
  deployment_status:
    types: [completed]

jobs:
  verify:
    if: github.event.deployment_status.state == 'success'
    runs-on: ubuntu-latest
    steps:
      - name: Health check
        run: |
          curl -sf https://your-domain.com/health || exit 1
          echo "Deployment healthy"
```

---

## Phase 6: Security Hardening

### 6.1 CodeQL Analysis

```yaml
# .github/workflows/codeql.yml
name: CodeQL
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  schedule:
    - cron: '0 4 * * 1'  # Weekly deep scan

permissions:
  security-events: write
  contents: read

jobs:
  analyze:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        language: [python]  # Add: javascript, go, java, etc.
    steps:
      - uses: actions/checkout@v4
      - uses: github/codeql-action/init@v3
        with:
          languages: ${{ matrix.language }}
      - uses: github/codeql-action/analyze@v3
```

### 6.2 Secret Scanning

Enabled by default on Pro for public repos. For private repos:
1. Go to Settings > Code security and analysis
2. Enable "Secret scanning"
3. Enable "Push protection" (blocks pushes containing secrets)

### 6.3 Private Vulnerability Reporting

Enable in Settings > Security > "Private vulnerability reporting". This lets security researchers report issues without creating public issues.

### 6.4 Dependency Graph

Enabled by default. Go to Insights > Dependency graph to view. Combined with Dependabot alerts, this gives you automatic CVE monitoring.

---

## Phase 7: Collaboration Features

### 7.1 Discussions

Enable in Settings > Features > Discussions. Create categories:
- **Announcements** (maintainers only)
- **Q&A** (community questions, mark answers)
- **Ideas** (feature brainstorming)
- **Show and Tell** (community projects using your tool)

### 7.2 Wiki

For internal documentation that doesn't fit in `/docs/`:
- Architecture decisions
- Runbooks
- Onboarding guides

### 7.3 GitHub Pages

Free with Pro. Use for project documentation site:
```yaml
# .github/workflows/pages.yml
name: Deploy Docs
on:
  push:
    branches: [main]
    paths: ['docs/**']

permissions:
  pages: write
  id-token: write

jobs:
  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/configure-pages@v4
      - uses: actions/upload-pages-artifact@v3
        with:
          path: docs/
      - uses: actions/deploy-pages@v4
        id: deployment
```

### 7.4 Draft PRs

Use draft PRs for:
- Work-in-progress that needs early feedback
- CI validation before review
- Establishing intent (blocks others from duplicating work)

```bash
gh pr create --draft --title "WIP: feature X" --body "Early draft, not ready for review"
```

---

## Phase 8: API Automation & Webhooks

### 8.1 GraphQL API — Key Mutations

The GitHub GraphQL API enables full project automation. Key mutations:

**Project Management**:
- `createProjectV2` / `deleteProjectV2` / `updateProjectV2`
- `addProjectV2ItemById` / `removeProjectV2Item`
- `updateProjectV2ItemFieldValue` / `clearProjectV2ItemFieldValue`
- `createProjectV2Field` / `updateProjectV2Field` / `deleteProjectV2Field`
- `createProjectV2StatusUpdate`
- `addSubIssue` / `removeSubIssue` / `reprioritizeSubIssue`

**Issue Management**:
- `createIssue` / `updateIssue` / `deleteIssue`
- `addLabelsToLabelable` / `removeLabelsFromLabelable`
- `createLabel` / `updateLabel` / `deleteLabel`
- `addAssigneesToAssignable`

**PR Management**:
- `createPullRequest` / `updatePullRequest` / `mergePullRequest`
- `enablePullRequestAutoMerge` / `disablePullRequestAutoMerge`
- `addPullRequestReview`
- `markPullRequestReadyForReview` / `convertPullRequestToDraft`

### 8.2 Schema Introspection

When building automation, always introspect the schema to verify mutations exist:

```bash
# List all available mutations
gh api graphql -f query='{ __type(name: "Mutation") { fields { name description } } }' \
  --jq '.data.__type.fields | length'  # Total count

# Check specific mutation signature
gh api graphql -f query='{ __type(name: "Mutation") { fields { name args { name type { name kind ofType { name } } } } } }' \
  --jq '.data.__type.fields[] | select(.name == "addSubIssue")'

# Check return type of a mutation
gh api graphql -f query='{ __type(name: "AddSubIssuePayload") { fields { name type { name } } } }'
```

### 8.3 Webhooks

Configure webhooks for external integrations:
```bash
# List existing webhooks
gh api repos/{owner}/{repo}/hooks

# Create a webhook
gh api repos/{owner}/{repo}/hooks -X POST \
  -f 'config[url]=https://your-server.com/webhook' \
  -f 'config[content_type]=json' \
  -f 'config[secret]=YOUR_SECRET' \
  -F 'events[]=push' \
  -F 'events[]=pull_request' \
  -F 'events[]=issues' \
  -f 'active=true'
```

---

## Phase 9: Operational Workflows

### 9.1 Issue Lifecycle

```
Created → Triaged (labels + fields set) → Planned (on board + milestone) →
In Progress (branch created) → In Review (PR open) → Done (PR merged, issue closed)
```

Enforce this flow:
1. Issue templates force structured input
2. Labels auto-applied by labeler workflow
3. Project board tracks status
4. Ruleset requires PR + CI for main
5. Auto-close issues via PR body: `Closes #123`
6. Stale workflow catches abandoned work

### 9.2 PR Lifecycle

```
Draft PR → Ready for Review → CI passes → Review approved →
Merge queue (if enabled) → Squash merge → Branch auto-deleted
```

### 9.3 Cold Start Recovery

Any new contributor (human or AI) should be able to pick up the project from scratch:

```bash
# Step 1: Understand current state
gh issue list --state open --limit 30
gh pr list --state open
gh project item-list $PROJECT_NUM --owner "{owner}" --limit 30
gh run list --limit 5

# Step 2: Read project docs
cat CLAUDE.md      # or README.md, CONTRIBUTING.md
cat AGENTS.md      # if using AI tools

# Step 3: Check milestones and priorities
gh api repos/{owner}/{repo}/milestones --jq '.[] | "\(.title): \(.open_issues) open, \(.closed_issues) closed"'

# Step 4: Find highest-priority unblocked work
gh issue list --label "priority:critical" --state open
gh issue list --label "priority:high" --state open
```

---

## Phase 10: Checklist — Full Maximization Audit

Use this checklist to verify every capability is configured:

### Repository
- [ ] Squash merge only, auto-delete branches
- [ ] Topics set for discoverability
- [ ] CODEOWNERS file with path-based ownership
- [ ] PR template (`.github/PULL_REQUEST_TEMPLATE.md`)
- [ ] SECURITY.md with private vulnerability reporting instructions
- [ ] CONTRIBUTING.md with development standards

### Branch Protection
- [ ] Ruleset (not legacy branch protection) on `main`
- [ ] Require PR (no direct push)
- [ ] Require status checks (exact CI job name match)
- [ ] Require code owner review
- [ ] Require conversation resolution
- [ ] Block force push and branch deletion
- [ ] Consider: required signatures, linear history

### Issues
- [ ] Issue forms (YAML, not markdown templates) — bug, feature, chore minimum
- [ ] `config.yml` disables blank issues, adds contact links
- [ ] Pinned issues for important notices
- [ ] Sub-issues for epic breakdown

### Labels
- [ ] Namespaced taxonomy: type, priority, size, status, phase, epic, agent
- [ ] Every label has a description
- [ ] Consistent color scheme per namespace

### Project Board
- [ ] Project V2 created and linked to repo
- [ ] Custom fields: Status, Priority, Phase, Size, Epic (minimum)
- [ ] All open issues added to board with fields populated
- [ ] 4 views: Roadmap, Sprint Board, By Epic, By Milestone
- [ ] Status update posted with current state

### Milestones
- [ ] Active milestones created for current + next release
- [ ] Due dates set where applicable
- [ ] Issues assigned to milestones

### CI/CD
- [ ] Main CI workflow with lint, typecheck, test, security jobs
- [ ] Verification gate job (`if: always()`)
- [ ] Concurrency control (`cancel-in-progress`)
- [ ] Caching (pip/npm/cargo)
- [ ] Auto-labeler workflow
- [ ] Stale issue workflow
- [ ] Release workflow (tag-triggered)
- [ ] Dependabot configured for all ecosystems

### Security
- [ ] CodeQL workflow (scheduled + PR-triggered)
- [ ] Secret scanning enabled
- [ ] Push protection enabled
- [ ] Dependabot alerts enabled
- [ ] Dependabot security updates enabled
- [ ] Private vulnerability reporting enabled
- [ ] Dependency graph reviewed

### Collaboration
- [ ] Discussions enabled with categories
- [ ] Wiki enabled (if applicable)
- [ ] GitHub Pages for documentation (if applicable)
- [ ] Draft PR workflow documented

### Automation
- [ ] Webhooks configured for external integrations (if applicable)
- [ ] Project automations: PR merged → Done, Issue closed → Done
- [ ] Bot/CI comments on PRs (coverage, deployment preview)

---

## Appendix A: GraphQL Quick Reference

```bash
# Get project ID
gh project view $NUM --owner $OWNER --format json --jq '.id'

# Get issue node ID
gh issue view $NUM --json id --jq '.id'

# List project fields and option IDs
gh api graphql -f query='{ node(id: "'$PID'") { ... on ProjectV2 { fields(first: 30) {
  nodes { ... on ProjectV2SingleSelectField { id name options { id name } } } } } } }'

# Set field value on project item
gh api graphql -f query='mutation { updateProjectV2ItemFieldValue(input: {
  projectId: "'$PID'" itemId: "'$IID'" fieldId: "'$FID'"
  value: { singleSelectOptionId: "'$OID'" }
}) { projectV2Item { id } } }'

# Create sub-issue relationship
gh api graphql -f query='mutation { addSubIssue(input: {
  issueId: "'$PARENT'" subIssueId: "'$CHILD'"
}) { issue { id } subIssue { id } } }'

# Post status update
gh api graphql -f query='mutation { createProjectV2StatusUpdate(input: {
  projectId: "'$PID'" body: "Update text" status: ON_TRACK
  startDate: "2026-01-01" targetDate: "2026-06-30"
}) { statusUpdate { id } } }'
```

## Appendix B: Feature Availability Matrix

| Feature | Free | Pro ($4/mo) | Team ($4/user/mo) |
|---------|------|-------------|---------------------|
| Public repos | Unlimited | Unlimited | Unlimited |
| Private repos | Unlimited | Unlimited | Unlimited |
| Actions minutes/month | 2,000 | 3,000 | 3,000 |
| Concurrent Actions jobs | 20 | 40 | 60 |
| Artifact/Packages storage | 500 MB | 1 GB | 2 GB |
| Cache storage | 10 GB | 10 GB | 10 GB |
| Codespaces core hours/month | 120 | 180 | — |
| Codespaces storage/month | 15 GB | 20 GB | — |
| Branch protection (private) | No | Yes | Yes |
| Required reviewers (private) | No | Yes | Yes |
| CODEOWNERS (private) | No | Yes | Yes |
| Environments (private) | No | Yes | Yes |
| Draft PRs | Yes | Yes | Yes |
| Projects V2 (all features) | Yes | Yes | Yes |
| Sub-issues (100/parent, 8 levels) | Yes | Yes | Yes |
| Issue Types (org-level) | Yes | Yes | Yes |
| Milestones | Yes | Yes | Yes |
| CodeQL (private repos) | No | No (add-on) | No (add-on) |
| Secret scanning (private repos) | No | No (add-on $19/user) | No (add-on) |
| Secret scanning (public repos) | Yes | Yes | Yes |
| Push protection (public repos) | Yes | Yes | Yes |
| Dependabot (all features) | Yes | Yes | Yes |
| SBOM export | Yes | Yes | Yes |
| GitHub Pages (private repos) | No | Yes | Yes |
| Wiki (private repos) | No | Yes | Yes |
| Discussions | Yes | Yes | Yes |
| Merge queue | No | No | Yes (org only) |
| Support | Community | Email | Email |

**Critical clarification (April 2025 change)**: GitHub split Advanced Security into two add-on products:
- **Secret Protection** ($19/user/mo): Secret scanning + push protection for private repos
- **Code Security** (separate pricing): CodeQL, Copilot Autofix, dependency review for private repos

Pro gives you the critical solo-dev features: branch protection, required reviewers, CODEOWNERS, environments, Pages, and wiki on private repos. For security scanning on private repos, you need the add-ons (but public repos get everything free).

## Appendix C: Common Gotchas

1. **Ruleset check names must match exactly** — `"CI / Test"` ≠ `"test"`. Use the exact string from Actions.
2. **YAML issue templates**: Step names with `: ` (colon-space) break parsing. Always quote.
3. **`createProjectV2View` doesn't exist in the API** — views must be created in the browser UI.
4. **`updateProjectV2Field` doesn't accept `projectId`** — the field ID alone is sufficient.
5. **`createProjectV2StatusUpdate` returns `statusUpdate`** not `projectV2StatusUpdate`.
6. **GraphQL `singleSelectOptions` require `description`** field — not optional.
7. **Labels with `--force`** — use `gh label create --force` to update existing labels without error.
8. **Milestone assignment** — `gh issue edit --milestone` takes the milestone **title**, not ID.
9. **Sub-issue ordering** — `reprioritizeSubIssue` with `afterId: null` puts the issue first.
10. **Branch protection blocks `git push origin main`** — always use feature branches + PRs.

## Appendix D: 2025-2026 Feature Timeline

Track what shipped and when, so you know what's available:

| Date | Feature | Impact |
|------|---------|--------|
| **Mar 2025** | GitHub split Advanced Security → Secret Protection + Code Security | Separate $19/user/mo add-ons |
| **Apr 2025** | Sub-issues GA (100/parent, 8 levels) | Replaces Tasklists (retired Apr 30) |
| **Apr 2025** | Issue Types GA (org-level, 25 custom) | Standardized classification |
| **Apr 2025** | Advanced Search GA (AND/OR/nested) | Complex filtering |
| **Apr 2025** | Projects: 50,000 item limit | Up from 1,200 |
| **Apr 2025** | Projects (classic) retired | V2 is the only option |
| **Nov 2025** | Actions cache > 10 GB (pay-as-you-go) | Expandable cache storage |
| **Nov 2025** | Reusable workflows: 10 nested, 50 total | Up from 4 nested, 20 total |
| **Jan 2026** | Hierarchy view in Projects (public preview) | Visual sub-issue trees |
| **Jan 2026** | Semantic search for Issues (public preview) | 39% better search results |
| **Jan 2026** | Actions runner pricing reduced up to 39% | Cost savings |
| **Feb 2026** | Query-based project import | Bulk-add from search |
| **Feb 2026** | Actions: action allowlisting (all plans) | Security: restrict which actions run |
| **Feb 2026** | Actions: non-zipped artifacts | `archive: false` option |
| **Feb 2026** | Copilot CLI GA | Agentic coding in terminal |
| **Mar 2026** | Hierarchy view: filtering, dedup, persist state | Sub-issue filtering in projects |
| **Mar 2026** | File upload fields in issue forms | Require attachments in templates |
| **Mid-2026** | Parallel steps in Actions (targeted) | Concurrent steps within a job |

## Appendix E: Actions Minute Multipliers

Different runner types consume included minutes at different rates:

| Runner | Per-Minute Cost | Minutes Multiplier |
|--------|-----------------|-------------------|
| Linux 2-core x64 | $0.006 | 1x (baseline) |
| Linux 2-core arm64 | $0.005 | 0.83x |
| Windows 2-core x64 | $0.010 | 1.67x |
| macOS 3-4 core | $0.062 | 10.3x |

**Pro plan budget**: 3,000 Linux minutes = ~1,800 Windows minutes = ~290 macOS minutes. Optimize by running platform-specific tests on Linux when possible.

---

*Generated from hands-on implementation on a production project (March 2026). Capabilities verified via GitHub GraphQL schema introspection (238 mutations cataloged), REST API testing, and extensive web research across GitHub Docs, Changelog, and community discussions.*
