feat(initiative-planner): cross-repo discussion_repo + PRD planning artifacts

Merged
DO
4d ago
+475-38

Why

Graduating WorldChest from combsmith/incubator to combsmith/worldchest on 2026-10-21 exposed two gaps in the planner:

  1. The approved idea's Discussion lived in the incubator (#5) but the epic belongs in the product repo. The dispatch failed with Could not resolve to a Discussion with the number of 5, and a mirror Discussion (worldchest #6) had to be hand-written.
  2. The planner never read the product repo's _bmad-output/planning-artifacts/, which org AGENTS.md names as the planning source of truth. Bob planned from Discussion prose instead of John's PRD.

What changed

AreaChange
initiative-planner.ymlNew optional discussion_repo input (default target_repo) → job env DISCUSSION_REPO; passed to apply-plan in Bob's prompt. GITHUB_TOKEN is used only when both target and discussion repo are self, otherwise the PAT. Concurrency key includes the discussion repo.
gather-context.shReads the Discussion and its referenced #N issues from DISCUSSION_REPO. Open epics, reconcile harvest and artifacts stay on REPO. Validates both repo slugs. New discussion_repo and planning_artifacts keys. Artifacts: contents-API listing; prd.md in full, other top-level .md truncated (PLANNING_ARTIFACT_MAX_CHARS, default 12000), at most 20 files, fetched raw into a temp dir (never on argv). 404 or no markdown → null, any other API error fails loud (same rule as decision-brief).
apply-plan.sh / lib/mutations.shCross-repo only: epic back-reference/idempotency key becomes Planned from idea discussion owner/repo#N, and issue links in the Discussion reply are qualified with the product repo. Same-repo output is byte-identical, so existing epics still bind. comment_on_discussion takes the discussion repo and logs it in DRY_RUN. The comment already routes to the Discussion's own repo through its global node id.
redispatch.shForwards DISCUSSION_REPO as discussion_repo only when set; the default dispatch is unchanged.
prompts/bmad/scrum-master.mdNew "Planning inputs" section. When a PRD exists, its FRs are the scope and its success metrics are the epic's metric; the Discussion is context. Conflicts go to open_questions. Cross-repo referenced_issues must not become blocked_by_existing_issues.
DocsGraduation flow in docs/initiatives/idea-to-initiative-pipeline.md; README row updated.

Tests

Added to tests/test_initiative_planner.bats, with gh mocked:

  • cross-repo discussion read (gather-context) plus cross-repo apply (back-reference, discussion_repo on the comment, qualified links)
  • same-repo apply unchanged (bare #N)
  • artifacts present (PRD full, brief truncated, png/dir skipped, raw fetch)
  • artifacts absent (null, context keys otherwise unchanged)
  • 404 on the folder → null, exit 0
  • non-404 error → fails loud
  • malformed DISCUSSION_REPO rejected before any API call
  • workflow wiring (yq)

Added to tests/test_initiative_planner_redispatch.bats: discussion_repo is omitted by default, forwarded when set, and rejected when malformed.

Local runs: the planner, redispatch, reconcile and materialize suites pass (102 tests). shellcheck --severity=warning -x, actionlint -ignore SC2129, markdownlint-cli2 and check-bats-negation are clean.

Not in this PR

  • combsmith/.github's initiative-planner-reusable.yml is untouched. It always plans same-repo, and the incubator has no planner stub, so graduation is a manual dispatch.
  • No release tag.

Next graduation

gh workflow run initiative-planner.yml --repo combsmith/.github-private \
  -f discussion=<N> -f discussion_repo=combsmith/incubator \
  -f target_repo=combsmith/<product> -f dry_run=true

🤖 Generated with Claude Code

Problem

See the linked issue.

Risk

Medium — changes GitHub Actions workflow behavior, which is exercised only post-merge; verify via the affected workflow runs.

Test plan

Tests added/updated: tests/test_initiative_planner.bats,tests/test_initiative_planner_redispatch.bats. Verification: bash scripts/dev-lead-lint.sh (shellcheck --severity=warning) ran pre-commit; the bats suite runs in CI.

Rollback

Revert this PR. No non-revertible side effects (no tags, migrations, or external state).

Monitoring

Watch the affected workflow run(s) in the Actions tab and this PR's Lint check for regressions.