Skip to content

feat(plan-feature): add Epic creation and grouping strategies#222

Merged
mrizzi merged 1 commit into
mainfrom
TC-4869
Jul 1, 2026
Merged

feat(plan-feature): add Epic creation and grouping strategies#222
mrizzi merged 1 commit into
mainfrom
TC-4869

Conversation

@mrizzi

@mrizzi mrizzi commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Extends plan-feature Steps 5 and 6 to generate and create Epic issues between Features and Tasks when a level-1 issue type is available
  • Supports three Epic grouping strategies: by-repository, by-sub-feature, and trivial — configurable via interactive prompt or CLAUDE.md Hierarchy Configuration
  • Gracefully falls back to existing Feature → Task hierarchy when no Epic-level type exists
  • Adds three new constraints (1.79–1.81) to docs/constraints.md
  • Adds eval scenario (id 6) with multi-repo fixture for by-repository Epic grouping

Implements TC-4869

Test plan

  • Verify Epic grouping strategy prompt is present in Step 5
  • Verify Epic creation sub-step 6a.0 is correctly placed before 6a in Step 6
  • Verify hierarchy linking: Feature → Epic (parent + Incorporates) → Task (parent)
  • Verify graceful fallback preserves current Feature → Task behavior
  • Verify eval fixture has SYNTHETIC TEST DATA header
  • Run eval scenario 6 against plan-feature skill

🤖 Generated with Claude Code

Summary by Sourcery

Introduce configurable Epic-level hierarchy between Features and Tasks in the plan-feature workflow, with backward-compatible behavior when Epics are unavailable.

New Features:

  • Add Epic grouping step to plan-feature Step 5 with strategies by repository, by sub-feature, or trivial, configurable via CLAUDE.md or interactive prompt.
  • Add Epic creation sub-step 6a.0 in the plan-feature workflow to create Epic issues between Feature and Task levels when a level-1 issue type exists.

Enhancements:

  • Update task creation in Step 6 to assign tasks to Epics as parents when available while preserving existing behavior when Epics are absent.
  • Adjust issue link creation so Features incorporate Epics when present, or Tasks when Epics are unavailable, maintaining hierarchy semantics.
  • Extend constraints documentation to cover Epic creation, fallback hierarchy behavior, and configurable Epic grouping strategies.
  • Add an eval fixture describing a feature-epic hierarchy scenario for validating the new plan-feature behavior.

Documentation:

  • Document Epic grouping behavior, strategies, and graceful degradation in the plan-feature SKILL.md and constraints.md.

Tests:

  • Add synthetic eval scenario and fixture to exercise multi-repository Epic grouping and feature-epic-task hierarchy for the plan-feature skill.

Extend plan-feature Steps 5 and 6 to support Epic hierarchy between
Features and Tasks. When a level-1 issue type (Epic) is discovered
in Step 2.5, the skill groups tasks into Epics using one of three
strategies: by-repository, by-sub-feature, or trivial. Epics are
created with parent set to the Feature, and tasks are parented to
their assigned Epic. Incorporates links go from Feature to Epics.

When no level-1 type exists, the skill falls back to the existing
Feature → Task hierarchy unchanged (graceful degradation).

Adds three new constraints (1.79-1.81) and a new eval scenario
(id 6) with a multi-repo fixture to exercise by-repository grouping.

Implements TC-4869

Assisted-by: Claude Code
@sourcery-ai

sourcery-ai Bot commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Adds Epic-level hierarchy support to the plan-feature skill, including configurable grouping strategies, Epic creation in Jira, hierarchy-aware parent/link behavior, and corresponding constraints/eval fixtures while preserving backward-compatible Feature → Task behavior.

Sequence diagram for Epic-aware Jira issue creation in plan-feature

sequenceDiagram
  actor User
  participant plan_feature_skill
  participant Jira

  User->>plan_feature_skill: run plan-feature (Step 0–6)
  plan_feature_skill->>plan_feature_skill: Step_2_5_discover_level_1_type

  alt level_1_type_found
    plan_feature_skill->>plan_feature_skill: Step_5_determine_epic_grouping_strategy
    plan_feature_skill->>plan_feature_skill: Step_5_assign_tasks_to_epic_groups

    loop for_each_epic_group
      plan_feature_skill->>Jira: jira.create_issue(projectKey, issueTypeName, summary, description, parent, additional_fields)
      Jira-->>plan_feature_skill: epic_key
      plan_feature_skill->>plan_feature_skill: record_epic_group_mapping
    end

    loop for_each_task
      plan_feature_skill->>Jira: jira.create_issue(projectKey, taskIssueTypeName, summary, description, parent=epic_key, additional_fields)
      Jira-->>plan_feature_skill: task_key
    end

    loop for_each_epic
      plan_feature_skill->>Jira: jira.create_issue_link(link_type="Incorporates", inward_issue_key=feature_key, outward_issue_key=epic_key)
    end
  else no_level_1_type
    plan_feature_skill->>plan_feature_skill: set_no_epic_flag

    loop for_each_task
      plan_feature_skill->>Jira: jira.create_issue(projectKey, taskIssueTypeName, summary, description, parent=feature_or_none, additional_fields)
      Jira-->>plan_feature_skill: task_key
    end

    loop for_each_task
      plan_feature_skill->>Jira: jira.create_issue_link(link_type="Incorporates", inward_issue_key=feature_key, outward_issue_key=task_key)
    end
  end
