Karpathy-skills CLAUDE.md v2 — extending forrestchang's pattern with lessons from building draftcat
Karpathy-skills CLAUDE.md v2 — extending forrestchang's pattern with lessons from building draftcat
Karpathy-skills CLAUDE.md v2 — extending forrestchang's pattern with lessons from building draftcat
Karpathy-skills CLAUDE.md v2 — extending forrestchang's pattern with lessons from building draftcat
Karpathy-skills CLAUDE.md v2 — extending forrestchang's pattern with lessons from building draftcat
Updated 2026-04-22 — ten rules for Claude Code: four for edit-time, six for runtime.
Forrestchang's andrej-karpathy-skills CLAUDE.md is four rules aimed at the moment Claude is writing code. They work. What they don't cover is the moment Claude is running. Once a Claude-driven pipeline goes to production, a different failure mode shows up: confident outputs, silent budget overruns, destructive side-effects, prompt injection via user input.
These six extension rules are what I shipped into draftcat — a Go pipeline engine where Claude drafts, classifies, and summarizes, but never executes. Deterministic code does. The rules below are what made that claim stick.
Merge with your own project rules. Tradeoff: these bias toward caution over autonomy.
- Think Before Coding — state assumptions, surface tradeoffs, ask when unclear.
- Simplicity First — minimum code, no speculative abstractions.
- Surgical Changes — touch only what the task requires.
- Goal-Driven Execution — define success criteria, loop until verified.
(Full text: forrestchang/andrej-karpathy-skills/CLAUDE.md.)
Claude is for judgment calls. Plain code does everything else.
Fetching, filtering, routing, persisting, dispatching — none of it is a language task. Don't ask the model to "decide if we should retry" when a status code already answers. Use the model for: classification, drafting, summarization, extraction from unstructured text. That's the whole list.
The failure mode without this rule: the model makes a routing decision one week, a different routing decision the next, and you've reinvented flaky if-else at $0.003/token.
No silent overruns. Ever.
Every AI step runs under a token budget: per-step, per-pipeline, per-day. Exceeding any of the three halts the pipeline immediately, logs the breach, and surfaces it to the operator. Budgets live in config, not in prompts.
budgets:
per_step_tokens: 2048
per_pipeline_tokens: 10000
per_day_tokens: 100000The failure mode without this rule: a runaway loop burns $40 overnight and you find out from the invoice.
Label destructive actions. Require approval. No exceptions via flags.
Anything touching the outside world — sending an email, updating a CRM, posting a message — is an approval step, not an ai step. The approval is routed to an operator channel (Slack, Telegram, whatever) with approve/edit/reject controls. The pipeline blocks until a decision is recorded.
- name: approve-send
type: approval
mode: hitl
channel: telegramThe failure mode without this rule: a hallucinated follow-up email goes to a real customer.
Unstructured strings don't belong in deterministic downstream code.
Every AI step declares an output schema. The runtime rejects anything that doesn't match — missing fields, wrong types, out-of-range numbers. Rejected outputs trigger a retry (under budget) or halt.
output_schema:
type: object
required: [match, reason, score]
properties:
match: { type: boolean }
reason: { type: string, maxLength: 280 }
score: { type: integer, minimum: 0, maximum: 100 }The failure mode without this rule: a boolean comes back as the string "maybe" and a downstream if branches the wrong way.
For generated React and Next.js code, I use agentproof-react as a small deterministic review gate before shipping.
User-supplied text is not trusted.
Before any operator or external input enters a prompt, strip role markers (system:, assistant:, <|im_start|> variants), enforce length limits, and normalize markdown so formatting can't break prompt boundaries. This is prompt-injection defense, not input validation — the goal is to stop an attacker from pivoting the model mid-run.
Don't narrate to the attacker.
When input is rejected for sanitization or schema violations, log internally — never echo the rejection reason back to the source. A detailed error message is a free signal that tells the attacker which pattern to try next.
The full ten rules are working if:
- Diffs are smaller and more targeted (rules 1–4).
- Pipeline runs have predictable token costs (rule 6).
- No AI output ever reaches a production side-effect without a human approval record (rule 7).
- Downstream code never branches on a malformed AI response (rule 8).
- Operator-channel logs show silent rejections rather than echoed errors (rules 9–10).
If even one of those is failing, the rule isn't enforced — it's aspirational.
- Retrieval that degrades instead of failing (PAAN #16) — what recall does when the embedding provider is unreachable: two independent branches, RRF merge, and a
degradedflag so the agent knows it answered from a partial corpus. Reference repo: agentic-task-system. - Claude Code persistent memory between sessions — your task manager as agent memory via MCP (PAAN #3) — memory that survives session restarts and compaction because it never lived in the context window: hybrid RRF retrieval over TickTick or an Obsidian vault, with provenance. Reference repo: agentic-task-system.
- Driving CapCut / JianYing video drafts from an LLM agent (PAAN #4) — Rule #5 ("Deterministic First") applied to video editing: a zero-dep Node CLI is the deterministic surface; the agent only emits JSON command arrays. Reference repo: capcut-cli.
- JianYing 6.0+ encryption: detection and workarounds — what to do when the file the agent wants to edit is encrypted. Pain-driven gist with verbatim Chinese error strings.
- CapCut / JianYing draft_content.json schema cheat sheet — every top-level key, jq one-liners, version differences. Search-driven reference.
- Hybrid AI agents: a 2B local VLM beats GPT-4V at browser-use UI grounding — the production pattern Rule #6 ("Token Budgets") points at: replace per-screenshot frontier-VLM calls in your agent loop with a 2B specialist that hits 45.3% on ScreenSpot-v2 for $0 per inference. Reference repo: browserground.
- Claude Code with local LLMs —
ANTHROPIC_BASE_URL, Ollama, LM Studio, vLLM, LiteLLM, and the four tool-call errors everyone hits. Compatibility matrix + verbatim error messages. - Context7 v2 — what changes when an MCP server backs an enterprise GraphQL API instead of a public docs index (per-tenant auth, live introspection, mutation envelopes).
- Production AI Automation Notes #1: Agent Approval Gates — the five-contract pattern (draft → validate → approve → dispatch → audit) that turns rule #7 into something you can drop into any agent stack. Reference repo: agent-approval-gate.
- LLM cost tracking in Go (PAAN #9) — per-model price table + dollar spend from token usage, on top of the token budget gate. Reference repo: draftcat.
- AI agents that can't pick their own next action (PAAN #10) — deterministic step pipelines in Go: typed deterministic/ai/approval steps, the engine walks a fixed sequence. Reference repo: draftcat.
- pipeline_runner.go — minimal engine that loads YAML steps and runs them under budget.
- ai-pipeline-config.yaml — full pipeline config with budgets and HITL channels.
If this saved you time, follow @renezander030 — weekly gists on Claude Code, MCP, and automation. The runtime discipline above lives in draftcat (Go, MIT).