Story
As a maintainer reviewing a freshly planned initiative,
I want open-questions to carry the stories they affect, and have apply-plan withhold ready-for-dev from those stories while flagging the epic,
so that contested decisions block release to dev-lead until a maintainer resolves them, instead of flowing through baked into acceptance criteria.
Acceptance Criteria
- plan.schema.json changes
open_questions items from bare strings to objects with a required question string and an affected_story_ids array of local story ids.
- validate-plan.py rejects an open_question whose
affected_story_ids references a story id not present in the plan (mirroring the existing dangling-edge check), and the bats fixture is updated to the new object shape so existing tests pass.
- apply-plan.sh labels each affected story
planning:needs-input and does NOT stamp it ready-for-dev (the per-story status line at apply-plan.sh:80 becomes conditional); stories not referenced by any open-question are unchanged.
- apply-plan.sh labels the epic with a gate label (e.g.
initiative:needs-input) so a maintainer sees resolution is required before initiative:auto, and the discussion summary lists each open question with its affected story numbers.
- New bats cases prove: an affected story carries
planning:needs-input and omits ready-for-dev; an unaffected story is unchanged; the epic carries the gate label.
Tasks / Subtasks
Dev Notes
- Today open_questions is
string[] (plan.schema.json) rendered as a flat list in the discussion comment at apply-plan.sh:122; the bats fixture at tests/test_initiative_planner.bats:35 uses the string form — update it to the object form or downstream tests break.
- Story status is a hard-coded line
Status: ready-for-dev appended at apply-plan.sh:80, and a test asserts it at tests/test_initiative_planner.bats:130 — make it conditional and update that assertion.
- Reuse the id-existence loop in validate-plan.py:62-70 (the blocked_by dangling-edge check) for affected_story_ids.
- The labels
planning:needs-input and initiative:needs-input likely do NOT exist in the repo yet — see open_questions. create_issue posts to repos/{repo}/issues with a labels array (lib/mutations.sh:62-67); the labels must exist in the repo label set first.
- hands_off stories already withhold auto-release via
initiative:hold (apply-plan.sh:82-85); this is the ANALOGOUS gate for unresolved questions — keep the two mechanisms distinct.
Project Structure Notes
Touches the schema/validator/apply trio together; this is the schema-shape change so the fixture in tests must move in lockstep. New labels are repo configuration, not code.
References
- scripts/initiative-planner/plan.schema.json
- scripts/initiative-planner/validate-plan.py#L62-L70
- scripts/initiative-planner/apply-plan.sh#L80-L125
- tests/test_initiative_planner.bats#L35-L130
Likely target surface
scripts/initiative-planner/plan.schema.json
scripts/initiative-planner/validate-plan.py
scripts/initiative-planner/apply-plan.sh
tests/test_initiative_planner.bats
Story prepared by the BMAD Scrum Master (Bob) for epic #597. Status: ready-for-dev.
Story
As a maintainer reviewing a freshly planned initiative,
I want open-questions to carry the stories they affect, and have apply-plan withhold
ready-for-devfrom those stories while flagging the epic,so that contested decisions block release to dev-lead until a maintainer resolves them, instead of flowing through baked into acceptance criteria.
Acceptance Criteria
open_questionsitems from bare strings to objects with a requiredquestionstring and anaffected_story_idsarray of local story ids.affected_story_idsreferences a story id not present in the plan (mirroring the existing dangling-edge check), and the bats fixture is updated to the new object shape so existing tests pass.planning:needs-inputand does NOT stamp itready-for-dev(the per-story status line at apply-plan.sh:80 becomes conditional); stories not referenced by any open-question are unchanged.initiative:needs-input) so a maintainer sees resolution is required beforeinitiative:auto, and the discussion summary lists each open question with its affected story numbers.planning:needs-inputand omitsready-for-dev; an unaffected story is unchanged; the epic carries the gate label.Tasks / Subtasks
{question, affected_story_ids}objects. (AC: test issue from agent #1)planning:needs-inputstory label and theinitiative:needs-inputepic label. (AC: Add @claude delegation, auto-merge, and rebase handling #3, Optimize review: small-PR and incremental fast paths #4)Dev Notes
string[](plan.schema.json) rendered as a flat list in the discussion comment at apply-plan.sh:122; the bats fixture at tests/test_initiative_planner.bats:35 uses the string form — update it to the object form or downstream tests break.Status: ready-for-devappended at apply-plan.sh:80, and a test asserts it at tests/test_initiative_planner.bats:130 — make it conditional and update that assertion.planning:needs-inputandinitiative:needs-inputlikely do NOT exist in the repo yet — see open_questions. create_issue posts torepos/{repo}/issueswith a labels array (lib/mutations.sh:62-67); the labels must exist in the repo label set first.initiative:hold(apply-plan.sh:82-85); this is the ANALOGOUS gate for unresolved questions — keep the two mechanisms distinct.Project Structure Notes
Touches the schema/validator/apply trio together; this is the schema-shape change so the fixture in tests must move in lockstep. New labels are repo configuration, not code.
References
Likely target surface
scripts/initiative-planner/plan.schema.jsonscripts/initiative-planner/validate-plan.pyscripts/initiative-planner/apply-plan.shtests/test_initiative_planner.batsStory prepared by the BMAD Scrum Master (Bob) for epic #597. Status: ready-for-dev.