scsh 1.22.2

Scoped Skills Helper — preflight a git repo and run its scoped skills in ephemeral containers.
# Built-in review-loop demo: implement a meaningful change to a deliberately tiny word-counting
# program, prepare its PR description, then loop an agent-driven do-while whose body is
# declare_done_or_fix → five parallel reviewer personas → decide. Review feedback travels as the
# decide step's `feedback` output, which the NEXT round's declare_done_or_fix step receives as a
# loop-carried input — review comments NEVER
# appear in the repository's git history. Only real work is committed: the feature, PR description,
# fixes, and any deliberate-style notes. The bar: every grade excellent or good, with at least as
# many excellent as good (excellent=5, good=4 ⇒ mean ≥ 4.5).
description: "Extend a tiny word-counting program, prepare its PR description, then loop five focused reviewers and a coding agent until the change meets the approval bar."
steps:
  implement:
    agent:
      harness: claude
      model: opus
    prompt: |
      This repository contains a deliberately small word-counting CLI. Implement this feature
      request without adding third-party dependencies:

      Generalize the program from counting individual words to counting adjacent word groups.
      Add `--group-size N` (default 1) and `--limit N` (default 10). Word groups must never cross
      an input line boundary. Normalize case, treat punctuation as separators while retaining
      apostrophes inside words, and order results deterministically by descending count then
      alphabetically. Reject non-positive option values with a clear CLI error. Preserve the
      existing output format for the default options.

      Rewrite the implementation as needed, update or add focused tests and user documentation,
      run the tests, and commit the complete feature with the message
      `fantastic-loop: add grouped word counts`. Put a one-line summary in the `summary` result
      field.
    output:
      summary:
        type: string
    commits: true
  prepare:
    needs: implement
    agent:
      harness: claude
      model: opus
    prompt: |
      Read this repository's code and its git history. Write `PR-DESCRIPTION.md` at the
      repository root describing the change set as if opening a pull request: the big picture
      first (what this code enables), then notable details. Commit only that file with the
      message `fantastic-loop: prepare PR description`. Put a one-line summary in the `summary`
      result field.
    output:
      summary:
        type: string
    commits: true
  declare_done_or_fix:
    needs: prepare
    inputs:
      FEEDBACK: decide.feedback
    agent:
      harness: claude
      model: opus
    prompt: |
      You are the coding agent in a review loop. The `FEEDBACK` environment variable carries the
      previous review round's full report. If it is empty, this is the first round: declare the
      implementation ready for its initial review, change nothing, commit nothing, and set the
      `actions` result field to `Ready for initial review.`
      Otherwise address EVERY comment in it: 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. Commit your changes with the message
      `fantastic-loop: address review feedback`. Write `actions` as several short paragraphs,
      separated by blank lines: one paragraph for each reviewer lens 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 long paragraph.
    output:
      actions:
        type: string
    commits: true
  review_correctness:
    needs: declare_done_or_fix
    agent:
      harness: codex
      model: gpt-5.5
    prompt: |
      You are the correctness reviewer in a five-reviewer panel. Review the code in this
      repository through that lens only: bugs, edge cases, error handling. Respect
      `STYLE-NOTES.md`: a decision documented there is deliberate — do not penalize it. Treat
      `PR-DESCRIPTION.md` as context only; grade the CODE. Grade fairly for the repository's
      modest scope: `excellent` means you would approve with praise, `good` means approve with
      nits, `average` or `poor` mean real work is needed. Put the grade in the `grade` result
      field and your most important, concrete, actionable comments (at most three, fewer is
      better, one plain-text string with one comment per paragraph) in `comments`. Put the exact
      number of comment paragraphs in `comment_count`. Do not change any files or make commits.
    output:
      grade:
        type: enum
        choices: excellent, good, average, poor
      comments:
        type: string
      comment_count:
        type: int
    commits: false
  review_conventions:
    needs: declare_done_or_fix
    agent:
      harness: codex
      model: gpt-5.5
    prompt: |
      You are the conventions reviewer in a five-reviewer panel. Review the code in this
      repository through that lens only: naming, structure, formatting, idiomatic consistency.
      Respect `STYLE-NOTES.md`: a decision documented there is deliberate — do not penalize it.
      Treat `PR-DESCRIPTION.md` as context only; grade the CODE. Grade fairly for the
      repository's modest scope: `excellent` means you would approve with praise, `good` means
      approve with nits, `average` or `poor` mean real work is needed. Put the grade in the
      `grade` result field and your most important, concrete, actionable comments (at most
      three, fewer is better, one plain-text string with one comment per paragraph) in
      `comments`. Put the exact number of comment paragraphs in `comment_count`. Do not change
      any files or make commits.
    output:
      grade:
        type: enum
        choices: excellent, good, average, poor
      comments:
        type: string
      comment_count:
        type: int
    commits: false
  review_simplicity:
    needs: declare_done_or_fix
    agent:
      harness: codex
      model: gpt-5.5
    prompt: |
      You are the simplicity reviewer in a five-reviewer panel. Review the code in this
      repository through that lens only: needless complexity, dead weight, whether every element
      earns its place. Respect `STYLE-NOTES.md`: a decision documented there is deliberate — do
      not penalize it. Treat `PR-DESCRIPTION.md` as context only; grade the CODE. Grade fairly
      for the repository's modest scope: `excellent` means you would approve with praise, `good`
      means approve with nits, `average` or `poor` mean real work is needed. Put the grade in
      the `grade` result field and your most important, concrete, actionable comments (at most
      three, fewer is better, one plain-text string with one comment per paragraph) in
      `comments`. Put the exact number of comment paragraphs in `comment_count`. Do not change
      any files or make commits.
    output:
      grade:
        type: enum
        choices: excellent, good, average, poor
      comments:
        type: string
      comment_count:
        type: int
    commits: false
  review_testing:
    needs: declare_done_or_fix
    agent:
      harness: codex
      model: gpt-5.5
    prompt: |
      You are the testing reviewer in a five-reviewer panel. Review the code in this repository
      through that lens only: is the behavior covered by runnable, meaningful tests, and do they
      pass. Respect `STYLE-NOTES.md`: a decision documented there is deliberate — do not
      penalize it. Treat `PR-DESCRIPTION.md` as context only; grade the CODE. Grade fairly for
      the repository's modest scope: `excellent` means you would approve with praise, `good`
      means approve with nits, `average` or `poor` mean real work is needed. Put the grade in
      the `grade` result field and your most important, concrete, actionable comments (at most
      three, fewer is better, one plain-text string with one comment per paragraph) in
      `comments`. Put the exact number of comment paragraphs in `comment_count`. Do not change
      any files or make commits.
    output:
      grade:
        type: enum
        choices: excellent, good, average, poor
      comments:
        type: string
      comment_count:
        type: int
    commits: false
  review_docs:
    needs: declare_done_or_fix
    agent:
      harness: codex
      model: gpt-5.5
    prompt: |
      You are the documentation reviewer in a five-reviewer panel. Review the code in this
      repository through that lens only: readability for a newcomer — comments, docstrings, and
      README accuracy. Respect `STYLE-NOTES.md`: a decision documented there is deliberate — do
      not penalize it. Treat `PR-DESCRIPTION.md` as context only; grade the CODE. Grade fairly
      for the repository's modest scope: `excellent` means you would approve with praise, `good`
      means approve with nits, `average` or `poor` mean real work is needed. Put the grade in
      the `grade` result field and your most important, concrete, actionable comments (at most
      three, fewer is better, one plain-text string with one comment per paragraph) in
      `comments`. Put the exact number of comment paragraphs in `comment_count`. Do not change
      any files or make commits.
    output:
      grade:
        type: enum
        choices: excellent, good, average, poor
      comments:
        type: string
      comment_count:
        type: int
    commits: false
  decide:
    needs: review_correctness, review_conventions, review_simplicity, review_testing, review_docs
    do-while: declare_done_or_fix
    agent:
      harness: codex
      model: gpt-5.5
    inputs:
      GRADE_CORRECTNESS: review_correctness.grade
      COMMENTS_CORRECTNESS: review_correctness.comments
      GRADE_CONVENTIONS: review_conventions.grade
      COMMENTS_CONVENTIONS: review_conventions.comments
      GRADE_SIMPLICITY: review_simplicity.grade
      COMMENTS_SIMPLICITY: review_simplicity.comments
      GRADE_TESTING: review_testing.grade
      COMMENTS_TESTING: review_testing.comments
      GRADE_DOCS: review_docs.grade
      COMMENTS_DOCS: review_docs.comments
    prompt: |
      You are the scorekeeper of a review loop. The five reviewer grades and comments are in the
      GRADE_* and COMMENTS_* environment variables. Scores: excellent=5, good=4, average=3,
      poor=2. The bar is met when EVERY grade is excellent or good AND there are at least as
      many excellent as good (equivalently, the mean score is at least 4.5). Do not change any
      files or make commits. Put `met` or `not met` in the `verdict` result field. Put the full
      round report in the `feedback` result field as one plain-text string: first the line
      `Round verdict: met` or `Round verdict: not met`, then each reviewer's grade and comments
      verbatim, one labeled section per reviewer. Set `SCSH_DO_WHILE_REPEAT` to true when the
      bar is NOT met (another round is needed), false when it is met.
    output:
      SCSH_DO_WHILE_REPEAT:
        type: bool
      verdict:
        type: string
      feedback:
        type: string
    commits: false