Repository navigation
Merge train: land all 44 open PRs - #243
Merged
Merged
Conversation
_render_dag and _render_dag_markdown walked the DAG as a tree, so a group with several parents (and its whole subtree, and its '<-- this PR' marker) appeared once per parent. The merge node is now drawn in full under its last-listed parent with '(also depends on: ...)' and referenced as '(see below)' under the others.
A chmod-only change produces a diff entry with no hunks. Like binary files, nothing in the plan can claim it, coverage validation passes, and the mode change is missing from every sub-PR. Reject it up front with the same kind of message as binary files.
The '(see below)' stub was placed under every parent except depends_on[-1], but the DFS visits parents in group order, so the stub could appear after the full node. Render in full under the last parent actually visited and drop the unreachable 'rendered' guard.
fetch_fork_pr and fetch_fork_branch fetched into refs/pr-split/* without a leading '+', so once the ref existed from a previous run any rebased or force-pushed fork head was rejected as non-fast-forward and the split failed with PR_FETCH_FAILED. Use a forced refspec.
A parent that is never visited (it depends on an unknown group) left its child stubbed forever with no full rendering. Compute the pending set from a root-first reachability walk.
The chunk file summary said 'indices 0..N-1' where N was the number of that file's hunks in the chunk, while the diff labels (and the system prompt's instructions) use per-file global indices. For a file split across chunks the summary told the model to use indices already assigned in an earlier chunk. FileSummary now carries the actual indices and the summary lists them when they are not 0..N-1.
derive_split_namespace could return an empty string (branch 'pr-split//pr-1', rejected by git), emit '..' or edge dots, and mapped user:feat/x and a local feat-x to the same namespace so one split's add_worktree force-deleted the other's branches. Keep the fork user in the namespace, strip ref-invalid sequences, and fall back to a short hash when nothing survives.
Setting any permission in a workflow resets the others to none, so the example's pull-requests: write alone leaves actions/checkout without read access on private repos. The repo's own split-score.yml already includes contents: read.
Tracking 'done' parents was wrong in both directions (a mid-walk ancestor is neither done nor pending). Count visits instead: every reachable parent is drawn exactly once, so a child is stubbed until its final visit and drawn in full there.
score_pr.py materialised the PR's base and head as local branches named after them. A fork PR opened from the fork's own 'main' has HEAD_BRANCH == BASE_BRANCH, so the second 'git branch -f' pointed the base at the PR head, the diff came out empty, and the PR was reported as within limits. Pass origin/<base> and the fetched head ref straight to pr-split instead; rev-parse --verify accepts any ref.
…shold The comment step only ran when should_split was true, so once a PR was pushed back under the limit its old '<!-- pr-split-score -->' comment with the split plan stayed. The script now writes a 'within limits' body on every skip, and the action updates an existing marker comment regardless of should_split while still only creating one when a split is suggested. Non-PR events are skipped in the step itself.
scripts/score_pr.py computes overflow*1000 + file_scatter*50 + groups, not the full score_plan objective (underflow, edges, tiny groups, depth/width) that README and METHODOLOGY describe; say so.
… path Failure-path skips (pr-split error, missing plan) must not produce a body, or a transient failure would overwrite a valid split-plan comment with a false 'within limits' message.
unidiff's is_removed_file is true for any single hunk whose target length is 0, which also matches a file emptied on the dev branch. The sub-PR then deleted the file, its tree differed from dev, and merging it conflicted (modify/delete). Treat only a /dev/null target as a deletion.
A chmod that came with a content change passed validation but the worker only wrote file content, so the executable bit never reached the sub-PR. Read new mode / new file mode from the diff header and chmod the materialized file.
A symlink in the diff (new file mode 120000, or index ... 120000 for a retargeted link) was written as a regular file containing the target path plus a newline, so the sub-PR changed the entry type. Read the mode from the index line too, create symlinks with symlink_to, never write through an existing link, and unlink dangling links on removal.
A get_pr_state failure was recorded as a skip and the run still ended with exit 0 and 'Merge complete', so a broken gh session or transient API error looked like success to scripts and webhooks. Report the affected groups, exit 1, and send exit_reason=fetch_error.
A response with status=failed carries no function_call, so it was reported as 'no function_call in response output' and the real error (rate limit, server error) was lost.
The example used @main while the repo's own split-score.yml pins @v1.0.0; a floating ref means downstream repos pick up unreleased action changes. Match the shipped workflow.
A PR closed while --auto polled was discarded silently: the batch was reported as incomplete with an empty skipped list. Record it as '(CLOSED)' like a closed PR found before merging.
Every non-tool_use stop reason was logged as 'LLM output truncated', mislabelling end_turn/stop_sequence responses that carried a complete tool block.
…to claude/nice-gauss-whhkxl Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015rnEEjXWDBdePRhKMmZr1w
… claude/nice-gauss-whhkxl Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015rnEEjXWDBdePRhKMmZr1w
…aude/nice-gauss-whhkxl Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015rnEEjXWDBdePRhKMmZr1w
…o claude/nice-gauss-whhkxl Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015rnEEjXWDBdePRhKMmZr1w
…aude/nice-gauss-whhkxl Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015rnEEjXWDBdePRhKMmZr1w
…to claude/nice-gauss-whhkxl Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015rnEEjXWDBdePRhKMmZr1w
…aude/nice-gauss-whhkxl Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015rnEEjXWDBdePRhKMmZr1w
…' into claude/nice-gauss-whhkxl Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015rnEEjXWDBdePRhKMmZr1w
… into claude/nice-gauss-whhkxl Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015rnEEjXWDBdePRhKMmZr1w
pr-split now saves plans under .pr-split/plans/<branch>.json, so the score action looked for .pr-split/plan.json, never found it, and reported every oversized PR as "pr-split wrote no plan file". Read the per-branch file, falling back to the legacy path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015rnEEjXWDBdePRhKMmZr1w
|
Warning Review limit reachedNext included review available in 36 minutes. View limit detailsLimit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (42)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
pr-split analysis
This PR has 4,187 LOC and could be split into 22 smaller PRs:
Run |
This was referenced Sep 27, 2026
Closed
Closed
vitali87
pushed a commit
that referenced
this pull request
Sep 28, 2026
Under the default orthogonal priority, keeping two different files in one group cost 400 per file pair while opening a group cost 250, so the optimum was always one file per group: 21 PRs, several of 3-6 lines, for this repo's 1,698-line PR #10. Only unrelated files (no shared directory, symbols or test pairing) now pay that penalty; related ones get their affinity reward, so they share a PR when it fits. The model is also far smaller and starts from a good plan: - one variable per scored unit pair with linear bounds, instead of one per pair per group slot (n^2 variables instead of n^3); - group slots bounded by the graph plan's size plus a margin, instead of one per unit; - the graph plan seeds the search as a hint; - groups are numbered in diff order, not by arbitrary solver slot. On PR #10, cp_sat now plans 8 groups, down from 21, and proves the plan optimal in about 5 seconds; before, it stopped at its 15-second limit. On the 4,187-line merge #243 it plans 13 groups without tiny ones (the graph planner makes 24, 11 of them tiny), scoring 300 on pr-split's plan objective against the graph plan's 387. That diff still reaches the time limit without proving optimality, and runs of up to 60 seconds give the same plan. After the standalone pass, every sub-PR of both splits passes its own test suite. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015rnEEjXWDBdePRhKMmZr1w
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Lands every open PR in one merge, so CI and the branch-up-to-date rule only have to pass once instead of 44 times in a row. Each PR branch was first updated with current
main(merge commits, no force-push), then all were merged here. Every PR head is an ancestor of this branch, so GitHub marks each PR merged once this lands.Included
Changes made while merging
main, so it lands as a no-op.mainalready. Only their remaining parts are kept.splitnow requires the base to be a local branch.core.hooksPathdirectory is now a privatemkdtempdirectory instead of a fixed shared path under the temp dir, where another local user could plant hooks.ghwas missing. With fix: keep split --dry-run non-destructive and report a typo'd branch as not found #111/fix: validate split settings before the existing-plan cleanup closes PRs and deletes branches #136 in, a dry run with an existing split now refuses before any cleanup, soghis never reached. The test now asserts that refusal.scripts/score_pr.pyread.pr-split/plan.json, but plans now live under.pr-split/plans/<branch>.json. The score action therefore reported every oversized PR as "wrote no plan file". It now reads the per-branch file and falls back to the old path.Checks
ruff check,ruff format --check,ty check pr_split(20 diagnostics, same as main) andpytest(1015 passed) all pass locally.🤖 Generated with Claude Code
https://claude.ai/code/session_015rnEEjXWDBdePRhKMmZr1w
Generated by Claude Code