Skip to content

Implementation Plan: Local Review Rounds Before PR Creation (Reduce GitHub API Usage)#1970

Merged
Trecek merged 11 commits into
developfrom
local-review-rounds-before-pr-creation-reduce-github-api-usa/1945
May 6, 2026
Merged

Implementation Plan: Local Review Rounds Before PR Creation (Reduce GitHub API Usage)#1970
Trecek merged 11 commits into
developfrom
local-review-rounds-before-pr-creation-reduce-github-api-usa/1945

Conversation

@Trecek
Copy link
Copy Markdown
Collaborator

@Trecek Trecek commented May 6, 2026

Summary

Add a local_review_rounds configuration and plumbing so that the existing review loop steps (annotate_pr_diff, review_pr, resolve_review, check_review_loop) receive a review_mode context value ("local" or "github") computed per-iteration. Part A covers the config dataclass, defaults, ingredient bridge, callable modification, recipe YAML wiring for all three looping recipes, and tests for all of the above. Part B will cover the skill SKILL.md behavioral changes (how review-pr and resolve-review branch on mode=local vs mode=github) — implement as a separate task.

Closes #1945

Implementation Plan

Plan file: /home/talon/projects/autoskillit-runs/impl-20260505-165914-350121/.autoskillit/temp/make-plan/local_review_rounds_plan_2026-05-05_170500_part_a.md

🤖 Generated with Claude Code via AutoSkillit

Token Usage Summary

Step count uncached output cache_read peak_ctx turns cache_write time
plan 1 1.1k 16.4k 870.0k 87.5k 115 75.3k 9m 0s
verify 2 2.3k 23.7k 2.4M 72.1k 164 101.2k 12m 36s
implement 2 17.0M 76.6k 6.3M 99.7k 597 331.0k 1h 2m
prepare_pr 1 52 5.8k 161.3k 41.6k 17 29.6k 1m 30s
compose_pr 1 51 1.8k 133.9k 26.2k 14 13.2k 54s
review_pr 2 268 62.0k 1.8M 109.5k 164 190.1k 20m 9s
resolve_review 2 870 54.7k 7.1M 121.0k 274 167.2k 25m 38s
Total 17.0M 241.0k 18.7M 121.0k 907.7k 2h 11m

Token Efficiency

Step LoC Changed cache_read/LoC cache_write/LoC output/LoC
plan 0
verify 0
implement 1306 4853.1 253.5 58.6
prepare_pr 0
compose_pr 0
review_pr 0
resolve_review 101 69890.9 1655.4 541.3
Total 1407 13302.0 645.1 171.3

Trecek and others added 4 commits May 5, 2026 17:25
Adds ReviewConfig with local_review_rounds (default 3) and wires it through:
- AutomationConfig.from_dynaconf and defaults.yaml
- resolve_ingredient_defaults bridge (as "local_review_rounds" string)
- annotate_pr_diff callable: computes review_mode ("local" or "github")
  based on iteration < local_rounds, using git diff in local mode
- All three looping recipes (implementation, implementation-groups, remediation):
  - ingredients: adds local_review_rounds with default ""
  - annotate_pr_diff: passes base_branch, local_review_rounds, current_iteration;
    captures review_mode; adds optional_context_refs
  - review_pr: appends mode=${{ context.review_mode }}
  - resolve_review: appends mode=${{ context.review_mode }}
- Callable contracts for remediation and merge-prs

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…olve-review

Part B of the local review rounds feature (Part A covered config/callable/ingredient/recipe plumbing).

review-pr (mode=local):
- Skips all GitHub API calls for comment posting
- Writes findings to local_findings_{pr_number}.json with iteration tracking
- Still writes diff_context and raw_findings (mode-independent handoffs)
- Gate tokens emitted identically in both modes

