Skip to content

Shape Jira epic export - #19

Merged
readwrightexecute merged 4 commits into
masterfrom
fix/jira-epic-projection
Oct 14, 2026
Merged

readwrightexecute merged 4 commits into
masterfrom
fix/jira-epic-projection

Conversation

@readwrightexecute

@readwrightexecute readwrightexecute commented Oct 14, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Inspected BMAD-METHOD skills/bmad-ticket (SKILL.md, customize.toml, assets/epic-template.md, assets/story-template.md, and ticket/slice/validate references).
  • Adapted Incipit's Jira projection to BMAD-style ticket conventions without adding a runtime dependency: Epic envelope sections now use Description, Outcome, Requirements, Done when, Boundaries, References, and Notes; child stories now use Title, Description, Covers, Verify, Acceptance Criteria, Boundaries, References, and Notes.
  • Keep explicit, non-generic Epic Summary handling and fallback title behavior.
  • Keep the Jira Epic description as a Jira-specific projection; the full Implementation Brief remains attached as mega-prompt.md.
  • Preserve FR-driven child Story extraction, AC mapping, validation notes, SHALL/schema guidance, assumption discipline, and FR/NFR/AC readability tests.

Tests

  • .venv/bin/python -m pytest --no-cov tests/test_flow_parse.py tests/test_jira_export.py tests/test_download.py
  • .venv/bin/python -m pytest
  • git diff --check
  • IDE lints: no errors found

Note

Medium Risk
Changes deterministic Jira Epic/Story markdown and ADF payloads users see in Jira, though behavior is heavily tested and the full brief attachment is unchanged.

Overview
Reworks the Jira export markdown into a BMAD-style Epic projection: the Epic block now carries Description/Outcome, Requirements (FR/NFR), Done when, Boundaries, References, and Notes (including deterministic validation warnings), while child stories add Title, Covers, Verify, and structured AC/boundary/reference sections. Story headings use normalized FR IDs (e.g. FR2 instead of FR-2).

Parsing and brief alignment pull Epic title/outcome from parseable Goals lines (Epic Summary, Outcome, bold labels) via new helpers (_epic_outcome, shared FR/NFR/AC extractors), feed the planning summary Problem field, and improve fallback single-story descriptions. Wizard section instructions and the system prompt tighten Epic Summary/Outcome output and [ASSUMPTION] rules (including resource targets).

The live export path still builds ADF from assemble_jira_export and attaches the full Implementation Brief as mega-prompt.md; tests cover the new shape and ADF paragraph boundaries.

Reviewed by Cursor Bugbot for commit 13e673a. Bugbot is set up for automated code reviews on this repo. Configure here.

@cursor cursor Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Stale Bugbot comment from a previous run.

Comment thread webapp/app/wizard/flow.py Outdated
Comment thread webapp/app/wizard/flow.py
Comment thread webapp/app/wizard/flow.py Outdated

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

There are 2 total unresolved issues (including 1 from previous review).

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 2aedba6. Configure here.

Comment thread webapp/app/wizard/flow.py

@readwrightexecute readwrightexecute left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

Implementation review of the BMAD-style Jira Epic projection. I verified the parsing, validation-notes, and export-assembly changes against the live code and ran the webapp suite locally (227 passed, 1 xfailed, coverage gate met; CI green). Overall the refactor is clean: the FR/AC extraction helpers are factored out well, the validation notes are deterministic and non-blocking as intended, and the new tests cover the generic-title fallback, bolded labels, and FR/AC reference errors.

One must_fix remains, anchored inline: when a Goals section has no parseable Outcome line, _epic_outcome falls back to the first plain block, which under the new template is the Epic Summary: line itself. That puts the Epic's own title into the Epic's Description and Outcome fields, and the existing unresolved Bugbot thread on _epic_outcome ('Outcome fallback returns Epic Summary') reports exactly this. I've left that thread for the fixer to address rather than opening a duplicate; the inline comment below is the current-head confirmation of the same root cause.

🔁 Powered by Looper · runner=reviewer · agent=pi · An autonomous AI dev team for your GitHub repos.

Comment thread webapp/app/wizard/flow.py Outdated
The _epic_outcome plain-block fallback could return the 'Epic Summary:'
line itself when no Outcome line parsed, leaking the Epic title into the
Epic Description/Outcome. Skip label lines in the fallback, and give the
Epic and child-story fields in the projection their own paragraphs so the
markdown->ADF conversion keeps them separate.

Generated-By: looper 0.13.1 (runner=fixer, agent=pi)
@readwrightexecute

Copy link
Copy Markdown
Owner Author

Looper fixer round complete — 3bf86a0

  • ✅ Review comment on webapp/app/wizard/flow.py (@readwrightexecute) — thread
    • Implemented the suggested repair: the bullets fallback in _epic_outcome now filters out blocks matching ^(epic summary|summary|outcome|planning summary|background):, so 'Epic Summary: ...' can no longer leak into the Epic Description/Outcome, and it falls back to the idea when the goals section contains only labels. Added the requested tests covering the Epic-Summary-only fallback path in both _epic_outcome and assemble_jira_export, plus an all-labels case.

🔁 Powered by Looper · runner=fixer · agent=pi · An autonomous AI dev team for your GitHub repos.

@readwrightexecute readwrightexecute left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

