Skip to content

feat(brainstormer): axis-aligned epic/ticket generator (#123)#136

Merged
hadamrd merged 1 commit into
trunkfrom
loop/123-iter
May 28, 2026
Merged

feat(brainstormer): axis-aligned epic/ticket generator (#123)#136
hadamrd merged 1 commit into
trunkfrom
loop/123-iter

Conversation

@hadamrd
Copy link
Copy Markdown
Owner

@hadamrd hadamrd commented May 28, 2026

Summary

  • New Brainstormer module: reads ProductVision, scans open backlog via gh_client, drives an SDK session, returns a filtered BrainstormReport.
  • Anti-cosmetic guardrail runs post-SDK: drops items with missing axis/story, unknown axes, or titles/bodies that substring-match rejected_as_cosmetic (case-insensitive). Drops are logged at INFO.
  • New _brainstormer_sdk.py (mirrors _critic_sdk.py) + brief template brainstormer.md.tmpl (vision verbatim + axes yaml + open backlog + rubric).
  • New list_open_backlog helper in gh_client.py — no shell-outs from brainstormer.py.

Closes #123. Part of #121.

Test plan

  • pytest tests/test_brainstormer.py — 18 passing
    • happy path (2 epics + 3 tickets all survive)
    • cosmetic filter (title match → dropped, drop reason recorded)
    • cosmetic match in body (adversarial)
    • case-insensitive cosmetic match
    • missing-citation filter (empty axis / empty story)
    • unknown-axis filter
    • empty / None vision → ValueError
    • SDK timeout → RuntimeError
    • SDK generic error → RuntimeError
    • malformed JSON → RuntimeError carrying raw last_message
    • JSON with trailing prose still parsed
    • integration: rendered prompt contains vision text + axes + rubric + backlog placeholder
    • backlog helper partitions epics from tickets

🤖 Generated with Claude Code

…etic guardrail (#123)

Introduces the `Brainstormer` SDK session that reads a ProductVision
(from #122), scans the open backlog via `gh_client`, and proposes
epics + tickets that must cite an axis + customer story. The post-SDK
guardrail drops anything missing citations, citing an unknown axis,
or substring-matching an axis's `rejected_as_cosmetic` list — defense
in depth against the loop drifting into cosmetic work.

- src/forge_loop/brainstormer.py — `Brainstormer.run(vision)`,
  `BrainstormReport`, `ProposedEpic`, `ProposedTicket`.
- src/forge_loop/_brainstormer_sdk.py — sync SDK shim mirroring
  `_critic_sdk.py` shape.
- src/forge_loop/briefs/brainstormer.md.tmpl — primes the session
  with vision (verbatim), axes (yaml-rendered), open backlog, and the
  hard-refusal rubric.
- src/forge_loop/gh_client.py — adds `list_open_backlog` +
  `OpenBacklog` so callers don't shell to `gh`.
- tests/test_brainstormer.py — happy path, every filter (missing
  axis, missing story, unknown axis, cosmetic title/body match,
  case-insensitive), empty-vision guardrail, SDK timeout + error +
  malformed-output handling, integration with fixtures, prompt-
  contents assertion.

Part of #121.
@hadamrd hadamrd merged commit befb911 into trunk May 28, 2026
@hadamrd hadamrd deleted the loop/123-iter branch May 28, 2026 18:10
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.

feat(brainstormer): Brainstormer skill module — reads vision, scans backlog, proposes axis-aligned epics+tickets

1 participant