## What Adds `pr-simplify`, a Fabro workflow that runs a "simplify" code-review pass over an existing PR and updates that same PR in place. ## How it works - **One agent, three parallel reviews.** A single agent node runs the pass and uses `spawn_agent` to fan out three reviewers — code reuse, code quality, and efficiency — concurrently, then aggregates their findings. Sub-agent results return directly to the orchestrator, which is the clean way to aggregate multiple perspectives. (A fork + `tripleoctagon` fan-in was the wrong primitive here: fan-in selects a single "best" branch and merges only its worktree, so it would silently drop two of the three reviews.) - **Updates the existing PR — no new PR.** The agent runs `gh pr checkout` on the PR's branch, applies the fixes, commits, and pushes — landing one fixup commit on the existing PR, plus a summary comment and a `simplify:<model>` label. `[run.pull_request] enabled = false` keeps Fabro from opening a second PR from its run branch. - **Fable by default, overridable.** The graph sets `default_model=claude-fable-5`, which floors the orchestrator and all three reviewers to Fable. `--model <id>` wins over it per run (`configured model → graph default_model → catalog default`), and the label reflects whatever actually ran. ## Usage ```bash fabro run pr-simplify -I pr=<number> # Fable (default) fabro run pr-simplify -I pr=<number> --model gpt-55 # override the model ``` Requires GitHub token permissions `contents` / `pull_requests` / `issues` = write (declared in the workflow) so it can push the commit, comment, and label. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Signed-off-by: Bryan Helmkamp <19+brynary@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com> Co-authored-by: Bryan Helmkamp <19+brynary@users.noreply.github.com>
4.5 KiB
Simplify: Code Review and Cleanup
Run the simplify code-review pass on PR #{{ inputs.pr }}: review the changes for reuse, quality, and efficiency, fix what's worth fixing, and update the existing PR in place.
Phase 1: Identify the changes
Run gh pr diff {{ inputs.pr }} to see what changed. (Fall back to git diff origin/main...HEAD if that returns nothing.) This diff is the shared context for the reviews below.
Phase 2: Launch three review sub-agents in parallel
Use the spawn_agent tool to launch all three reviewers below. Spawn all three first so they run concurrently, then wait for their results and aggregate them. Give each sub-agent its full brief, and tell it to run gh pr diff {{ inputs.pr }} itself to see the changes. Each reviewer only reports findings — it does not edit code.
Reviewer 1 — Code Reuse
For each change:
- Search for existing utilities and helpers that could replace newly written code. Use grep to find similar patterns elsewhere — utility directories, shared modules, and files adjacent to the changed ones.
- Flag any new function that duplicates existing functionality; name the existing function to use instead.
- Flag inline logic that could use an existing utility — hand-rolled string manipulation, manual path handling, custom environment checks, ad-hoc type guards, and similar.
This is a greenfield app — focus on maximizing simplicity; don't worry about backward compatibility.
Reviewer 2 — Code Quality
Review the same changes for hacky patterns:
- Redundant state: state that duplicates existing state, cached values that could be derived, observers/effects that could be direct calls.
- Parameter sprawl: new parameters bolted onto a function instead of generalizing or restructuring existing ones.
- Copy-paste with slight variation: near-duplicate blocks that should be unified with a shared abstraction.
- Leaky abstractions: exposing internals that should be encapsulated, or breaking existing boundaries.
- Stringly-typed code: raw strings where constants, enums, or branded types already exist.
This is a greenfield app — be aggressive in optimizing quality.
Reviewer 3 — Efficiency
Review the same changes for efficiency:
- Unnecessary work: redundant computations, repeated file reads, duplicate network/API calls, N+1 patterns.
- Missed concurrency: independent operations run sequentially when they could run in parallel.
- Hot-path bloat: new blocking work added to startup or per-request/per-render hot paths.
- Unnecessary existence checks: pre-checking a file/resource before operating (TOCTOU) — operate directly and handle the error.
- Memory: unbounded data structures, missing cleanup, listener leaks.
- Overly broad operations: reading whole files when a portion suffices, loading all items when filtering for one.
Phase 3: Apply fixes
Wait for all three reviewers, aggregate their findings, and fix each issue directly. If a finding is a false positive or not worth addressing, note it and move on — don't argue with it, just skip it.
Phase 4: Update the existing PR
-
Check out the PR branch: run
gh pr checkout {{ inputs.pr }}so your edits land on the PR's own branch. Do not create a new branch or a new PR. -
Commit and push: commit with a clear message describing the simplify pass, then push to update PR #{{ inputs.pr }}. Push to the existing branch — do not open a new pull request. If you made no changes (the code was already clean), skip the commit and say so in the comment below.
-
Comment: post a summary on PR #{{ inputs.pr }} noting this was an automated simplify run, what was fixed, and anything you skipped and why:
gh pr comment {{ inputs.pr }} --body "<your summary>" -
Label: record which model ran this pass. Read the model you are running as from your environment block (the
Model:line) and build the labelsimplify:<model-id>— e.g. if your model isclaude-opus-4-8, the label issimplify:claude-opus-4-8. Apply it via the GitHub issues API; do not usegh pr edit --add-label(it walks a deprecated Projects-classic GraphQL path and fails here). Ensure the label exists, then add it (gh fills{owner}/{repo}from the current repo):gh label create "simplify:<model-id>" --color BFD4F2 --description "Simplify pass by <model-id>" 2>/dev/null || true gh api repos/{owner}/{repo}/issues/{{ inputs.pr }}/labels -X POST -f "labels[]=simplify:<model-id>"
Done
Briefly summarize what was fixed (or confirm the code was already clean), and confirm the PR was updated, commented, and labeled.