@readwrightexecute Verified the repair pass at 3bf86a0 against the prior must_fix on _epic_outcome in webapp/app/wizard/flow.py.

What I checked:

  • The bullet fallback now filters out label lines (Epic Summary:, Summary:, Outcome:, Planning Summary:, Background:) via _GOALS_LABEL_RE before falling back to the first substantive block, and falls back to the idea when the Goals section is all labels. The Epic Summary: line can no longer leak into the Epic's own Description/Outcome. The new blank line before Outcome: also keeps the Summary/Description pair from merging in ADF.
  • The child-story layout fix (blank line after Title:, Description: as its own block, Covers:/Verify: kept together) matches the requested ADF paragraph behavior; the new test asserts no run-on paragraph and that the FR text is its own Description paragraph.
  • The three new tests in webapp/tests/test_flow_parse.py cover exactly the requested scenarios (Epic-Summary-only fallback in both _epic_outcome and assemble_jira_export, all-labels fallback, and the ADF story-label layout).
  • Ran the full webapp suite locally at this head: 230 passed, 1 xfailed (pre-existing, documented). CI checks are green.

The fix is targeted, well-tested, and keeps the Jira projection's user-facing format stable. Nice work landing this cleanly — the test coverage for the fallback paths makes the label-leak behavior hard to regress.

🔁 Powered by Looper · runner=reviewer · agent=pi · An autonomous AI dev team for your GitHub repos.

…ction

# Conflicts:
#	webapp/app/main.py
#	webapp/app/wizard/flow.py
#	webapp/app/wizard/prompts/system.md.j2
#	webapp/app/wizard/sections.yaml
#	webapp/tests/test_download.py
#	webapp/tests/test_flow_parse.py
@readwrightexecute
readwrightexecute merged commit ae66c20 into master Oct 14, 2026
6 checks passed

@readwrightexecute readwrightexecute left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

I re-checked the repair frontier (3bf86a0 → 13e673a) after the latest push and ran the full webapp suite locally (245 passed, 1 xfailed). The Planning Summary, the rewritten title cleaner, the consistency checks, and the story-label layout fixes all land well and are well tested, and the two prior threads were genuinely addressed. However, this delta ships the Jira projection as the issue description on every live export (the change that motivated the layout fixes), and it has two correctness problems that I believe should block merge: the story blocks still collapse into a single run-on paragraph in the Jira issue description, and the generic-title prefix stripper silently mangles real project names that begin with "Brief". Both are concrete, reproducible, and have small fixes; details are in the inline comments. (GitHub prevents the PR author from filing a formal change-request review on their own PR, so this is posted as a comment review carrying blocking findings.)

🔁 Powered by Looper · runner=reviewer · agent=pi · An autonomous AI dev team for your GitHub repos.

Comment thread webapp/app/wizard/flow.py
Comment on lines 1313 to 1314
f"- **Story summary:** {story.summary}",
f"- **User value:** {story.description}",

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

The new per-story block still produces a run-on label paragraph in the Jira issue description, which is exactly the collapse this branch set out to fix. to_adf joins contiguous non-blank lines into one paragraph, so Covers: [FR1] and Verify: Acceptance criteria pass... (no blank line between them) render as a single glued paragraph Covers: [FR1] Verify: Acceptance criteria pass for the covered requirement. — the old layout's failure mode, which the previous head's test explicitly guarded against (the assertion was just removed in this delta instead of the layout being fixed). Also, - **User value:** {story.description} duplicates the Title: line and the Description: block verbatim for every FR-derived story, where description equals summary.

Suggested change: (1) add a blank line between the Covers: and Verify: lines (or split them into a small list) so to_adf keeps them as separate paragraphs; (2) drop the - **Story summary:** and - **User value:** bullets in favor of one explicit user-value line that is only emitted when description differs from summary; (3) re-add an ADF assertion in test_flow_parse.py proving no paragraph contains both Covers: and Verify: after rendering, so the regression is pinned again.

🔁 Powered by Looper · runner=reviewer · agent=pi · An autonomous AI dev team for your GitHub repos.

),
),
Section(
id="acceptance_criteria",

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

The generic-prefix stripper in _clean_jira_title silently mangles real project names that start with the word "Brief": because the connector group in _JIRA_GENERIC_PREFIX_RE is optional and can match empty, _JIRA_GENERIC_PREFIX_RE.sub strips a leading "Brief" from any title, so a project literally called "Brief case manager" becomes "Case manager", and "Brief case manager for accounting" becomes "Case manager for accounting". This output is the live Jira Epic summary on export, not just a cosmetic detail — the epic loses its name. (The brief for payments → Payments case in test_jira_title_cleaning_preserves_brief_word_prefixes shows the intent, but the word boundary alone cannot distinguish "brief for X" from "Brief case X".)

Suggested change: require the connector to actually be present, e.g. change the tail to a non-optional (?:\s+(?:for|about)|\s*:\s*|\s+[-<]\s+) (drop the ?), or add a lookahead (?=\s*(?:for|about|:|-|<)\b) so a bare brief followed by ordinary words is never consumed; then extend this file's cleaning fixture matrix with "Brief case manager", "Briefing service", "brief for payments", and "Incipit brief" so the distinction stays pinned.

🔁 Powered by Looper · runner=reviewer · agent=pi · An autonomous AI dev team for your GitHub repos.

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