Setup
Stay present with AI. A Claude Code plugin that keeps you understanding what you sign to own.
npx -y skills add saadshahd/moo.md --skill setupAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
What its author says it does
Copied from the file, not written here
Use when installing or refreshing sound taste rules in a project — an explicit "sound setup", starting work in a repo with no .claude/sound/, or a taste-not-defined nudge. Also use to re-run after a stack change (new framework, new package in a monorepo).
SKILL.md
7.9 KB, as published. Nobody here has run it
sound:setup
Scaffold a project's taste rules from the sound corpus: probe the stack, select ONLY rules whose subject the repo's code actually shows — evidence-cited per rule, never a tag-wide dump — confirm with the user, then install each confirmed rule's corpus prose verbatim. Each rule lands as a plain reference file in .claude/sound/<topic>/ — the tree sound:prime points at. Written files belong to the user; re-runs reconcile (see Re-runs).
Corpus: ../../corpus/ relative to this SKILL.md — the candidate universe, laid out as <topic>/<rule>.md: the directory is the rule's topic, the file is the pure rule body — no frontmatter, no metadata. Sibling ../../corpus-optin/ (same layout) holds opt-in rules, excluded from candidacy unless the user names one at invocation (Phase 2). If corpus/ is missing or unreadable, STOP and say so — never install a partial set silently.
Phase 1 — Probe
Decide which kind-tags apply (react, db, distributed) — verified STACK FACTS that anchor Phase 2's per-rule judgment and are presented at Confirm, not a filter that earns any rule an install.
Usage decides; manifest presence only says where to look. Verify every hint at its USE sites in source before proposing a tag — deps can be dead weight, hoisted, or tooling-only. Negatives need the same rigor: a client's config/wrapper file never clears a dep; search its use sites (.publish(, .send(, .create(…) before ruling a tag out. Read every package.json (root + workspaces) and workspace markers (pnpm-workspace.yaml, turbo.json) → hypotheses → verify each in source. Note TS / pure-JS / neither: it sets the TS-only veto (Phase 2) and the no-JS/TS abort (Failure modes).
| Tag | Fires on (verified usage) | Does NOT fire on |
|---|---|---|
react | .tsx/.jsx files, JSX or react imports in real source | react in deps with zero usage; react-shaped tooling (ink absent too) |
db | a db client or ORM imported in source, whichever one; redis-as-store; EMBEDDED dbs with owned DDL/schema (sqlite, node:sqlite, level — in-process still counts); owned schema/migration files | consuming someone else's hosted API without owning storage |
distributed | any SIDE-EFFECTFUL remote boundary: payments, email/SMS, queue/broker publish, webhook handlers, bot messaging SDKs, multiple owned services reconciling state. FRAMEWORK-WRAPPED senders count: an auth provider configured with an SMTP transport, e.g. next-auth EmailProvider, IS email-sending usage even with no direct nodemailer import. Publisher-side evidence alone is SUFFICIENT — the consumer usually lives outside the repo | READ-ONLY consumption of remote APIs (fetch-and-render); analytics beacons; redis as a plain same-process cache (get/set/del only) |
Phase 2 — Select (per rule, evidence-cited)
Candidates = the ENTIRE corpus/. There is no tag pre-filter — each rule's own subject-surface gate below is the selection; the Phase 1 facts are the evidence it judges against.
Opt-in gate (deterministic). The candidate universe is corpus/ ONLY. A corpus-optin/ rule enters candidacy solely when the user names it at invocation — then read it from corpus-optin/. Directory membership is the gate; a default run never proposes an opt-in rule.
A candidate installs iff the repo contains the SUBJECT-SURFACE the rule governs — code where the rule's Detect: question is askable — cited as ONE FILE path (never a directory, never a glob). The rule's Not-when: can veto. No citation, no install. An actual violation is NOT required (rules are prevention) and its absence never vetoes. Existing COMPLIANCE is evidence FOR install: a repo already doing the mandated shape has the surface.
A fired tag earns NOTHING by itself — each rule's OWN Detect question must be askable at the cited file. A repo that publishes to Redis does not thereby get every distributed rule: with no replicas, no supervised queue, no versioned concurrent writes, the fold/restart-policy/write-conflict rules are skipped, each with its reason.
- Subject-bearing rule:
command-vs-fact-when-reconciled-elsewhereinstalls iff the repo has async-reconciled state (a server ack, a queue, a webhook-confirmed flow) — cite the file. A repo that names no events does not get the event-naming rules. - Universal-subject rule (subject is "any code": naming, transformation shape, comments, function design): passes trivially — cite any substantive source file. Never manufacture deeper evidence.
- A rule whose mandated shape requires TypeScript (casts, branded types,
satisfies, compile-time exhaustiveness) never installs in a pure-JS repo. - Candidacy does NOT mean universal-subject: command/event-naming, intent-vs-fact splits, and ledger rules are candidates like everything else but subject-bearing — they need their surface (a named event vocabulary, state reconciled elsewhere, an append-only store).
- Test-scoped rule: its subject is the CODE UNDER TEST, never test-file presence — a zero-test repo with testable logic still earns the general testing rules (cite the testable code). Test rules with a more specific shape (roundtrip laws need encode/decode pairs; property generators need domain invariants) still need THAT shape cited.
- Every rejected candidate gets a one-line reason, surfaced at Confirm.
Method — DEEP by design; spend the tokens. Every candidate rule is judged against its own full text and the real repo, returning per-rule install + citation or skip + reason. Batching rules that look at the same code across subagents buys parallelism on a large repo; a narrow surface is better served inline — the output SET is what's judged, not the mechanism.
Phase 3 — Confirm (never skip, never auto-install)
Present compactly: the extracted facts (each with file evidence), the proposed tag set, and the proposed rule set — each rule as name + citation + its one-line statement (never name-only; the user must see what each rule requires) — plus the rejected candidates grouped with their reasons. The statement is the rule's opening mandate: the file's first sentence, extended to the next only when the first merely scopes or defines without stating the mandate (e.g. derive-dont-sync, module-is-the-noun-functions-are-bare-verbs). Never _Avoid_, Detect:, or Not-when:. The user's answer is the verdict — a corrected set replaces yours without argument; redo the affected phases. Write only after explicit confirmation. The user confirms the SET here; the written files are theirs afterward.
Propose-only mode: if the invocation asks for a proposal only (evals, dry runs), read propose-only.md and follow it instead of confirming or writing.
Phase 4 — Write
Copy each confirmed rule's file verbatim — no additions — to .claude/sound/<topic>/<rule-name>.md, a plain reference file. <topic> is the rule's parent directory in the corpus. These live OUTSIDE .claude/rules/, so they never auto-load; the browsable .claude/sound/ tree IS the map sound:prime points at. No marker, manifest, or hash anywhere.
Re-runs
If .claude/sound/ already exists, read re-runs.md before writing anything — existing files are user-owned and are reconciled, never overwritten.
Failure modes to keep loud
- Corpus unreachable / rule file unparseable → stop before writing anything.
- User declines all tags → Phase 2 still runs over the full corpus; rules whose surface lives behind a declined tag are skipped with that reason. Say that's what happened.
- Repo has no JS/TS at all → the corpus doesn't apply; say so and install nothing.
- A selected rule with no citable evidence is a selection BUG — drop it and say so, never install on vibes.