skills/prototype-first-wisdom/SKILL.md
Solve a complex bug or design problem by building a tiny isolated prototype first, instead of patching the production system in place. Trigger PROACTIVELY when (1) the same bug has resisted 2+ in-place fix attempts (fail-retry loop), (2) the user mentions "minimal prototype", "from zero", "from scratch", "simple script", "sandbox", "standalone", "isolate", "play around", or "try a sandbox version", (3) you find yourself ranking a list of suspects and ruling them out via source-grep on a runtime/visual bug, (4) the user is brainstorming many design options for a UI surface and wants speed (e.g., "make 20 patterns of the top page"), (5) the next reasonable step would be "instrument the existing complex code" — pause and consider this skill instead. Build the prototype in the repo-scoped Dropbox-synced cclogs dir (`$DROPBOX_CCLOGS_DIR/<repo>/<descriptive-name>/`) so it survives switching between Mac and WSL; the exception is a prototype that must import the repo's production code or use its workspace/Vite tooling — keep that one in `__inbox/<descriptive-name>/` in the project root (in-repo, gitignored) so relative imports resolve. Match the project's tech stack (HTML+CSS+vanilla JS for static sites, Vite+React for React apps, Node script for CLI/utility logic). Don't commit it — its value is the learning, not the artifact. **Variant for repeated regression cycles (8+ in-place fixes on the same bug class):** keep the prototype as a committed sub-package named `packages/prototype-<topic>/` — see the "Variant: project-level reference prototype" section below.
npx skillsauth add takazudo/claude-resources prototype-first-wisdomInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
When work is genuinely complex — a bug that won't die after multiple in-place fixes, a UI surface with too many design options, an investigation that keeps coming back wrong — the right move is not to add another patch on top of the entangled production code. Build the simplest possible thing that exhibits the same problem (or the simplest version of the design space), confirm it works in isolation, then bring the learning back to production.
This skill captures a pattern Takazudo has used twice with strong results — the bezier-tool dev (kept failing in place until a from-scratch prototype landed it) and the 20-design-patterns brainstorm (huge time fixing a built site vs. dramatically faster making 20 fresh layouts). It also fits any situation where source-grep ruling-out is failing on a runtime bug.
Invoke proactively in any of these:
When in doubt: if the next reasonable step would be "instrument the existing complex code with console.log and grep", consider whether building the smallest reproduction outside the app would converge faster.
Two homes for a prototype, chosen by whether it needs the repo's own code:
Standalone / rough-design prototype (separated concern — design exploration, isolated math, a canvas/shader sandbox, a repro that hard-codes its inputs rather than importing production functions) → build it in the repo-scoped Dropbox cclogs dir:
PROTO_DIR=$(node "$HOME/.claude/scripts/get-logdir.js")/<descriptive-name> # …/Dropbox/cclogs/<repo>/<name>/
mkdir -p "$PROTO_DIR"
This dir is Dropbox-synced, so a prototype you build on Mac is there when you switch to WSL (and vice versa) — the whole point. It lives outside the repo, so nothing to gitignore.
Prototype that must import the repo's production code or use its workspace/Vite tooling → build it in-repo under __inbox/<descriptive-name>/ so relative imports and the project's tooling resolve:
mkdir -p __inbox/<descriptive-name>
__inbox/ is in-repo and should be (or become) gitignored — see "Gitignore check" below. This is the only case that still uses __inbox/; default to the cclogs dir otherwise.
Use a name that's specific to the task: repro-image-drift/, top-page-layouts/, bezier-pen-math/. Future-you will thank present-you.
The prototype should match the production project's tech stack closely enough that the learning transfers, but not so closely that you re-import all the entanglement.
| Project type | Prototype form |
|---|---|
| Static site / vanilla web | index.html + style.css + script.js — open in a browser |
| React + Vite app | A new mini Vite app in <prototype-dir>/ (pnpm create vite), or a single .html with React via CDN if you want to skip the build step |
| Next.js app | Same as React+Vite — Vite playground is faster than booting another Next.js project |
| Node CLI / utility | A standalone .mjs script — node <prototype-dir>/repro.mjs |
| Backend handler / API logic | A standalone .mjs that imports the production function and calls it with hard-coded inputs |
| Canvas / visual | HTML + canvas + script. If the production app uses React, you can skip React in the prototype if the bug is in the canvas layer itself |
| GLSL / shader | A single .html with the shader inline + a uniform-tweaking UI |
The rule of thumb: match the part of the stack that touches the bug, drop everything else. If the bug is in coord-conversion math, your prototype only needs the math. If the bug is in React render timing, your prototype needs React + a minimal component but no router / no global state / no external services.
For bugs:
console.log (browser).For design exploration:
For Node: node <prototype-dir>/repro.mjs. Read stdout.
For HTML/Vite: open in a browser, read DevTools console + visual.
If the prototype reproduces the bug → root cause is in what you imported (the production functions). Move to instrumenting the prototype, not production. Iteration is now fast.
If the prototype's output is correct → bug is not in the imported layer; it's in the production orchestration around it (state machinery, refs, effects, paint pipeline). Escalate: extend the prototype to include the next layer of complexity, or build a component-level test that exercises the orchestration.
For design exploration: pick the variants that work, port the chosen patterns to production. Discard the rest.
Once the prototype tells you what's wrong:
The prototype is throwaway — its value is the learning it produced, not the artifact. A prototype in the cclogs dir lives outside the repo, so there's nothing to commit or gitignore; an __inbox/ prototype is in-repo and should be gitignored (see "Gitignore check" below).
If the user explicitly asks to keep an in-repo prototype, fine — move it out of __inbox/ to a permanent location and commit that. But default to don't commit.
When you finish the work and report back to the user, mention where the prototype lives in case they want to look. Example: "Prototype that reproduced the bug: $DROPBOX_CCLOGS_DIR/<repo>/repro-image-drift/repro.mjs" (or the __inbox/... path if it was an in-repo prototype).
Only relevant when you took the in-repo __inbox/ path (a standalone prototype in the cclogs dir lives outside the repo — skip this). Before creating __inbox/<name>/, ensure __inbox/ is gitignored. If the project has a CLAUDE.md or contributor guide, it likely already documents this convention. Otherwise:
grep -Fxq "__inbox/" .gitignore 2>/dev/null || echo "__inbox/" >> .gitignore
For projects that don't already use __inbox/, double-check with the user before adding it to .gitignore — some projects use a different ephemeral-scratch convention (tmp/, scratch/, .local/).
packages/prototype-<topic>/The default pattern is throwaway — build in the cclogs dir (or __inbox/ when it needs the repo's code), don't commit, learning lives in your head and in the production fix. But there is one case where the prototype should be kept as a committed sub-package:
Trigger: the same bug class has resisted many (typically 8+) in-place fix cycles. Each cycle ships CI-green, each cycle's reviewer can't see the bug from source alone, each cycle's user can. At that point, the throwaway pattern is no longer enough — you need a permanent canonical reference that future waves of diagnosis can diff production against.
This is a second-order escalation. Default to throwaway. Only escalate to a sub-package prototype when the throwaway approach has itself failed to break the cycle (i.e., you tried in-place fixes, you tried throwaway prototypes, and the bug class keeps coming back).
In a monorepo / workspace project: packages/prototype-<topic>/. The packages/prototype- prefix is the convention — it makes the directory's purpose immediately obvious to anyone scanning the repo: this is a prototype, not production, not a library.
Examples:
packages/prototype-canvas/ — for a canvas pan/zoom + coordinate-system bug classpackages/prototype-clipping/ — if a follow-up bug isolates to rect clipping on top of canvaspackages/prototype-undo-redo/ — for an undo-state-divergence bug classEach prototype proves exactly one axis of the production system's complexity. When production is found to deviate from the prototype's behavior on that axis, you've localized the bug.
Match the production app's tech (Vite + React for a React app, plain HTML+canvas if the production app's bug lives in the canvas layer below React, etc.). Include:
coordinate-model.md (or equivalent spec doc) that names the canonical invariants this prototype proves. Future planning agents read this to understand "what does this prototype claim to be true?"By default, prototype demos stay local-only — pnpm <prototype>:dev runs them when someone wants to inspect, and that's enough. Don't wire them into CI preview deploys, don't add them to pr-checks.yml's deploy table, don't waste CI minutes building them on every PR.
The exceptions:
/canvas-fix-app/ so I can check it on each iteration." Honor the request.When in doubt: don't deploy. Adding a CI deploy is cheap; reverting one quietly is harder.
Unlike the throwaway variant, this prototype is part of the codebase. It is committed, lives at HEAD, and is maintained as production migrates to match its invariants. Future waves (diagnosis, fixes, confirm walks) read it as the canonical reference.
When all bug-class waves are complete and production has structurally adopted the prototype's model, the prototype can either (a) stay as a permanent regression-test playground, or (b) be removed if its invariants are now enforced by production tests. Default to (a) until the user says otherwise.
When this skill triggers and the project shows the high-cycle escalation signal (8+ cycles, monorepo, l-lessons-* skill with a "this bug class is back" entry), build the sub-package prototype. When in doubt, ask the user — single-cycle throwaway is the safer default; over-engineering a permanent prototype for a bug class you've only seen once wastes effort.
/headless-browser / /verify-ui) still catches things stdout can't (computed style, paint pipeline, real RAF). Prototype-first works with browser-first, not instead of it.Tried fixing in place repeatedly; geometry kept being wrong. Built a from-scratch minimal bezier-pen prototype as standalone HTML+canvas+JS in the repo-scoped cclogs dir (standalone — no production imports needed). Got the math right in isolation. Brought the corrected math back to production. Bug landed.
User asked for 20 top-page design variants on a built website. Trying to make the live site render 20 variants would have been huge time. Instead made 20 fresh standalone HTML files, each its own design. Much faster, user picked the winners, those got ported to production.
PR-1530 then PR-1537 both shipped fixes that didn't actually fix the user-visible bug because the diagnosis was source-grep-based. Round-2 plan switched to: build a Node script under __inbox/repro-1533-r2/ (in-repo, because it imports the production conversion functions — the cclogs exception) that calls those functions with hard-coded user-repro inputs, logs intermediates, asserts the expected transform. Either the script reproduces the bug (math is wrong → fix the math) or it doesn't (math is innocent → escalate to component-level test for orchestration).
Ask: "If I imagine running a 50-line script that hard-codes the inputs and calls the production function — would that script fail?"
/headless-browser or component-level test instead. Prototype-first won't help; verification-first will.development
Link Claude Code skill names mentioned in a CodeGrid article (data/{series}/{n}.md) to the author's public claude-resources repo, pinned to the latest commit hash so links don't rot. Use when: (1) user says 'linkify cc resources', 'link the skills', 'link skill names', or invokes /dev-linkify-cc-resources; (2) editing a CodeGrid article that mentions `/commits`, `/pr-complete`, `/skill-creator` or other Claude Code skills and they should point to claude-resources. Only links skills that actually exist in the public repo; skips hypothetical examples and code blocks.
development
Second opinion from Claude Opus on a plan or approach. Use when: (1) Planning phase of /big-plan needs a higher-quality review than /codex-2nd / /gco-2nd / /gcoc-2nd, (2) User says 'opus 2nd' or 'opus opinion', (3) Wanting Anthropic's larger model to critique a plan. Spawns a general-purpose Agent with model: opus that reads the plan file and returns structured feedback. Anthropic quota — not free.
tools
AI-based testing via subagent + a per-task test-flow skill. Use when the user wants to verify something that mechanical assertions can't fully capture — image recognition, visual size/position comparison, animation smoothness, multi-step manual flows that need AI judgment. Triggers: 'AI-based test', 'AI test', 'visual verify', 'image recognition test', 'manual operation test', 'human-eye check', 'verify visually', 'compare screenshots', 'looks the same', 'looks correct'. The skill's job is to (1) author a focused test-flow skill that captures the exact procedure + verdict criteria, then (2) dispatch a verification subagent via the Agent tool that loads BOTH the test-flow skill AND a browser-driving skill (/verify-ui primary, /headless-browser fallback) so the subagent has clear context and consistent verdicts. NEVER uses `claude -p` — subagent dispatch goes through the Agent tool exclusively.
development
End-of-workflow audit of touched GitHub issues, PRs, and branches via a Sonnet subagent. Use when: (1) /big-plan, /x-as-pr, or /x-wt-teams finishes its main work and needs to verify every touched resource is in the right state (closed when done, kept when ongoing, deleted when dead), (2) User says 'cleanup resources', 'audit cleanup', or 'check what should be closed', (3) A long workflow ends and the manager wants a structured paper trail of what it closed/kept/deleted. Auto-execute by default — the Sonnet agent proposes, the manager (you) executes safe actions and prints a final report.