Sno Station
Sno Station은 AI 에이전트를 하나의 팀으로 묶는 오픈소스 워크스테이션으로, 로컬 머신에서 에이전트 협업을 가능하게 함
Claude Code가 작성한 코드를 검토하고, 변경 전후 10가지 질문과 검증을 통해 버그를 사전에 수정
Rules and checks that make Claude Code look around a change, not just at the lines it writes: ten questions before code, a reviewer that didn't write it, proof before done, bugs fixed as a class.
플러그인JavaScriptGitHub @joetawil7직접 설치운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
설치형 프로젝트는 배포 도메인 없이도 확인할 수 있습니다. 개인 저장소는 GitHub 로그인으로, 조직 저장소는 위의 저장소 확인 파일로 직접 확인해 주세요.
메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗first-pass makes a coding agent check the code around a change, not only the lines it writes, and prove its work before it calls anything done. It's a Claude Code plugin; Cursor, Codex and other agents get the same rules and skills (the hooks are Claude Code only). You set it up once, in the folder that holds your repos.
What it does
file:line, a test, or a gap you decide to accept./first-pass:hulk lifts the
scope for one task, so it looks everywhere./first-pass:quick, the checks the change can affect); anything less is reported as built, not done./first-pass:review checks your own branch before you ask for
review, or a teammate's PRs across several repos. Every finding comes with its proof or
is marked unproven, and it never posts to GitHub. /first-pass:review hulk <what> reviews
with the scope lifted, so it looks everywhere.What it helps with
/plugin marketplace add joetawil7/first-pass
/plugin install first-pass@first-pass
Then, in the folder where you start your sessions: /first-pass:setup-first-pass.
I built a product feature by feature with Claude Code. Every feature request ended with some version of "make sure the code is correct and bug free, cover all gaps, be 100% sure." Then I ran a full audit. It found 318 issues, 25 of them high severity.
When I sorted them, only 45 were mistakes in the lines being written. The rest were in the code around those lines:
| What went wrong | Issues |
|---|---|
| Another code path using the same data was not updated | 54 |
| Runs twice, runs at the same time, or stops halfway | 54 |
| An outside service fails or is slow, and the error is hidden | 45 |
| A plain mistake in the code itself | 45 |
| Time, units, rounding | 26 |
| Scale: no limit, no index, lists that stop at one page | 25 |
| Endings: cancel, delete, expire, reconnect, downgrade | 19 |
| UI, help, legal or pricing text that says what the code doesn't do | 18 |
| Pipeline: CI red, no tests against a real database | 17 |
| Hostile user or uncapped cost | 15 |
(One private codebase, sorted by hand with one cause per issue. Your mix will differ.)
Several of these had been found by earlier audits and fixed. Each fix patched one spot, and nothing carried the lesson into the next session.
"Be 100% sure" changed how sure the answers sounded. It never made the agent open the other file that writes the same field, or ask what happens when the webhook arrives twice. So first-pass names those checks, and asks for proof before anything is called done:
file:line, a test, or "Not handled, because ___" for you to accept.breaker agent reviews each change in a fresh context, starting from the other
code paths that touch the same data./first-pass:quick, the checks the change can affect). Short of that, it's reported as built, not done.| Piece | What it does | When |
|---|---|---|
premortem | The ten questions, answered against the code | Before code |
breaker (agent) | Fresh-context review of the diff and of every other path touching the same data; concrete findings only | Before done |
ship-check | The definition of done, ending in a report where every "Verified" line says what was run and its result | Before done |
fix-the-class | Reproduce, name the class, search for it in the task's scope (everywhere when your own prompt asks for that fix, not when you pick it from a task's list), run the ten questions on the fix, fix or record each hit, make it hard to repeat | On any bug |
setup-first-pass | Writes the rules once, a map of your repos, and a section per repo with its real commands, test limits and a drafted INVARIANTS.md | Once, then to update |
habit-words | Reads what you typed in your recent sessions and maps words like "be 100% sure" to the checks they should mean | At setup, then when due |
sharpen | Rewrites the prompt you type after it: numbered asks, habit words turned into checks, names and numbers kept exactly. Shows you the rewrite, then works from it | Only when you type it |
review | Reviews your own branch before you ask for review (type nothing after it), or a teammate's PRs, several repos at once. Checks the change against its ticket, judges the failed checks and every Bugbot comment, runs the breaker, traces the other code that uses what changed, proves each finding or marks it unproven, and says what the merge needs and how to check the deploy. Reads GitHub and never posts; pushes a fix only on your yes | Only when you type it |
jev | Sets up the optional Jev judge (TypeSafe's decision model), which ship-check asks whether a review finding is real harm, which small ones to fix now, and what proof a small fix needs | Only when you type it |
hulk | Lifts the task's scope for one task: searches, reviews and bug hunts go across the whole codebase, and problems found anywhere are handled as usual (for a pull request: /first-pass:review hulk <what>) | Only when you type it |
A lot of us open one folder with every repo in it and start each session there. Claude Code
then finds agents, skills and hooks only in that folder and above it: a repo's own
.claude/agents, its .claude/settings.json hooks and its .cursor/rules/*.mdc imports
never load, and its CLAUDE.md loads only once a file in it is read. first-pass is built for
that:
AGENTS.md (imported by CLAUDE.md), loaded from
the first message and updated in one place.Most of us have words we type out of habit: "be 100% sure", "don't assume", "full review", "all fine, right?". They name no place to look, so the answer sounds more certain without anything more being checked.
habit-words reads what you typed in your last 20 Claude Code sessions, shows how often you
use each phrase, what went wrong after it, and what to say instead. Then it writes a short
block that maps each phrase to the checks it should trigger. You never have to type them
again, and if you do, they mean the checks, not a more confident tone.
What it reads and keeps:
~/.claude/projects, and only what you typed, plus the end
of the agent's reply before each prompt that pushes back on it. Tool output, pasted text,
notifications and script-started runs are left out.AGENTS.md and CLAUDE.md at the root (the rules and, if you want them, the reply style
and your habit words), and a section in each repo's CLAUDE.md or
AGENTS.md, all between first-pass markers. Outside the markers it adds only import
lines, and it lists each one it adds.~/.claude/CLAUDE.md, in every mode: this machine's answer on
heavy runs (in every project on it, except a server, a worker or an end-to-end or integration
run in a repo with no first-pass section, or whose real-people line says "unknown" or is
missing, which asks first), how a run is bounded and stopped here (a wrapper named there is
the one the parts runner starts each part through in a main folder), and what can look at a UI (browsers,
simulators, emulators, device tools) or is missing for it. It describes your machine only, so it never goes in
a file your teammates share.INVARIANTS.md in each repo (a draft for you to review), .first-pass/workspace.json at
the root, and .claude/cursor-rules/*.md copies where a repo imports .mdc files..first-pass/parts.json in a repo whose CI checks split into parts, for the parts runner, and
the runner's logs, marks and lock files in first-pass-parts in the system temp folder. They
stay there after a run, so you can read them. Delete the folder only when no run is going:
a killed run's leftovers (a file it wrote in the checkout, a test database) are cleaned up by
the next run of that part only while its record is there.~/.claude/plugins/data/ for the hooks, and a temp file while
habit-words runs, deleted when it's done.~/.claude/first-pass/jev.json, only if you set up the Jev judge: which variable holds
your key, and for which repos. Never the key itself.Setup never commits or pushes, and sends nothing anywhere except one test request per key
to TypeSafe if you set up the Jev judge: you review the files and commit them. The plugin's own
scripts make no network calls and read no keys or tokens from your environment (the parts
runner runs your repo's own test commands, reads only the keys its recipe names from your
repo's env file, and checks only that a test server on this machine answers), with one
exception you have to switch on: the Jev judge reads the one key you named and sends review
findings (with secrets, emails and phone numbers blanked) to TypeSafe's API, from
ship-check and jev. Setup's survey reads only the variable names in the example env files
a repo commits (.env.example and the like), never a value and never your real .env. Besides that, the only skill that reaches a server is review: it
reads the PRs, checks and comments through your own gh login, and it pushes a fix only
when you picked that fix and said yes to the push.
/plugin marketplace add joetawil7/first-pass
/plugin install first-pass@first-pass
From a terminal: claude plugin marketplace add joetawil7/first-pass, then
claude plugin install first-pass@first-pass. To update later:
claude plugin marketplace update first-pass, then claude plugin update first-pass@first-pass.
The hooks need Node.js 18 or later on your PATH. The tests run on Windows and Linux.
npx skills add joetawil7/first-pass -a cursor --copy # this project
npx skills add joetawil7/first-pass -a cursor --copy -g # every project
This uses the skills CLI. Swap -a cursor for your
agent (-a codex, -a windsurf, ...). --copy writes real files instead of symlinks,
which Windows checkouts turn into plain text. Don't add -a claude-code if you use the
plugin, or you'll get every skill twice. Other tools get the rules and skills; the hooks are
Claude Code's.
In the folder where your sessions start: /first-pass:setup-first-pass (or
/setup-first-pass outside Claude Code). It looks through your repos, asks only what the
code can't tell it (which repos have a UI, which depend on which, which repo hooks to run),
and writes the files above. Re-run it after an update: your own text, each repo's section and
INVARIANTS.md are kept.
Once a repo's files are committed, every teammate's agent loads its section. Tell setup
which repos people open on their own: those also get the rules and a copy of the breaker.
Each person installs the skills: the plugin for Claude Code, the npx skills line for
Cursor.
ship-check runs the breaker and, while it works, CI's checks in a clean
checkout (in CI's own parts side by side, when the repo has a parts recipe), when your repo's test limits and your machine's limit on heavy runs at once allow both. Nothing is committed to your
branch before the review's result is handled unless you say to ship it as it is, and
nothing is called done before it either way. Then it reports
Verified: <what was run> → <result> and what wasn't verified.fix-the-class fixes the one you found, the others like it, and adds the check
that stops the next one./first-pass:review with nothing after it reviews your
work against its base, its PR, its checks and the ticket in the branch name, and ends
with what to fix before you ask for review. On a teammate's PR, add the links and what's
live, for example "/first-pass:review backend#147 web#151, live today: no agency
workspaces": the same checks, plus a message you can send the developer. Every finding
comes with its proof, or is marked unproven, and says whether users can hit it today. A
PR from a fork or an outside contributor is read, never run, unless you say yes, since
running it would run a stranger's code with your logins. The report also says what
changes for users, what the merge needs (a new app build, env vars, migrations, deploy
order), what to check after the deploy, and which of the ten questions and which
neighboring code were checked. It reads GitHub but never posts, and it fixes something
only when you pick it after the report.Instead of "make sure it's bug free", try: "Run the pre-mortem, show me the tests that fail without the change, and list what you didn't verify."
Or write the prompt the way you would anyway and put /first-pass:sharpen in front of it
(/sharpen in Cursor). It splits a message that mixes three asks into a numbered list,
turns the habit words into the checks they stand for, shows you the rewrite, and works from
that. It stops to ask only when it would have to guess, and it never adds work you didn't
ask for. In Claude Code a hook holds back edits, shell commands, subagents, MCP tools,
publishing, scheduling and other skills until the rewrite is on screen (reading files is
never held back): with the
instruction alone, the rewrite was skipped in 7 of my 11 test runs.
If you have a TypeSafe API key, /first-pass:jev turns on a
second opinion for ship-check: Jev, a model that only picks from a list and says how sure
it is, judges whether each review finding is real harm, which small ones are worth fixing
now, and what proof a small fix needs (the checks alone, a unit test, a real-database test
or a browser test). It is cheap and fast, but when I had it sort 269 audit issues it gave
more weight to how many people meet an issue than to how bad the harm is. So it can make a
finding serious, never clear one the reviewer called serious, and when it is unsure or
fails, the rules decide as if it weren't there.
I test a rule the way I'd test code: fresh Claude Code sessions and agents (Opus, high effort) that load nothing else, hidden checks they never see, and judges who read the output blind.
These are small samples on small tasks. They show the rules do what they say, not how much they help on your code.
fix-the-class and then running ship-check used about $29 at API list prices
(three reviewer passes). The trade is fewer rounds after "done". The pre-mortem scales
with the change: a copy tweak answers it in one line. To keep the cost down, a prompt with
several items builds them all first, then reviews them while CI's full checks run in one
clean checkout holding them all. A later fix reruns only the checks it can affect, and the
full checks run once more on the final change: nothing is committed before them unless you
say to ship it as it is, and nothing is called done before they pass. /first-pass:quick
trades the full checks for the ones the change can affect and leaves the rest of the suite
for a full run, such as your pull request's CI. During the work, only serious findings (money, data, something done twice or sent
wrong, security, legal, a crash, stuck work, the change not doing its job) are fixed and
checked again; those only a rare path reaches, found after the first review, are collected
and fixed together in one batch with one review, and a rare one that batch's review or a later
review of the same change finds comes to you first on the list instead of starting another
round; nothing ships until you answer, and the change stays not done while it's unfixed. The smaller ones
come to you once, as one list at the end, and the ones you pick get one review together.
Before this, a reviewer finding a small case, a question to you, a fix and another review
of that fix could chain for hours: in one two-day stretch, about a third of 84 reviews
found only small points, and most of them still started another round.
Questions to you wait until nothing else can move (sharpen and setup still ask before
they start, and a failed commit, push or deploy still stops the work at once): each one stops the session until you
answer, and in three sessions over three days, 17 of 70 sets of questions waited an hour or
more. So the agent first does every part that doesn't depend on your answer, then asks
what's left in one set.fix-the-class pushes toward: a
shared helper that's the only way to do a thing, a database constraint, a CI check.sed -i, a heredoc, a copy, a formatter) is found at the end of the turn, from
git status and the file's time, so the done check and end-of-turn hooks see it; hooks
that run after each edit don't. Not seen: files git ignores; on Windows, a copy
(, ) over a file git showed no change in, which keeps the source's
times; writes from a command still running in the background after it returned; from a
main folder, a repo the command neither runs in, s into nor names a path in; and, in
a single repo, any other repo. Counted anyway: a file rewritten with the same content
(, then ); another program's write or delete while a shell
command runs; and after you refuse a command, writes until your next prompt. A delete is
dated by its folder, so a later change in the same folder can count or hide it.If you try it and it gets in your way, open an issue and tell me where. Reports of a bug that got past all of this are the most useful kind.
quick |
Quick mode, until /first-pass:quick off: instead of CI's full checks, a change runs format, lint, types, build, its own tests and every unit, integration, flow and browser test that reaches what it touched; the rest of the suite is left for a full run, such as your pull request's CI |
| Only when you type it |
| Parts runner | Runs CI's checks on your machine in the parts your repo's .first-pass/parts.json names (setup drafts it from CI): stages in order, a stage's parts side by side, each with its own port, run-named databases and logs, through your memory-capped runner if you named one (with one repo and no main folder, one part at a time inside it). It stops only what it started, and a part that needs another refuses to run until that one passed on the same checkout; --tests gives the steps that take a test list only chosen files, and --no-tests runs a part's other steps without them | When ship-check runs CI's checks |
| Hooks | Run each repo's own hooks from the main folder, send back a "done" with no evidence, say what drifted at session start, and hold sharpen's work until its rewrite is shown | Every session |
Copy-Itemcopycdgit stashgit stash pop