Skip to content

feat(blast-radius): PR 4 — specialist consumption + flip default to on#5

Open
ni5h4nt wants to merge 8 commits into
feature/blast-radius-pr3-workflowfrom
feature/blast-radius-pr4-consumption
Open

feat(blast-radius): PR 4 — specialist consumption + flip default to on#5
ni5h4nt wants to merge 8 commits into
feature/blast-radius-pr3-workflowfrom
feature/blast-radius-pr4-consumption

Conversation

@ni5h4nt
Copy link
Copy Markdown
Owner

@ni5h4nt ni5h4nt commented May 5, 2026

Summary

PR 4 of the blast-radius initiative — the one that actually changes reviewer behavior. Three coordinated changes; the flag flip is the last commit so a regression revert is exactly one commit.

  1. Real base/head content via git_provider. New GitHostAdapter.get_file_content + GitHubAdapter impl + fetch_file_contents_activity (rename-aware: uses old_path for base SHA, path for head; skip-on-error rather than coercing exceptions to empty content).
  2. Specialists consume impact_context. coordinator.py and analyzer.py both render a ## Impact Context markdown section into their user prompts via the shared render_impact_context helper in a new neutral module app/services/review/impact_prompt.py. Every specialist's system prompt is augmented with a standing rule about confidence tiers (EXTRACTED/INFERRED = definitely impacted; AMBIGUOUS = possibly impacted, lower severity by one level if a finding depends on one). Done in the coordinator/analyzer, not per-specialist file.
  3. Default flag flipped to True. Last commit. Revert just fbcf61c-equivalent to disable the feature without touching prompt or git-provider code.

Stacked on PR 3 (PR #4 in this repo). GitHub will auto-retarget the base branch when PR 3 merges.

Spec: docs/superpowers/specs/2026-05-02-blast-radius-pre-filter-design.md
Plan: docs/superpowers/plans/2026-05-04-blast-radius-pr4-specialist-consumption.md (lives on the umbrella branch)

What lands (8 commits, 20 files, +955/-30)

  • app/services/git_provider.py + app/services/github_adapter.pyget_file_content(owner, repo, path, sha) -> Optional[str]. None for 404 / directory / non-file / decode failure.
  • app/services/review/impact_prompt.py (NEW, neutral helper module) — _STANDING_AMBIGUITY_RULE, public render_impact_context(impact), public augment_system_prompt(base). Exists specifically to break the coordinator <-> analyzer import cycle.
  • app/workflows/context_activities.pyfetch_file_contents_activity registered in REGISTERED_ACTIVITIES. Rename-aware. Skip-on-error (genuine 404 -> empty string; exception -> file dropped from output).
  • app/workflows/review_workflow.pyfetch_file_contents runs before extract_changed_symbols when the flag is on; threads old_path per file.
  • app/services/review/multi_agent_analyzer.pymulti_agent_analyze_file accepts impact_context; _build_context puts it under context["impact"] (legacy integer slot redefined for the symbol-level payload, documented inline).
  • app/services/review/coordinator.py_build_review_prompt renders the new section; Agent(...) constructed with augment_system_prompt(config["prompt"]).
  • app/services/analyzer.py — single-agent analyze_file accepts impact_context; new _build_user_prompt helper appends render_impact_context(...) when non-None; system prompt augmented identically to multi-agent. Lazy-imports the helpers to break the package-init cycle (documented inline).
  • app/workflows/activities.pyanalyze_file_activity forwards input.impact_context to BOTH paths.
  • app/core/config.pyblast_radius_enabled: bool = True (was False). Last commit.

Architecture decisions

  • Standing rule lives in impact_prompt.py, not per-specialist. Seven specialist subclass files would otherwise need identical edits; augment_system_prompt(base) does it in one place.
  • get_file_content returns Optional[str]None for genuine 404 (added/removed/directory), exception propagates for transient errors. The activity coerces None to "" so the chunker runs on added/removed files; exceptions trigger per-file skip rather than fabricating empty content.
  • context["impact"] slot redefined. Pre-PR-4 it carried an integer impact-radius from the legacy ImpactAnalyzer (no consumer reads it). PR 4 reuses the slot for the symbol-level BlastRadius payload.
  • Lazy imports in analyzer.py for the impact_prompt helpers. The neutral module itself has no review-package deps, but app/services/review/__init__.py eagerly imports from coordinator.py (which imports from analyzer.py), recreating the cycle on submodule import. Lazy imports fix it cleanly without a wider __init__.py refactor.

Test plan

  • get_file_content happy path + 404 + directory + empty-file
  • fetch_file_contents_activity returns the right per-file payloads + rename-aware base fetch + skip-on-error + worker-registration object-identity
  • Workflow: flag-off skips fetch_file_contents; flag-on runs fetch_file_contents < extract_changed_symbols < compute_blast_radius < analyze_file_activity
  • _build_context carries impact_context under "impact"
  • render_impact_context covers all sections + graph-unavailable case
  • Coordinator constructs Agent with system_prompt containing the standing AMBIGUOUS rule (end-to-end wiring)
  • Single-agent _build_user_prompt renders the same section
  • analyze_file_activity forwards impact_context to multi-agent path
  • Default flag is True; workflow blast-radius tests still pass
  • uv run ruff check clean across all 11 touched Python files
  • 50/50 targeted Python tests pass

Rollback plan

Revert just commit feat(blast-radius): flip blast_radius_enabled default to True. Everything else stays — workflow phase still runs, prompts still know how to render impact context, but every Settings() defaults to False again so the phase short-circuits.

ni5h4nt added 8 commits May 5, 2026 13:55
Phase 8/9 of blast-radius PR 4.

This is the behaviour-changing commit. Reverting just this commit
disables blast-radius prompts and the workflow phase entirely without
touching git_provider, prompt-rendering, or specialist code.
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