Loading

Entity relationship diagram for Feature–Epic–Task Jira hierarchy

erDiagram
  FEATURE {
    string feature_key
    string summary
  }

  EPIC {
    string epic_key
    string summary
    string parent_feature_key
  }

  TASK {
    string task_key
    string summary
    string parent_key
  }

  FEATURE ||--o{ EPIC : has_epics_when_level_1_type
  EPIC ||--o{ TASK : epic_parent_of_tasks
  FEATURE ||--o{ TASK : direct_parent_when_no_epic

  FEATURE ||--o{ FEATURE : incorporates_epic_or_task
Loading

File-Level Changes

Change Details Files
Introduce Epic grouping and description generation in the plan-feature planning workflow when a level-1 issue type exists.
  • Add Step 5 guidance for detecting Epic availability based on Step 2.5 and conditionally enabling Epic grouping.
  • Define three Epic grouping strategies (by-repository, by-sub-feature, trivial) and how each groups tasks.
  • Add logic to choose grouping strategy via CLAUDE.md Hierarchy Configuration or an interactive prompt.
  • Specify how to generate Epic summaries and plain-text descriptions per group.
  • Describe rules for assigning tasks to Epic groups based on repository, sub-feature approval, or trivial single-Epic mode.
plugins/sdlc-workflow/skills/plan-feature/SKILL.md
Add Jira Epic creation sub-step before task creation, with hierarchy-aware parent handling and graceful degradation when Epics are unavailable.
  • Introduce Step 6a.0 instructions to create Epic issues in Jira before tasks, including field inheritance and labels.
  • Define mapping from Epic group labels to created Epic keys for later parent assignment.
  • Specify Epic-aware parent behavior for task creation, setting tasks’ parent to Epic key when available and falling back to Feature or none otherwise.
  • Document graceful degradation behavior when no level-1 type exists, including skipping Epic creation and retaining Feature → Task links.
plugins/sdlc-workflow/skills/plan-feature/SKILL.md
Update link-creation behavior to use Feature→Epic “Incorporates” links when Epics exist and preserve existing Feature→Task links otherwise.
  • Modify Step 6b link creation instructions to consider both tasks and Epics.
  • Define conditional logic for creating “Incorporates” links from Feature to Epics in Epic-enabled projects.
  • Retain previous behavior of “Incorporates” links from Feature to Tasks when Epics are not available, ensuring backward compatibility.
plugins/sdlc-workflow/skills/plan-feature/SKILL.md
Add new constraints documenting Epic creation, fallback behavior, and configurable grouping strategy, and update constraint source references.
  • Introduce constraints 1.79–1.81 describing Epic creation requirements, fallback hierarchy behavior, and configuration mechanisms.
  • Update the plan-feature SKILL.md entry in the constraints source table to reference new Epic-related sections and constraints.
docs/constraints.md
Add synthetic eval fixture describing a feature with Jira metadata to exercise the Feature→Epic hierarchy behavior.
  • Create a new synthetic test data file with a mock Jira Feature issue including metadata like key, summary, priority, fix versions, and requirements.
  • Ensure the fixture is clearly labeled as synthetic test data for eval purposes.
evals/plan-feature/files/feature-epic-hierarchy.md

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • The by-sub-feature Epic grouping flow is currently a bit underspecified—consider adding concrete guidance on how sub-feature group labels are derived and presented to the user to keep behavior consistent across runs.
  • In the Epic-aware parent field and graceful degradation sections, it may help to explicitly spell out how the no-Epic flag from Step 2.5 is surfaced and consumed (variable name / state handling) to avoid ambiguity for implementers wiring the logic.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The by-sub-feature Epic grouping flow is currently a bit underspecified—consider adding concrete guidance on how sub-feature group labels are derived and presented to the user to keep behavior consistent across runs.
- In the Epic-aware parent field and graceful degradation sections, it may help to explicitly spell out how the `no-Epic` flag from Step 2.5 is surfaced and consumed (variable name / state handling) to avoid ambiguity for implementers wiring the logic.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eval Results

Eval Results: plan-feature

Eval Passed Failed Pass Rate
eval-1 16/16 0 100%
eval-2 14/14 0 100%
eval-3 15/15 0 100%
eval-4 7/11 4 64%
eval-5 11/15 4 73%
eval-6 14/14 0 100%

Failed Assertions

eval-4: 4 failing assertions
  • Assertion: "After each task is created, a description digest comment is posted with a format-tagged SHA-256 hash — exactly 64 lowercase hex characters prefixed by 'sha256-md:' or 'sha256-adf:', not a placeholder, abbreviated value, or example string. Marker format: '[sdlc-workflow] Description digest: sha256-md:<64-char-hex>' (or sha256-adf). The digest is computed by re-fetching the description from the API and running scripts/sha256-digest.py"
    Evidence: "Each task file contains a digest line at the bottom (e.g., task-1 line 44: 'Description digest: sha256-md:23ca784d1b3b08815985bfe2505561e22412caee786d324b73fc76f607d6dcdf'). While all four digests have the sha256-md: prefix followed by exactly 64 lowercase hex characters, the marker format does NOT match the required '[sdlc-workflow] Description digest: sha256-md:<hash>' pattern — the '[sdlc-workflow]' prefix is missing from all four. The assertion specifies the marker format must include this prefix."

  • Assertion: "Convention-aware enrichment validates file-type applicability per shared/convention-applicability-rules.md before including a convention — inapplicable conventions are excluded entirely (not listed with 'Not applicable' annotations), and applicable ones include a rationale in the prescribed format ('Applies: task modifies <file> matching the convention's <scope>'), not free-form prose"
    Evidence: "No task description contains any reference to CONVENTIONS.md, 'Per CONVENTIONS', or 'Applies:' rationale lines. The convention-applicability-rules.md prescribes that applicable conventions include 'Applies: task modifies <file> matching the convention's <scope>' in Implementation Notes. None of the four task files contain any such rationale. While this could mean no conventions were applicable (if no CONVENTIONS.md exists for the target repo), the assertion requires that convention-aware enrichment was performed — there is no evidence of any convention applicability check having been done."

  • Assertion: "When the Feature issue has a priority set (not 'Undefined'), every created task's additional_fields includes 'priority' with the inherited priority name. When the Feature's priority is 'Undefined', the priority key is omitted entirely from additional_fields (not set to null or 'Undefined')"
    Evidence: "The Feature TC-9004 has Priority: Major (not 'Undefined'). The impact-map.md states 'Priority: Major (propagated from TC-9004)' and summary-comment.md states 'Priority: Major — inherited from TC-9004 and propagated to all created tasks'. However, none of the four task description files contain any mention of 'priority', 'Major', or 'additional_fields'. There is no concrete evidence in the output files that the Jira API calls to create tasks actually included priority in additional_fields — only the plan documents state the intention to propagate."

  • Assertion: "When the Feature issue has a non-empty fixVersions array and the fixVersion scope config (from ### Jira Field Defaults in CLAUDE.md) is 'task' or 'both' (or absent, defaulting to 'both'), every created task's additional_fields includes 'fixVersions' with the inherited version(s). When fixVersion scope is 'feature' or the Feature has no fixVersions, the fixVersions key is omitted entirely from additional_fields"
    Evidence: "The Feature TC-9004 has Fix Versions: RHTPA 1.5.0. CLAUDE.md has no '### Jira Field Defaults' section, so fixVersion scope defaults to 'both', meaning fixVersions should propagate to tasks. The impact-map.md states 'Fix Versions: RHTPA 1.5.0 (propagated from TC-9004)' and summary-comment.md states 'Fix Versions: RHTPA 1.5.0 — inherited from TC-9004 and propagated to all created tasks'. However, none of the four task description files contain any mention of 'fixVersions', 'RHTPA', or 'additional_fields'. There is no concrete evidence in the output files that the Jira API calls actually included fixVersions in additional_fields."

eval-5: 4 failing assertions
  • Assertion: "Each task file contains all required template sections: Repository, Target Branch, Description, at least one of Files to Modify or Files to Create, Implementation Notes, Acceptance Criteria, Test Requirements"
    Evidence: "Bookend tasks (task-1-create-feature-branch.md and task-8-merge-feature-branch.md) are missing 'Files to Modify', 'Files to Create', and 'Implementation Notes' sections. Task 1 has sections: Repository, Target Branch, Bookend Type, Description, Acceptance Criteria, Test Requirements, Dependencies. Task 8 has sections: Repository, Target Branch, Bookend Type, Description, Acceptance Criteria, Test Requirements, Dependencies. Non-bookend tasks (2-7) all contain the required sections."

  • Assertion: "Convention-aware enrichment validates file-type applicability per shared/convention-applicability-rules.md before including a convention — inapplicable conventions are excluded entirely (not listed with 'Not applicable' annotations), and applicable ones include a rationale in the prescribed format ('Applies: task modifies <file> matching the convention's <scope>'), not free-form prose"
    Evidence: "No convention-related enrichment with prescribed 'Applies:' rationale format is present in any task file. The task files reference 'Per docs/constraints.md' rules (e.g., task-2 lines 28-31, task-3 lines 23-24) but these are constraint references, not convention enrichment. There is no 'Per CONVENTIONS.md' reference with 'Applies: task modifies <file> matching the convention's <scope>' format anywhere in the outputs. The CONVENTIONS.md in this repo (sdlc-plugins) contains conventions like 'Commit Messages' that are broadly applicable and should have been included with the prescribed 'Applies: convention has no file-type restriction (broadly applicable)' rationale, but no such rationale appears."

  • Assertion: "When the Feature issue has a priority set (not 'Undefined'), every created task's additional_fields includes 'priority' with the inherited priority name. When the Feature's priority is 'Undefined', the priority key is omitted entirely from additional_fields (not set to null or 'Undefined')"
    Evidence: "The feature issue has Priority: High (not Undefined), so every created task should include priority in additional_fields. The summary-comment.md states 'Priority: High — inherited from Feature TC-9005 and propagated to all created tasks' and the impact-map.md states 'Priority: High (inherited from Feature TC-9005, propagated to all tasks)'. However, none of the 8 individual task files (task-1 through task-8) contain any 'additional_fields' section, 'priority' field, or mention of 'High' priority. The priority propagation is only documented in the summary and impact map, not in the actual task descriptions themselves."

  • Assertion: "When the Feature issue has a non-empty fixVersions array and the fixVersion scope config (from ### Jira Field Defaults in CLAUDE.md) is 'task' or 'both' (or absent, defaulting to 'both'), every created task's additional_fields includes 'fixVersions' with the inherited version(s). When fixVersion scope is 'feature' or the Feature has no fixVersions, the fixVersions key is omitted entirely from additional_fields"
    Evidence: "The feature issue has Fix Versions: RHTPA 2.0.0 (non-empty) and there is no fixVersion scope config in CLAUDE.md (defaults to 'both'), so every created task should include fixVersions in additional_fields. The summary-comment.md and impact-map.md both mention fixVersions propagation. However, none of the 8 individual task files contain any 'additional_fields' section or 'fixVersions' field. The fixVersions propagation is only documented in the summary and impact map, not in the actual task descriptions."

Pass rate: 89% · Tokens: 69,716 · Duration: 281s

Baseline (b22bcfd2): 76% · 47,235 tokens · 217s


Generated by sdlc-workflow/run-evals v0.11.1

@mrizzi

mrizzi commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator Author

[sdlc-workflow/verify-pr] Re: @sourcery-ai[bot] review — Two items classified:

  1. "consider adding concrete guidance on how sub-feature group labels are derived" — Classified as suggestion — this requests increased documentation specificity; CONVENTIONS.md does not mandate detail levels for skill step descriptions, and no codebase pattern demonstrates a minimum specificity convention. No sub-task created.

  2. "it may help to explicitly spell out how the no-Epic flag from Step 2.5 is surfaced and consumed" — Classified as suggestion — this proposes naming the flag explicitly; the current text references "Step 2.5 set the no-Epic flag" contextually, which is sufficient for implementer understanding. No sub-task created.

@mrizzi

mrizzi commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator Author

Verification Report for TC-4869 (commit 11919ac)

Check Result Details
Review Feedback PASS 2 suggestions from sourcery-ai[bot]; no code change requests
Root-Cause Investigation N/A No sub-tasks created
Scope Containment PASS PR files exactly match task specification (4/4)
Diff Size PASS ~172 additions / ~11 deletions proportionate to scope
Commit Traceability PASS Commit 11919ac references TC-4869
Sensitive Patterns PASS No secrets or credentials in added lines
CI Status PASS All 4 checks pass
Acceptance Criteria PASS 9 of 9 criteria met
Test Quality PASS Eval Quality: PASS (89% pass rate, 77/85; all 8 failures pre-existing at baseline 76%; eval-6 new, 14/14 100%)
Test Change Classification ADDITIVE New eval-6 added with 14 assertions; no existing evals modified
Verification Commands N/A No verification commands specified

Overall: PASS

All checks pass. The PR correctly extends plan-feature Steps 5 and 6 with Epic grouping strategies and creation logic, adds graceful degradation for projects without Epics, introduces 3 new constraints (1.79–1.81), and adds eval scenario 6 with 14 assertions — all passing at 100%. The overall eval pass rate improved from 76% baseline to 89%.


This comment was AI-generated by sdlc-workflow/verify-pr v0.11.1.

@mrizzi mrizzi merged commit d573976 into main Jul 1, 2026
4 checks passed
@mrizzi mrizzi deleted the TC-4869 branch July 1, 2026 16:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant