Repository navigation
[Phase 3] Plan/apply split: apply consumes the dry-run's authoritative plan.json #604
Copy link
Copy link
Closed
Labels
dev-leadFor dev-lead agent pickupFor dev-lead agent pickupinitiativeEpic / initiative tracking issueEpic / initiative tracking issue
Description
Story
As a maintainer who reviewed a dry-run plan,
I want the apply run to load the exact plan.json the dry-run produced (optionally human-edited) instead of re-planning from scratch,
so that the preview binds the result — what a maintainer reviewed is what materializes.
Acceptance Criteria
- The dry-run produces an authoritative plan.json artifact (already uploaded today) that the apply run can be pointed at, and apply-plan.sh applies it without a re-plan (apply-plan.sh already reads PLAN_PATH).
- A documented mechanism lets a maintainer supply the reviewed plan.json to the apply run (workflow input / artifact handoff — chosen and documented; see open_questions).
- When a plan.json is supplied, the LLM planning step is skipped (no re-plan); validate-plan.py and apply-plan.sh still run on the supplied artifact.
- Backward path preserved: with no supplied plan, behavior is unchanged (Bob plans, then applies).
- scripts/initiative-planner/README.md and docs/initiatives/idea-to-initiative-pipeline.md describe the plan -> review -> apply split and where the human review point sits.
Tasks / Subtasks
- Add the apply-from-artifact path to initiative-planner.yml that skips the planning step when a reviewed plan.json is supplied. (AC: test issue from agent #1, Add @claude delegation, auto-merge, and rebase handling #3)
- Document and implement the handoff mechanism (workflow input / artifact download). (AC: Go-live improvements for PR review agent #2)
- Preserve the no-supplied-plan default behavior. (AC: Optimize review: small-PR and incremental fast paths #4)
- Update README.md and the pipeline doc to describe the split and the review gate. (AC: feat: add Copilot engine support via REVIEW_ENGINE toggle #5)
Dev Notes
- apply-plan.sh already consumes PLAN_PATH (apply-plan.sh:30-35) — the missing piece is letting the apply run LOAD a prior artifact instead of regenerating it. The dry-run already uploads plan.json at .github/workflows/initiative-planner.yml:178-186.
- This is discussion 💡 Adversarial Plan-Critic + Structural Gates for the Initiative-Planner (Bob) #593's explicit follow-on ("once the critic is trusted") — hence blocked by the critic story (id 6).
- Decide the handoff: a workflow_dispatch input pointing at a prior run/artifact to download vs a committed plan file. Artifact retention + cross-run download is the likely path — see open_questions.
- Keep the inert-epic discipline: even a human-reviewed plan still materializes WITHOUT initiative:auto (apply-plan.sh enforces this).
- Update both docs so the pipeline diagram in docs/initiatives/idea-to-initiative-pipeline.md reflects the new review point.
Project Structure Notes
Primarily a workflow + docs change; apply-plan.sh already supports loading an arbitrary PLAN_PATH. Sequenced last because it only pays off once the critic-improved plan is worth pinning.
References
- .github/workflows/initiative-planner.yml#L178-L186
- scripts/initiative-planner/apply-plan.sh#L30-L35
- scripts/initiative-planner/README.md
- docs/initiatives/idea-to-initiative-pipeline.md
Likely target surface
.github/workflows/initiative-planner.ymlscripts/initiative-planner/README.mddocs/initiatives/idea-to-initiative-pipeline.md
Story prepared by the BMAD Scrum Master (Bob) for epic #597. Status: ready-for-dev.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
dev-leadFor dev-lead agent pickupFor dev-lead agent pickupinitiativeEpic / initiative tracking issueEpic / initiative tracking issue
Activity
don-petry commentedon Jun 17, 2026
Dev-Lead Implementation Plan
Issue: #604 — [Phase 3] Plan/apply split: apply consumes the dry-run's authoritative plan.json
Scope
Add an apply-from-artifact path to the initiative-planner workflow so a maintainer can point the apply run at a prior dry-run's reviewed
plan.json(downloaded by run ID), skipping the LLM re-plan while still validating and applying the supplied artifact.Handoff mechanism (AC #2 decision)
New optional
plan_artifact_run_idworkflow_dispatchinput. When set, the workflow downloads theinitiative-plan-dry-runartifact (which already containsplan.json) from that run viagh run download, then applies it. Empty input ⇒ unchanged default (Bob plans then applies).Implementation Checklist
scripts/initiative-planner/apply-reviewed-plan.sh— thin orchestrator: verify suppliedPLAN_PATH, runvalidate-plan.py, thenapply-plan.sh(no re-plan).github/workflows/initiative-planner.yml— addplan_artifact_run_idinput +PLAN_ARTIFACT_RUN_IDenv; addactions: readfor artifact download; download step; gate the Bob LLM stepif PLAN_ARTIFACT_RUN_ID == ''; add reviewed-plan apply stepscripts/initiative-planner/README.md— document the plan → review → apply split + handoffdocs/initiatives/idea-to-initiative-pipeline.md— reflect the new review/apply gate in the diagram + proseTests to Write
apply-reviewed-plan.shvalidates then applies a supplied plan (DRY_RUN) — full DAG createdapply-reviewed-plan.shrejects an invalid supplied plan (cycle) before applying — zero mutationsapply-reviewed-plan.sherrors on a missing/empty supplied plan filetests/test_initiative_planner.bats, already in the lint.yml bats list)Test Command
scripts/run-bats.sh tests/test_initiative_planner.batsandbash .dev-lead/scripts/dev-lead-lint.shdon-petry commentedon Jun 17, 2026
Dev-Lead: Implementation Complete
Plan Execution
apply-reviewed-plan.sh— validates the supplied (possibly hand-edited) plan.json then runsapply-plan.sh, with no LLM re-planinitiative-planner.yml(newplan_artifact_run_idinput,actions: read, artifact download, gated Bob step, reviewed-plan apply step)plan_artifact_run_id⇒ unchanged)Handoff mechanism (AC #2)
Chosen: artifact-download-by-run-ID (
gh run download <run> --name initiative-plan-dry-run), not a committed plan file — keeps reviewed plans out of git and ties each apply to a specific, auditable dry-run. Documented in both docs.Test Results
Files Changed
scripts/initiative-planner/apply-reviewed-plan.sh(new): no-re-plan handoff — re-validate thenapply-plan.sh.github/workflows/initiative-planner.yml:plan_artifact_run_idinput,actions: read, download-reviewed-plan step,if-gate on the Bob step, apply-reviewed-plan stepscripts/initiative-planner/README.md: documents the split + handoff and the new script rowdocs/initiatives/idea-to-initiative-pipeline.md: diagram + prose reflect the plan-review gatetests/test_initiative_planner.bats: 4 new tests (already in the lint.yml bats list — no new file to register)Notes
PLAN_PATH) — confirmed unchanged; AC#2 — artifact-by-run-ID handoff; AC#3 — Bob stepif-gated off when a plan is supplied, whilevalidate-plan.py+apply-plan.shstill run viaapply-reviewed-plan.sh; AC#4 — empty input ⇒ unchanged; AC#5 — both docs updated.gather-context.shintentionally still runs on the apply path: it resolvesDISCUSSION_NODE_IDso apply-plan can post the summary back. It does not plan — the LLM step is the only thing skipped.initiative:auto; the blocking-open-questions and idempotency/supersede gates are honored byapply-plan.shregardless of path (covered by the new gate test).apply-reviewed-plan.shand covered.feat: implement issue #604 — [Phase 3] Plan/apply split: apply consum…
feat: implement issue #604 — [Phase 3] Plan/apply split: apply consum…
fix(ci): resolve all Tier-1 CI failures — duplicate headings, case ar…
feat: implement issue #604 — [Phase 3] Plan/apply split: apply consum…
feat: implement issue #604 — [Phase 3] Plan/apply split: apply consum…
feat: implement issue #604 — [Phase 3] Plan/apply split: apply consum…
feat: implement issue #604 — [Phase 3] Plan/apply split: apply consum…
feat: implement issue #604 — [Phase 3] Plan/apply split: apply consum…
feat: implement issue #604 — [Phase 3] Plan/apply split: apply consum…
feat: implement issue #604 — [Phase 3] Plan/apply split: apply consum…