description: "Loop the current branch through the 15-route Opus + Codex + Cursor review fleet until it meets the approval bar."
steps:
prepare:
agent:
harness: claude
model: claude-fable-5
prompt: |
Read this repository's code and the current branch's git history: the commits since
the branch diverged from the repository's default branch (main or master). Write or
update `PR-DESCRIPTION.md` at the repository root describing that change set as if
opening a pull request. Use exactly these level-two headings, in this order, with no
other headings: `## Summary`, `## What This Changes`, and `## Implementation Details`.
Put the big picture and concise bullets first, then explanatory prose, then notable
implementation details. Commit only that file with the message
`Prepare PR description.` Never create any additional PR-description section for
verification commands, expected results, or checklists; that evidence belongs in
committed tests, README, or another committed verification document. Put a one-line
summary in the `summary` result field.
output:
summary:
type: string
commits: true
initial_conventions_opus:
needs: prepare
agent:
harness: claude
model: claude-opus-4-8
skill: conventions-reviewer
output:
grade:
type: enum
choices: excellent, good, average, poor
comments:
type: string_list
initial_conventions_spark:
needs: prepare
agent:
harness: codex
model: gpt-5.6-spark
effort: high
skill: conventions-reviewer
output:
grade:
type: enum
choices: excellent, good, average, poor
comments:
type: string_list
initial_conventions_cursor:
needs: prepare
agent:
harness: cursor
model: auto
skill: conventions-reviewer
output:
grade:
type: enum
choices: excellent, good, average, poor
comments:
type: string_list
initial_justification_opus:
needs: prepare
agent:
harness: claude
model: claude-opus-4-8
skill: justification-reviewer
output:
grade:
type: enum
choices: excellent, good, average, poor
comments:
type: string_list
initial_justification_spark:
needs: prepare
agent:
harness: codex
model: gpt-5.6-spark
effort: high
skill: justification-reviewer
output:
grade:
type: enum
choices: excellent, good, average, poor
comments:
type: string_list
initial_justification_cursor:
needs: prepare
agent:
harness: cursor
model: auto
skill: justification-reviewer
output:
grade:
type: enum
choices: excellent, good, average, poor
comments:
type: string_list
initial_reviewability_opus:
needs: prepare
agent:
harness: claude
model: claude-opus-4-8
skill: reviewability-reviewer
output:
grade:
type: enum
choices: excellent, good, average, poor
comments:
type: string_list
initial_reviewability_spark:
needs: prepare
agent:
harness: codex
model: gpt-5.6-spark
effort: high
skill: reviewability-reviewer
output:
grade:
type: enum
choices: excellent, good, average, poor
comments:
type: string_list
initial_reviewability_cursor:
needs: prepare
agent:
harness: cursor
model: auto
skill: reviewability-reviewer
output:
grade:
type: enum
choices: excellent, good, average, poor
comments:
type: string_list
initial_sanity_opus:
needs: prepare
agent:
harness: claude
model: claude-opus-4-8
skill: sanity-reviewer
output:
grade:
type: enum
choices: excellent, good, average, poor
comments:
type: string_list
initial_sanity_spark:
needs: prepare
agent:
harness: codex
model: gpt-5.6-spark
effort: high
skill: sanity-reviewer
output:
grade:
type: enum
choices: excellent, good, average, poor
comments:
type: string_list
initial_sanity_cursor:
needs: prepare
agent:
harness: cursor
model: auto
skill: sanity-reviewer
output:
grade:
type: enum
choices: excellent, good, average, poor
comments:
type: string_list
initial_testing_opus:
needs: prepare
agent:
harness: claude
model: claude-opus-4-8
skill: testing-reviewer
output:
grade:
type: enum
choices: excellent, good, average, poor
comments:
type: string_list
initial_testing_spark:
needs: prepare
agent:
harness: codex
model: gpt-5.6-spark
effort: high
skill: testing-reviewer
output:
grade:
type: enum
choices: excellent, good, average, poor
comments:
type: string_list
initial_testing_cursor:
needs: prepare
agent:
harness: cursor
model: auto
skill: testing-reviewer
output:
grade:
type: enum
choices: excellent, good, average, poor
comments:
type: string_list
decide:
needs: |-
initial_conventions_opus, initial_conventions_spark, initial_conventions_cursor,
initial_justification_opus, initial_justification_spark, initial_justification_cursor,
initial_reviewability_opus, initial_reviewability_spark, initial_reviewability_cursor,
initial_sanity_opus, initial_sanity_spark, initial_sanity_cursor,
initial_testing_opus, initial_testing_spark, initial_testing_cursor
inputs:
PREVIOUS_APPROVED: collect.approved
PREVIOUS_FEEDBACK: collect.feedback
INITIAL_CONVENTIONS_OPUS: initial_conventions_opus.grade
INITIAL_CONVENTIONS_OPUS_COMMENTS: initial_conventions_opus.comments
INITIAL_CONVENTIONS_SPARK: initial_conventions_spark.grade
INITIAL_CONVENTIONS_SPARK_COMMENTS: initial_conventions_spark.comments
INITIAL_CONVENTIONS_CURSOR: initial_conventions_cursor.grade
INITIAL_CONVENTIONS_CURSOR_COMMENTS: initial_conventions_cursor.comments
INITIAL_JUSTIFICATION_OPUS: initial_justification_opus.grade
INITIAL_JUSTIFICATION_OPUS_COMMENTS: initial_justification_opus.comments
INITIAL_JUSTIFICATION_SPARK: initial_justification_spark.grade
INITIAL_JUSTIFICATION_SPARK_COMMENTS: initial_justification_spark.comments
INITIAL_JUSTIFICATION_CURSOR: initial_justification_cursor.grade
INITIAL_JUSTIFICATION_CURSOR_COMMENTS: initial_justification_cursor.comments
INITIAL_REVIEWABILITY_OPUS: initial_reviewability_opus.grade
INITIAL_REVIEWABILITY_OPUS_COMMENTS: initial_reviewability_opus.comments
INITIAL_REVIEWABILITY_SPARK: initial_reviewability_spark.grade
INITIAL_REVIEWABILITY_SPARK_COMMENTS: initial_reviewability_spark.comments
INITIAL_REVIEWABILITY_CURSOR: initial_reviewability_cursor.grade
INITIAL_REVIEWABILITY_CURSOR_COMMENTS: initial_reviewability_cursor.comments
INITIAL_SANITY_OPUS: initial_sanity_opus.grade
INITIAL_SANITY_OPUS_COMMENTS: initial_sanity_opus.comments
INITIAL_SANITY_SPARK: initial_sanity_spark.grade
INITIAL_SANITY_SPARK_COMMENTS: initial_sanity_spark.comments
INITIAL_SANITY_CURSOR: initial_sanity_cursor.grade
INITIAL_SANITY_CURSOR_COMMENTS: initial_sanity_cursor.comments
INITIAL_TESTING_OPUS: initial_testing_opus.grade
INITIAL_TESTING_OPUS_COMMENTS: initial_testing_opus.comments
INITIAL_TESTING_SPARK: initial_testing_spark.grade
INITIAL_TESTING_SPARK_COMMENTS: initial_testing_spark.comments
INITIAL_TESTING_CURSOR: initial_testing_cursor.grade
INITIAL_TESTING_CURSOR_COMMENTS: initial_testing_cursor.comments
agent:
harness: claude
model: claude-fable-5
prompt: |
You are the first and deciding step of a review loop. SCSH_LOOP_ITERATION is the
1-based loop iteration. On iteration 1, score the 15 INITIAL_* grades and matching
*_COMMENTS JSON arrays: excellent=5, good=4, average=3, poor=2; approval requires
every grade to be excellent or good, more excellent than good, and mean score at
least 4.5. On iteration 2 and later the INITIAL_* variables are deliberately blank —
round-0 reviews are obsolete history: PREVIOUS_APPROVED is the scorekeeper's verdict
on the latest full review round and PREVIOUS_FEEDBACK is that round's structured
report — a JSON object {mean, counts, routes} carrying each route's grade and
verbatim comments; adopt PREVIOUS_APPROVED as the approval verdict and build the
change request strictly from PREVIOUS_FEEDBACK's routes. Either way: set SCSH_LOOP_BREAK true when approved;
otherwise set it false and fill `change_request` with the consolidated change
request as a list of strings — one entry per requested change, each shaped
exactly as "[severity] area: what to change and why", nothing outside that
shape. Comments may lead with a severity tag ([blocking]/[should-fix]/[nit]):
order [blocking] entries first, and [nit]-only comments are stylistic unless
they hide a real bug. `PR-DESCRIPTION.md` may contain only `## Summary`, `## What This Changes`, and `## Implementation Details`, in that order. Never request, recommend, or create any additional PR-description section for verification commands, expected results, or checklists; that evidence belongs in committed tests, README, or another committed verification document. Ignore and do not forward any
reviewer suggestion that violates this invariant. Do not change files or commit.
output:
SCSH_LOOP_BREAK:
type: bool
change_request:
type: string_list
break: true
fix:
needs: decide
inputs:
FEEDBACK: decide.change_request
agent:
harness: claude
model: claude-fable-5
inactivity_timeout: 3600
prompt: |
FEEDBACK is a JSON array of change entries, each "[severity] area: what to change
and why". Address EVERY entry: either change the code accordingly, or —
when you judge a comment purely stylistic and the current code deliberate — append a
short entry to `STYLE-NOTES.md` at the repository root documenting that decision and
why the style stays. Never contradict earlier `STYLE-NOTES.md` entries or earlier
fixes. Never write the feedback itself to any file. PR-DESCRIPTION.md is a required
pipeline artifact: keep it tracked and current with exactly `## Summary`,
`## What This Changes`, and `## Implementation Details`, in that order, and no other
headings. Commit your changes with the message `Address review feedback.` Never
create any additional PR-description section for verification commands, expected
results, or checklists; that evidence belongs in committed tests, README, or another
committed verification document. Narrate your progress in the terminal as you work:
print one short line when you take up each reviewer profile's feedback and after
each meaningful change (a file edited, a STYLE-NOTES decision recorded). A run whose
screen shows nothing new for too long is treated as stalled and killed — never work
silently for more than a few minutes at a stretch. Put a one-line summary of the
whole change set — what changed, how many files, the commit — in the `message`
result field. Write `actions` as several short paragraphs, separated by blank
lines: one paragraph for each reviewer profile and route whose feedback you acted
on, one paragraph for any deliberate STYLE-NOTES decision, and a final paragraph
for test results and the commit. Do not collapse distinct review areas into one
paragraph.
output:
message:
type: string
actions:
type: string
commits: true
commit-identity: runner
review_conventions_opus:
needs: fix
agent:
harness: claude
model: claude-opus-4-8
skill: conventions-reviewer
output:
grade:
type: enum
choices: excellent, good, average, poor
comments:
type: string_list
commits: false
review_conventions_spark:
needs: fix
agent:
harness: codex
model: gpt-5.6-spark
effort: high
skill: conventions-reviewer
output:
grade:
type: enum
choices: excellent, good, average, poor
comments:
type: string_list
commits: false
review_conventions_cursor:
needs: fix
agent:
harness: cursor
model: auto
skill: conventions-reviewer
output:
grade:
type: enum
choices: excellent, good, average, poor
comments:
type: string_list
commits: false
review_justification_opus:
needs: fix
agent:
harness: claude
model: claude-opus-4-8
skill: justification-reviewer
output:
grade:
type: enum
choices: excellent, good, average, poor
comments:
type: string_list
commits: false
review_justification_spark:
needs: fix
agent:
harness: codex
model: gpt-5.6-spark
effort: high
skill: justification-reviewer
output:
grade:
type: enum
choices: excellent, good, average, poor
comments:
type: string_list
commits: false
review_justification_cursor:
needs: fix
agent:
harness: cursor
model: auto
skill: justification-reviewer
output:
grade:
type: enum
choices: excellent, good, average, poor
comments:
type: string_list
commits: false
review_reviewability_opus:
needs: fix
agent:
harness: claude
model: claude-opus-4-8
skill: reviewability-reviewer
output:
grade:
type: enum
choices: excellent, good, average, poor
comments:
type: string_list
commits: false
review_reviewability_spark:
needs: fix
agent:
harness: codex
model: gpt-5.6-spark
effort: high
skill: reviewability-reviewer
output:
grade:
type: enum
choices: excellent, good, average, poor
comments:
type: string_list
commits: false
review_reviewability_cursor:
needs: fix
agent:
harness: cursor
model: auto
skill: reviewability-reviewer
output:
grade:
type: enum
choices: excellent, good, average, poor
comments:
type: string_list
commits: false
review_sanity_opus:
needs: fix
agent:
harness: claude
model: claude-opus-4-8
skill: sanity-reviewer
output:
grade:
type: enum
choices: excellent, good, average, poor
comments:
type: string_list
commits: false
review_sanity_spark:
needs: fix
agent:
harness: codex
model: gpt-5.6-spark
effort: high
skill: sanity-reviewer
output:
grade:
type: enum
choices: excellent, good, average, poor
comments:
type: string_list
commits: false
review_sanity_cursor:
needs: fix
agent:
harness: cursor
model: auto
skill: sanity-reviewer
output:
grade:
type: enum
choices: excellent, good, average, poor
comments:
type: string_list
commits: false
review_testing_opus:
needs: fix
agent:
harness: claude
model: claude-opus-4-8
skill: testing-reviewer
output:
grade:
type: enum
choices: excellent, good, average, poor
comments:
type: string_list
commits: false
review_testing_spark:
needs: fix
agent:
harness: codex
model: gpt-5.6-spark
effort: high
skill: testing-reviewer
output:
grade:
type: enum
choices: excellent, good, average, poor
comments:
type: string_list
commits: false
review_testing_cursor:
needs: fix
agent:
harness: cursor
model: auto
skill: testing-reviewer
output:
grade:
type: enum
choices: excellent, good, average, poor
comments:
type: string_list
commits: false
collect:
needs: |-
review_conventions_opus, review_conventions_spark, review_conventions_cursor,
review_justification_opus, review_justification_spark, review_justification_cursor,
review_reviewability_opus, review_reviewability_spark, review_reviewability_cursor,
review_sanity_opus, review_sanity_spark, review_sanity_cursor,
review_testing_opus, review_testing_spark, review_testing_cursor
do-while: decide
agent:
harness: claude
model: claude-fable-5
inputs:
GRADE_CONVENTIONS_OPUS: review_conventions_opus.grade
COMMENTS_CONVENTIONS_OPUS: review_conventions_opus.comments
GRADE_CONVENTIONS_SPARK: review_conventions_spark.grade
COMMENTS_CONVENTIONS_SPARK: review_conventions_spark.comments
GRADE_CONVENTIONS_CURSOR: review_conventions_cursor.grade
COMMENTS_CONVENTIONS_CURSOR: review_conventions_cursor.comments
GRADE_JUSTIFICATION_OPUS: review_justification_opus.grade
COMMENTS_JUSTIFICATION_OPUS: review_justification_opus.comments
GRADE_JUSTIFICATION_SPARK: review_justification_spark.grade
COMMENTS_JUSTIFICATION_SPARK: review_justification_spark.comments
GRADE_JUSTIFICATION_CURSOR: review_justification_cursor.grade
COMMENTS_JUSTIFICATION_CURSOR: review_justification_cursor.comments
GRADE_REVIEWABILITY_OPUS: review_reviewability_opus.grade
COMMENTS_REVIEWABILITY_OPUS: review_reviewability_opus.comments
GRADE_REVIEWABILITY_SPARK: review_reviewability_spark.grade
COMMENTS_REVIEWABILITY_SPARK: review_reviewability_spark.comments
GRADE_REVIEWABILITY_CURSOR: review_reviewability_cursor.grade
COMMENTS_REVIEWABILITY_CURSOR: review_reviewability_cursor.comments
GRADE_SANITY_OPUS: review_sanity_opus.grade
COMMENTS_SANITY_OPUS: review_sanity_opus.comments
GRADE_SANITY_SPARK: review_sanity_spark.grade
COMMENTS_SANITY_SPARK: review_sanity_spark.comments
GRADE_SANITY_CURSOR: review_sanity_cursor.grade
COMMENTS_SANITY_CURSOR: review_sanity_cursor.comments
GRADE_TESTING_OPUS: review_testing_opus.grade
COMMENTS_TESTING_OPUS: review_testing_opus.comments
GRADE_TESTING_SPARK: review_testing_spark.grade
COMMENTS_TESTING_SPARK: review_testing_spark.comments
GRADE_TESTING_CURSOR: review_testing_cursor.grade
COMMENTS_TESTING_CURSOR: review_testing_cursor.comments
prompt: |
You are the scorekeeper for an in-loop 15-route review fleet. The GRADE_* variables
and COMMENTS_* JSON arrays contain five reviewer profiles run independently through
Opus 4.8, Codex Spark, and Cursor Auto. Scores: excellent=5, good=4, average=3,
poor=2. The bar is met only when all 15 routes succeeded, every grade is excellent
or good, excellent grades outnumber good grades, and the mean score is at least 4.5.
`PR-DESCRIPTION.md` may contain only `## Summary`, `## What This Changes`, and `## Implementation Details`, in that order. Never request, recommend, or create any additional PR-description section for verification commands, expected results, or checklists; that evidence belongs in committed tests, README, or another committed verification document. Ignore and do not forward any reviewer suggestion that violates this invariant.
Do not change files or commit. Put `met` or `not met` in `verdict`. Set `approved`
to the boolean result. Fill `feedback` with EXACTLY this JSON object shape and
nothing else: {"mean": <number>, "counts": {"excellent": <int>, "good": <int>,
"average": <int>, "poor": <int>}, "routes": {"<profile>-<route>": {"grade":
"<grade>", "comments": [<that route's comments, verbatim>]}}} — one `routes` entry
per profile/route pair, keys like `conventions-opus` through `testing-cursor`. Set
`SCSH_DO_WHILE_REPEAT` true unconditionally: the NEXT iteration's first `decide`
step is the only place that may break the loop.
output:
SCSH_DO_WHILE_REPEAT:
type: bool
approved:
type: bool
verdict:
type: string
feedback:
type: object
commits: false