resolve-review (mode=local):
- Reads from local_findings JSON instead of GitHub API
- ACCUMULATES DISCUSS findings to deferred_observations_{pr_number}.json (with round number)
- ACCUMULATES REJECT findings to reject_patterns_{pr_number}.json (stable filename, no timestamp)
- Skips all GitHub thread resolution and inline reply API calls
- Deduplicates before appending (guards against Issue #1604 duplicate comments)
- task test-check runs identically in both modes

resolve-review (mode=github):
- NEW: Before fetching findings, posts accumulated deferred_observations from prior local rounds
  as batch PR review comments with REVIEW-FLAG markers
- Then proceeds with existing GitHub API flow unchanged

Tests: test_review_pr_local_mode.py (11 tests), test_resolve_review_local_mode.py (16 tests), test_review_local_mode_contracts.py (10 tests)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator Author

@Trecek Trecek left a comment

Choose a reason for hiding this comment

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

AutoSkillit PR Review — Verdict: changes_requested

Comment thread src/autoskillit/smoke_utils.py Outdated
Comment thread src/autoskillit/smoke_utils.py Outdated
Comment thread src/autoskillit/smoke_utils.py
Comment thread src/autoskillit/smoke_utils.py
Comment thread src/autoskillit/config/_config_dataclasses.py
Comment thread tests/recipe/test_bundled_recipes_review_pr.py
Comment thread tests/skills/test_resolve_review_local_mode.py Outdated
Comment thread tests/skills/test_review_pr_local_mode.py Outdated
Comment thread tests/skills/test_review_pr_local_mode.py Outdated
Comment thread tests/test_smoke_utils.py
Copy link
Copy Markdown
Collaborator Author

@Trecek Trecek left a comment

Choose a reason for hiding this comment

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

AutoSkillit review: 2 blocking (critical) issues found. See inline comments — changes are required before merging.

Critical findings:

  • src/autoskillit/smoke_utils.py:88 — defense: int() conversions lack ValueError guard for non-numeric strings
  • src/autoskillit/smoke_utils.py:89 — bugs: review_mode='local' returned even when gh pr diff was called (empty base_branch fallback inconsistency)

Trecek and others added 4 commits May 5, 2026 19:39
…in annotate_pr_diff

- Wrap local_review_rounds and current_iteration int() casts in try/except ValueError
  (non-numeric non-empty strings no longer raise uncaught exceptions)
- Set review_mode="github" when local mode is requested but base_branch is empty,
  so the returned token matches the actual command executed (gh pr diff)
- Add warning log on silent local→github downgrade for observability
- Update T3.6 to supply base_branch so it actually tests local mode
- Add T3.8 covering the empty-base_branch fallback edge case

Addresses reviewer comments 3192654982, 3192654987, 3192654992, 3192654995, 3192655041

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…_review_rounds

- Add __post_init__ to ReviewConfig raising ValueError on negative values
- Wrap settings.py int() cast in _parse_int_config() helper that raises
  ConfigSchemaError with a clear message for non-numeric env var / YAML values
- Add local_review_rounds="0" fallback to ingredient_defaults.py except block
  so the key is always present even when config loading fails

Addresses reviewer comments 3192654999, 3192655003, 3192655005

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…usion comment

- Remove unnecessary from __future__ import annotations in test_review_config.py
- Add comment explaining why merge-prs.yaml is excluded from
  TestAnnotatePrDiffLocalReviewRounds parametrize fixture
- Drop trivially-satisfiable fallback disjunct "mode=" from test_resolve_review and
  test_review_pr mode parameter assertions — only the specific form is meaningful
- Replace trivially-satisfiable "default:" check with specific phrase assertion
  ("absent or unrecognized") in test_review_pr_local_mode_default_is_github

Addresses reviewer comments 3192655014, 3192655016, 3192655025, 3192655029, 3192655035

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ist line numbers

- T3.1 test_annotate_pr_diff_returns_review_mode_local: add base_branch="main" so
  the call actually exercises local mode (empty base_branch now falls back to github)
- Update _LEGACY_JSON_WRITES allowlist in test_schema_version_convention.py to
  reflect smoke_utils.py line shifts caused by the try/except guard insertion:
  115→126, 132→143, 346→357, 394→405 (also update list_site references)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator Author

@Trecek Trecek left a comment

Choose a reason for hiding this comment

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

AutoSkillit PR Review — Verdict: approved_with_comments

Comment thread tests/test_smoke_utils.py Outdated
Comment thread tests/test_smoke_utils.py
Comment thread tests/infra/test_schema_version_convention.py
Comment thread tests/config/test_review_config.py Outdated
Comment thread tests/config/test_review_config.py Outdated
Copy link
Copy Markdown
Collaborator Author

@Trecek Trecek left a comment

Choose a reason for hiding this comment

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

AutoSkillit review: warning-only findings detected. See inline comments — no blocking changes required.

One finding (tests/infra/test_schema_version_convention.py L156) is marked requires_decision as it documents intentional dual membership of a smoke_utils.py line in both the legacy allowlist and list_sites — verify the comment is accurate or add inline documentation.

Trecek and others added 3 commits May 5, 2026 20:03
… in test_review_config.py

Addresses reviewer comments 3192731887 and 3192731888.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
T3.3: move assert_called_once() after args[:3] check so assertion failures
report the actual command args rather than the call count first.
T3.4: add base_branch="" explicitly for symmetry with T3.1/T3.6.

Addresses reviewer comments 3192731880 and 3192731884.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…7 in allowlist

Lines 143 and 357 appear in both _LEGACY_JSON_WRITES and list_sites because the
AST scanner cannot distinguish list vs dict write payloads. Add inline comment to
prevent future confusion about the intentional dual membership.

Addresses reviewer comment 3192731886.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@Trecek Trecek added this pull request to the merge queue May 6, 2026
Merged via the queue into develop with commit 2577763 May 6, 2026
2 checks passed
@Trecek Trecek deleted the local-review-rounds-before-pr-creation-reduce-github-api-usa/1945 branch May 6, 2026 03:23
Trecek added a commit that referenced this pull request May 6, 2026
…tracts.py

Two docstrings introduced by develop/#1970 exceeded the 99-char ruff limit.
Shortened to pass pre-commit without changing assertion logic.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Trecek added a commit that referenced this pull request May 6, 2026
…tracts.py

Two docstrings introduced by develop/#1970 exceeded the 99-char ruff limit.
Shortened to pass pre-commit without changing assertion logic.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Trecek added a commit that referenced this pull request May 8, 2026
…itHub API Usage) (#1970)

## Summary

Add a `local_review_rounds` configuration and plumbing so that the
existing review loop steps (`annotate_pr_diff`, `review_pr`,
`resolve_review`, `check_review_loop`) receive a `review_mode` context
value (`"local"` or `"github"`) computed per-iteration. Part A covers
the config dataclass, defaults, ingredient bridge, callable
modification, recipe YAML wiring for all three looping recipes, and
tests for all of the above. Part B will cover the skill SKILL.md
behavioral changes (how `review-pr` and `resolve-review` branch on
`mode=local` vs `mode=github`) — implement as a separate task.

Closes #1945

## Implementation Plan

Plan file:
`/home/talon/projects/autoskillit-runs/impl-20260505-165914-350121/.autoskillit/temp/make-plan/local_review_rounds_plan_2026-05-05_170500_part_a.md`

🤖 Generated with [Claude Code](https://claude.com/claude-code) via
AutoSkillit
<!-- autoskillit:pipeline-signature
steps=prepare_pr,run_arch_lenses,compose_pr,annotate_pr_diff,review_pr
-->

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
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