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
- giangdvdotdev/aseprite-mcptheir own version, first seen Jul 30, 2026
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 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.
- AGENTS.mdAGENTS.md
- CLAUDE.mdCLAUDE.md
- specs/CLAUDE.mdCLAUDE.md
- sf-grillSkill
- sf-handoffSkill
- sf-ideaSkill
- sf-improveSkill
- sf-ingestSkill
- sf-prdSkill
- sf-specSkill
- sf-tddSkill
- sf-uxSkill
- specfactorySkill
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
- Distinctive: line 12
Call it with one artifact path.
- Distinctive: line 13
When a stage skill called you, hand the two front-matter values back to it.
- Very specific: line 17
Read the artifact's front matter for kind, version, and weight, and read specfactory.config.yaml for answerer, fixture, and codex_model.
- Distinctive: line 19
Stop and return the reason if any of these holds:
- Very specific: line 51
When the kind and weight select no specialist, record NOT_APPLICABLE: no specialist for this artifact in the digest rather than dropping …
- Very specific: line 52
When a specialist is selected but cannot be dispatched, the record is NOT_CONFIGURED: <reason>, never NOT_APPLICABLE: the panel was short a …
- Very specific: line 69
Run it when the artifact carries a technical design: kind: tdd, kind: spec, or a side-weight brief, which collapses the PRD and the …
- Distinctive: line 71
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 …
- Very specific: line 89
no answer within ten minutes: NOT_RUN: timeout after 600s
- Very specific: line 101
Read the findings file and the codex file yourself first: the agents returned digests, and a digest is not what the owner dispositions …
- Very specific: line 102
Every critical and high finding, from every reviewer and from Codex, goes to the answerer as one batch.
- Very specific: line 110
When it says yes, offer the whole batch as "accept every recommendation" before asking per finding.
- Very specific: line 114
Never open fixtures/<fixture>/answer-key.md yourself.
- Very specific: line 121
Every disposition written this way carries by: autopilot beside owner, and owner is autopilot where no one else carries the fix.
- Very specific: line 125
Write each answer into the file the finding came from, the reviewers' or the codex file: disposition, disposition_reason, owner, and …
- Very specific: line 129
Never write a disposition nobody gave you, outside the autopilot rule above, where the approved upstream gave it and by: autopilot says so.
- Distinctive: line 133
Write into the artifact's front matter, or hand these two values to the stage skill that called you:
- Very specific: line 140
Never touch approved, approved_by, or upstream_hashes.
- Very specific: line 142
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 …
- Very specific: line 144
Check that the generalist recorded score: and threshold: in the header, and ask it again if it did not.
≈ “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.
Files
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 anERROR. Layer 1 comes first, so mechanical defects never consume reviewer time. ReturnNOT_RUN: lint is not clean.- A stage skill called you and has not scored the artifact against
${CLAUDE_PLUGIN_ROOT}/rubrics/<kind>.mdand fixed every 0. That is layer 2 and it is the caller's, not yours. ReturnNOT_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.mdexists withround: 2in its header. Rounds are capped at two per version. Putparked: "two review rounds exhausted"in that file's YAML header, returnPARKED: two review rounds exhausted, and leave the artifactdraftfor 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.
| Weight | Panel |
side | independent-reviewer, plus traceability-reviewer on a spec |
standard | independent-reviewer plus the specialists for the kind |
enterprise | independent-reviewer plus every specialist that applies to the kind |
The specialists for the kind:
| Kind | Specialists |
tdd | security-reviewer |
ux | ux-reviewer |
prd | ux-reviewer |
spec | traceability-reviewer, and security-reviewer too when the spec touches data, authentication, or privacy |
brief, idea, adr | none |
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 statusnon-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_modelin 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, ownerowner, target the upstream artifact, and a draft change proposal underdocs/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 carriesby: autopilotbesideowner, andownerisautopilotwhere no one else carries the fix.sf_packet.pylists every rejection and deferral carrying it, so the owner can overturn any of them in one sitting, andsf_agreement.pynever 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.
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
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.

