An optional layer that mirrors each workspace's BMad artifacts to GitHub. Enable it during setup, or copy the skill's templates/.github workflows into the metarepo's .github/workflows/ later (replace the __SKILLS_DIR__ placeholder in sync-issues.yml with your tool's skills dir, e.g. .claude/skills).
Prerequisites: a generated metarepo, a GitHub account or org to host issues and boards, and the gh CLI authenticated.
Each workspace gets a private GitHub Project board and two label-separated issue trees:
- Delivery (
bmad-delivery): aDeliveryroot → Feature issues (one per PRD) → Epic issues → Story sub-issues. Epics/stories are driven by thedevelopment_status:map in BMad'ssprint-status.yaml; features come from the PRD run folders (prds/prd-*/prd.md), with the newest PRD holding the epics (BMad generatesepics.mdfrom it). Native sub-issue progress bars give per-epic and per-feature rollups for free; superseded PRDs close automatically. Issues are created in the metarepo by default; setrepo:in a workspace'sgithub-sync.yamlto keep its issues next to the code instead (step 1 below). - Planning (
bmad-planning, always in the metarepo): onePlanning: <workspace>checklist issue tracking which planning artifacts (brief, PRD, UX, architecture, epics) exist. This is the PM/architect view, separate from the engineering board.
- Push the metarepo to GitHub (issues live there by default; optionally set
repo:inworkspaces/<name>/github-sync.yamlto use the workspace's source repo; any org or personal account works). Boards can live under any owner too: the bootstrap asks where (saveable asproject_owner:in the metarepo-rootgithub-sync.yaml, overridable per workspace). - Run
bash .claude/skills/meta-router/scripts/bmad-github-bootstrap.sh <name>to create the private board, labels, and org issue types. On first run it offers to set up an org project template (name it whatever you like; the default is "BMad Project Template"): you build the views (Backlog, Epic Progress, Features, Planning; GitHub has no API for views) exactly once and every future board is copied from the template with views included. Views are visual-only: the script warns if the Backlog view is missing but never blocks on them, so add or change them anytime. The chosen name is saved astemplate:in a metarepo-rootgithub-sync.yaml(override per run withBMAD_TEMPLATE_NAME), alongside an auto-managedtemplate_id:; lookups go by that immutable ID first, so renaming the template later can't break the flow. Without a template (or on user accounts, where templates aren't supported) each board gets a printed view checklist instead. - Add a
BMAD_PROJECT_TOKENsecret: PAT with Projects read/write + Issues read/write + Pull requests read. The defaultGITHUB_TOKENcannot access Projects v2. If everything lives under one org, a fine-grained PAT works; if repos/boards span multiple orgs or your personal account, use a classic PAT (project+reposcopes; fine-grained PATs are single-owner) or a GitHub App installed per org. - Install
.claude/skills/meta-router/templates/.github/workflows/bmad-pr-ping.yml(bundled with the skill) into each source repo so story PRs update the board immediately (the nightly reconcile covers anything missed).
Per-workspace boards answer "how is this workspace going?"; the portfolio board answers "what is everyone doing?". Run
bash .claude/skills/meta-router/scripts/bmad-github-bootstrap.sh --portfolioto create one org-wide board that aggregates every workspace's delivery and planning issues. It gets the same Status options plus a Project single-select field with one option per BMad workspace, so views can group or filter by workspace (the bootstrap prints suggested views). The board number is saved as portfolio: (+ portfolio_owner:) in the metarepo-root github-sync.yaml; from then on every sync adds each issue to both its workspace board and the portfolio, sets Status on both, and stamps the Project field. New workspaces get their Project option appended automatically on first sync. Remove the portfolio: key to turn the fan-out off — per-workspace boards are unaffected. Re-running --portfolio repairs an existing board (Status options, missing Project field) instead of creating a duplicate. Mind GitHub's ~1,200 active items per board: archive Done items on the portfolio as it grows.
The sync is the single writer of issue state and board Status:
- BMad statuses map to
Backlog / Ready / In Progress / In Review / Done;donecloses the issue. - An open PR on a
story/<story-key>branch in anyrepos.yamlrepo forcesIn Review. Story PRs (one per affected repo) are linked onto the story issue automatically: a maintained Pull Requests section lists each PR with its repo and state (open/merged/closed). The scan covers the workspace'srepos.yamlrepos, plus its issues repo only whenrepo:is set explicitly — the defaulted metarepo holds every workspace's issues but no story branches. If two workspaces share a source repo, give their stories distinct slugs: astory/<key>branch can't tell which workspace's identical key it belongs to. - Stories that vanish after renumbering are closed as not-planned with a
bmad-orphanedlabel, never deleted. - Re-runs update rather than duplicate; each issue carries a hidden
<!-- bmad-sync:key:workspace -->marker. - Rate-limited API calls are retried with backoff and mutations are lightly spaced;
sync --allkeeps going past a broken workspace and reports the failures at the end (exit 1, so the Action run still flags it). Tunables are in the reference.
python .claude/skills/meta-router/scripts/bmad-issues.py sync --dry-runThe reference lists all flags.