Skip to content

[Phase 2] Fetch consumer references + assemble the DOWNSTREAM_IMPACT context block #730

Description

@github-actions

Story

As a pr-review pipeline,
I want in review-one-pr.sh, compute impacted consumers for the PR's changed files, best-effort fetch the consumer files that reference each impacted surface via gh api, and assemble a size-capped DOWNSTREAM_IMPACT context block,
so that the (tool-less) triage tier and the deeper tiers receive ready-to-read downstream-impact context inline, without needing tools or risking a cascade failure.

Acceptance Criteria

  1. In scripts/review-one-pr.sh, after the PR metadata/diff are prefetched, the changed files are passed through downstream-impact.sh and, for each impacted surface, the dependent consumers' referencing files are fetched via gh api (best-effort).
  2. The fetched references are assembled into a single size-capped DOWNSTREAM_IMPACT text block (capped like ADVISORY_BOT_FEEDBACK is capped at 8 KB), written to a file for the deeper tiers to read.
  3. Every failure mode degrades to a benign (none) block and continues the review: manifest absent, mapping empty, gh api rate-limited, cross-repo read denied (missing token scope), or fetch error — none aborts the cascade.
  4. When the impacted set is empty (PR touches no shared surface), the block is (none) and NO cross-repo gh api calls are made (no wasted calls / rate budget).
  5. The pass is gated so that when the manifest is absent the behavior is byte-for-byte identical to today (no new gh calls, no prompt changes) — verified by a test asserting the block is (none) and no consumer fetch occurs.

Tasks / Subtasks

Dev Notes

  • Pattern to mirror EXACTLY: the ADVISORY_BOT_FEEDBACK assembly in scripts/review-one-pr.sh (around L465-L545). It best-effort fetches via gh api, degrades each failure to (none), caps total size at 8 KB (${VAR:0:8000}), writes the result to /tmp/cascade/advisory-bot-feedback.txt, and exports the file path for the deeper tiers. The triage tier has NO tools, so this inline-assembly approach is mandatory — the model cannot fetch cross-repo data itself.
  • Rate-limit discipline: reuse is_rate_limited (already used for the diff prefetch) so a 429/529 on a consumer fetch degrades gracefully and never aborts. The cascade must not hard-fail on this optional pass.
  • Cross-repo read access is a real prerequisite: the workflow token must be able to read consumer repos (some may be private). Build for graceful degradation when access is missing (treat a 403/404 like (none)); the token/PAT decision is an advisory open_question, not a blocker for this story — the feature ships degrading-by-default.
  • Do NOT touch the cycle-cap logic in review-cycle.sh (the discussion's reference to review-cycle.sh is mis-grounded; that file counts non-converging review cycles and is unrelated). The correct insertion point is the context-assembly section of review-one-pr.sh.
  • Keep the new locals out of the bulky-locals window: like the advisory block, drop heavy strings after writing the file to avoid E2BIG on later jq/claude forks.
  • Testing standard: bats in tests/, registered in .github/workflows/lint.yml.

Project Structure Notes

All changes are in scripts/review-one-pr.sh (context assembly) + sourcing the Story-2 lib. No change to the tier/engine routing in engine.sh. Output file convention matches ADVISORY_BOT_FEEDBACK_FILE.

References

  • scripts/review-one-pr.sh#L465-L560
  • scripts/engine.sh#is_rate_limited
  • scripts/lib/downstream-impact.sh

Likely target surface

  • scripts/review-one-pr.sh
  • tests/test_downstream_impact.bats
  • .github/workflows/lint.yml

Story prepared by the BMAD Scrum Master (Bob) for epic #727. Status: ready-for-dev.

Metadata

Metadata

Assignees

No one assigned

    Labels

    initiativeEpic / initiative tracking issue

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions