agentleFS
mwellis81mwellis81/spec-factory/skills/sf-review/SKILL.md

sf-review

Skill1 starsChanged 40 days agoMITView on GitHub

Use when a lint-clean artifact needs its independent review round and cross-model check.

1 other project uses a version of this.

Adopted by

Most recently taken up by

  • Other versions1 project uses a version of this.

    Word for word · 0

    None found.

    Edited · 0

    None found.

    Wrote their own version · 1

    1. giangdvdotdev/aseprite-mcp★ 3same name

    How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.

  • In this repository13 other files it gives its agents.

The file

Show its rules and text

We split this skill into the rules it gives an agent

20 rules. About 0 are common, 5 are distinctive, and 15 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈5

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 15

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Call it with one artifact path.

    line 12
  2. Distinctive:

    When a stage skill called you, hand the two front-matter values back to it.

    line 13
  3. Very specific:

    Read the artifact's front matter for kind, version, and weight, and read specfactory.config.yaml for answerer, fixture, and codex_model.

    line 17
  4. Distinctive:

    Stop and return the reason if any of these holds:

    line 19
  5. Very specific:

    When the kind and weight select no specialist, record NOT_APPLICABLE: no specialist for this artifact in the digest rather than dropping …

    line 51
  6. Very specific:

    When a specialist is selected but cannot be dispatched, the record is NOT_CONFIGURED: <reason>, never NOT_APPLICABLE: the panel was short a …

    line 52
  7. Very specific:

    Run it when the artifact carries a technical design: kind: tdd, kind: spec, or a side-weight brief, which collapses the PRD and the …

    line 69
  8. Distinctive:

    Run it on round 1 only: on round 2 the value carries forward from round 1 unchanged, because the second model looked at this version once …

    line 71
  9. Very specific:

    no answer within ten minutes: NOT_RUN: timeout after 600s

    line 89
  10. Very specific:

    Read the findings file and the codex file yourself first: the agents returned digests, and a digest is not what the owner dispositions …

    line 101
  11. Very specific:

    Every critical and high finding, from every reviewer and from Codex, goes to the answerer as one batch.

    line 102
  12. Very specific:

    When it says yes, offer the whole batch as "accept every recommendation" before asking per finding.

    line 110
  13. Very specific:

    Never open fixtures/<fixture>/answer-key.md yourself.

    line 114
  14. Very specific:

    Every disposition written this way carries by: autopilot beside owner, and owner is autopilot where no one else carries the fix.

    line 121
  15. Very specific:

    Write each answer into the file the finding came from, the reviewers' or the codex file: disposition, disposition_reason, owner, and …

    line 125
  16. Very specific:

    Never write a disposition nobody gave you, outside the autopilot rule above, where the approved upstream gave it and by: autopilot says so.

    line 129
  17. Distinctive:

    Write into the artifact's front matter, or hand these two values to the stage skill that called you:

    line 133
  18. Very specific:

    Never touch approved, approved_by, or upstream_hashes.

    line 140
  19. Very specific:

    Put the same cross_model_check value into the findings file's header as codex:, which the reviewer left null because layer 4 had not run …

    line 142
  20. Very specific:

    Check that the generalist recorded score: and threshold: in the header, and ask it again if it did not.

    line 144

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

sf-review

Layers 3 and 4 of the review stack: independent review by fresh-context agents, then the Codex cross-model check. You dispatch, you record, and you disposition. You never write a finding yourself and you never edit the artifact under review; fixing what the findings say is the stage skill's job, on the next round.

Call it with one artifact path. When a stage skill called you, hand the two front-matter values back to it; when the engineer called you directly on a path, you are the caller and you write them yourself.

1. Refuse early

Read the artifact's front matter for kind, version, and weight, and read specfactory.config.yaml for answerer, fixture, and codex_model.

Stop and return the reason if any of these holds:

  • python ${CLAUDE_PLUGIN_ROOT}/scripts/sf_lint.py <artifact> --root . reports an ERROR. Layer 1 comes first, so mechanical defects never consume reviewer time. Return NOT_RUN: lint is not clean.
  • A stage skill called you and has not scored the artifact against ${CLAUDE_PLUGIN_ROOT}/rubrics/<kind>.md and fixed every 0. That is layer 2 and it is the caller's, not yours. Return NOT_RUN: the artifact has not been self-scored. Layer 2 leaves no record on disk, so when you were called directly on a path you cannot check it: do not guess and do not refuse, and say in the digest that the self-score was assumed rather than verified.
  • reviews/<basename>-v<version>-findings.md exists with round: 2 in its header. Rounds are capped at two per version. Put parked: "two review rounds exhausted" in that file's YAML header, return PARKED: two review rounds exhausted, and leave the artifact draft for the human to decide. The header is where it goes, because prose above an unfenced findings list would stop the file parsing.

The findings file is reviews/<basename>-v<version>-findings.md, where <basename> is the artifact file's name without its extension. The round is 1 when no findings file exists for this version, and 2 when one does. A findings file always carries the version it reviewed, in its name and in its header: re-drafting an artifact to a new version means a new review and a new file, never an edited old one, because a findings file whose version was rewritten claims a review that never happened.

2. Dispatch the panel

Panel size scales with the declared weight.

WeightPanel
sideindependent-reviewer, plus traceability-reviewer on a spec
standardindependent-reviewer plus the specialists for the kind
enterpriseindependent-reviewer plus every specialist that applies to the kind

The specialists for the kind:

KindSpecialists
tddsecurity-reviewer
uxux-reviewer
prdux-reviewer
spectraceability-reviewer, and security-reviewer too when the spec touches data, authentication, or privacy
brief, idea, adrnone

traceability-reviewer joins the panel on a spec at every weight, side included, because a side-weight spec drifts from its brief the same way a standard one drifts from its PRD.

When the kind and weight select no specialist, record NOT_APPLICABLE: no specialist for this artifact in the digest rather than dropping the fact. When a specialist is selected but cannot be dispatched, the record is NOT_CONFIGURED: <reason>, never NOT_APPLICABLE: the panel was short a member, and a check that did not happen is never a pass.

Dispatch them one at a time, never in parallel: they share one findings file, and the generalist creates it before a specialist appends to it. Each prompt carries only the artifact path, its upstream paths from upstream:, ${CLAUDE_PLUGIN_ROOT}/rubrics/<kind>.md, ${CLAUDE_PLUGIN_ROOT}/reviews/FORMAT.md, the findings path to write, and the round. traceability-reviewer also gets the upstream PRD, or the brief at side weight, the TDD and every ADR it names, and docs/factory/traceability.md when it exists. Nothing from the drafting conversation goes into that prompt. Each agent returns a digest; the findings stay on disk, so the drafting context never fills with them.

A reshaped spec, one whose front matter carries reshape: at the version after from_version, gets one seat instead of the panel: fidelity-reviewer, whose prompt also carries the approved copy at the record's before: path. Its cross_model_check is NOT_APPLICABLE: a reshape; lint proves the contract unchanged and the fidelity reviewer compares the text, and its round 2, when asked for, is fidelity-reviewer again.

Round 2 is the generalist alone, whatever the weight and whatever the kind. The specialists looked at this version on round 1 and their findings and dispositions are in the file; a second round exists to confirm that the accepted findings were fixed, not to review the artifact afresh, and it costs the owner another disposition wait, so it is dispatched only when the stage skill asks for it. Tell the generalist that a round-1 file exists: it keeps the round-1 findings and their dispositions, sets the header's round to 2, checks each accepted finding against the artifact, and appends only what is still wrong.

3. The cross-model check

Run it when the artifact carries a technical design: kind: tdd, kind: spec, or a side-weight brief, which collapses the PRD and the technical design into itself. For every other artifact the value is NOT_APPLICABLE: <kind> is not a technical artifact. Run it on round 1 only: on round 2 the value carries forward from round 1 unchanged, because the second model looked at this version once and a fix the generalist confirms is not a new document.

python ${CLAUDE_PLUGIN_ROOT}/scripts/sf_codex.py --artifact <artifact> --round <round> --root .

The wrapper runs the reconciled command below against Codex CLI 0.151.0, reads the answer back as a findings file, and prints the value the artifact's cross_model_check takes: the path of reviews/<basename>-v<version>-codex.md when the check ran, or a NOT_* word with its reason.

codex exec --sandbox read-only --model <codex_model> --cd <root> --skip-git-repo-check \
  --output-last-message reviews/<basename>-v<version>-codex.md \
  "Read <artifact> and ${CLAUDE_PLUGIN_ROOT}/rubrics/<kind>.md. Report gaps that affect correctness or the stated requirements as YAML findings in the format in ${CLAUDE_PLUGIN_ROOT}/reviews/FORMAT.md. Do not rewrite the document. Output nothing but the YAML list of findings."

The wrapper degrades rather than failing, and every outcome is recorded honestly:

  • binary absent, or codex login status non-zero: NOT_RUN: not available
  • non-zero exit, including a model name Codex does not know: NOT_RUN: exit status <n>
  • no answer within ten minutes: NOT_RUN: timeout after 600s
  • an answer that will not parse as findings: retried once with the format reminder appended, then NOT_RUN: unparseable output, with the raw answer kept in the codex file
  • no codex_model in the config: NOT_CONFIGURED: specfactory.config.yaml has no codex_model

None of these blocks reviewed, and none of them is a pass. They show in the chain table and in the approval prompt, so the human approves knowing the second model did not look. Agreement between two models is supporting evidence, never proof.

Codex findings go into the same disposition batch as the reviewers' findings, from the codex file.

4. Disposition the critical and high findings

Read the findings file and the codex file yourself first: the agents returned digests, and a digest is not what the owner dispositions against. Every critical and high finding, from every reviewer and from Codex, goes to the answerer as one batch. Print the batch in the session before asking anything, numbered, each finding in full: its id, its severity, and its finding, evidence, impact, and recommendation verbatim from the file. The owner is deciding what gets built from that text, and a one-line summary with the substance left on disk makes them open the file or guess; an owner driving this as an agent never opens the file. Then ask, per finding, accept, reject with a reason, or defer with an owner as the options and a recommendation first. medium and low findings are recorded and left; they never block approval, and the digest lists each medium in one line so the owner knows it exists.

answerer: human: ask with the question tool this harness provides, in as few calls as the tool allows, each question's text carrying the finding's id, severity, finding, and recommendation verbatim, per sf-grill's Question format, so the owner decides from the question text alone and never from a number that maps back to a message printed above; the options are accept, reject with a reason, and defer with an owner. Never "finding 3" and never a free-text "reply with your dispositions". The disposition batch is a batch under sf-grill's Fast track section, so run python ${CLAUDE_PLUGIN_ROOT}/scripts/sf_agreement.py --root . first. When it says yes, offer the whole batch as "accept every recommendation" before asking per finding. A finding accepted that way carries disposition: accepted and disposition_reason: accepted by fast track.

answerer: simulated: dispatch the stakeholder-sim role in fresh context (the ${CLAUDE_PLUGIN_ROOT}/agents/ file of that name is its Claude Code binding) once with the batch, exactly as an interview round. Never open fixtures/<fixture>/answer-key.md yourself; the sim is the only reader of the owner's mind, and the key's dispositions block reaches you through its answers. A finding the sim does not cover takes disposition: accepted with disposition_reason: accepted by default in a simulated run; the fixture answer key held no disposition, so an unattended run never waits on a human.

Autopilot, a spec reviewed inside sf-spec's Autopilot section and nothing else: nobody is asked, and you disposition every critical and high finding yourself against the approved upstream.

  • A fix that stays inside what the PRD, TDD and ADRs already say: accepted, and you make it.
  • A fix that would change what the PRD or TDD says: deferred, owner owner, target the upstream artifact, and a draft change proposal under docs/factory/changes/ carries it; the packet puts it to the owner.
  • A finding the upstream contradicts: rejected, with the reason quoting the line that contradicts it. Every disposition written this way carries by: autopilot beside owner, and owner is autopilot where no one else carries the fix. sf_packet.py lists every rejection and deferral carrying it, so the owner can overturn any of them in one sitting, and sf_agreement.py never counts it as the owner agreeing. Medium and low findings stay recorded and left, as above.

Write each answer into the file the finding came from, the reviewers' or the codex file: disposition, disposition_reason, owner, and target_artifact. sf_status.py, sf_lint.py, and sf_approve.py read both files, so a critical or high finding left open in either one keeps the artifact draft. owner is the answerer, fixture:<name> in a simulated run, unless the answer names someone else. target_artifact is the artifact reviewed unless the answer names another document. Never write a disposition nobody gave you, outside the autopilot rule above, where the approved upstream gave it and by: autopilot says so.

5. Record and return

Write into the artifact's front matter, or hand these two values to the stage skill that called you:

review: reviews/<basename>-v<version>-findings.md
cross_model_check: <the value ${CLAUDE_PLUGIN_ROOT}/scripts/sf_codex.py printed>

Never touch approved, approved_by, or upstream_hashes.

Put the same cross_model_check value into the findings file's header as codex:, which the reviewer left null because layer 4 had not run when it wrote.

Check that the generalist recorded score: and threshold: in the header, and ask it again if it did not; sf_status.py and sf_approve.py show them to the human. A reshape's fidelity review records no score, because it compares rather than scores.

Then run python ${CLAUDE_PLUGIN_ROOT}/scripts/sf_lint.py <artifact> --root . once more and report the digest: the rubric score against its threshold, the counts by severity across both files, every critical and high finding as its id, severity, one-line finding and disposition, every medium as one line, and the cross_model_check value verbatim. The digest is what the owner reads in the session and the file is the record; nothing critical or high may be in the file and absent from the digest. Say plainly whether the artifact is now reviewed, which of the accepted findings the stage skill has to fix, and whether round 2 is owed: it is when an accepted finding is critical or when the owner asks for a second look, and otherwise the version is done once the fixes are in and lint is clean. A score below the threshold is not a refusal: say so in the digest, and the stage skill decides whether a round remains. An accepted finding is not a refusal either. reviewed asks that every critical and high be dispositioned, not that every one be fixed, so when nothing critical or high is undispositioned and lint is clean, say the artifact is reviewed whatever it scored, and name the accepted findings that are still owed as work for a later version rather than a bar to this one. A panel that returns new high findings every round, which a good panel on a substantial artifact does, otherwise makes the artifact permanently unapprovable.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.