4.8 KiB
tweakcc-minimal
Minimal system prompts for Claude Code. Edits live in system-prompts/*.md.
Design principles
Sources: Pi system prompt, Pi blog post, Armin on Pi, Trail of Bits config, arch
- Trust the model -- frontier models know how to code; provide context and tools, not tutorials. Pi's entire prompt is ~1k tokens.
- Delegate workflow -- CLAUDE.md/AGENTS.md own conventions, not the system prompt
- Disposability -- cut anything that doesn't earn its context-window cost
- Sandbox over guardrails -- real security = OS-level sandbox (bubblewrap/seatbelt via
/sandbox) + deny rules + devcontainers, not verbose prompt text. Trail of Bits pairs--dangerously-skip-permissionswith layered defense: sandbox + deny rules + ephemeral containers. - Hooks over prompts -- "NEVER use rm -rf" in a prompt can be forgotten; a PreToolUse hook fires every time.
- Cheapest effective layer -- enforce at: OS sandbox > deny rules > hooks > prompt text (last resort)
Review methodology: 6 dimensions
| # | Dimension | Question | If yes |
|---|---|---|---|
| 1 | Model-knows-this | Would the model do this without being told? | Remove |
| 2 | CLAUDE.md overlap | Is the user's CLAUDE.md already saying this? | Remove from system prompt |
| 3 | Safety-critical | Would removing this cause dangerous behavior? | Keep, compress |
| 4 | Tool-binding | Necessary for the tool to function? | Keep |
| 5 | Behavioral shaping | Meaningfully changes default behavior? | Keep if proven |
| 6 | Context cost | How many chars? Always-loaded? | Prioritize cuts in always-loaded |
Heuristic: if removing a line would cause a failure mode you've actually seen, keep it. If it's "just in case", cut it.
What gets loaded when (CC 2.1.63)
Source: Southbridge Research reconstructed code (inferred, not decompiled). No loadType field exists in prompts JSON -- loading category is inferred from ID prefix.
Always loaded:
system-prompt-*-- every turn (~10 are feature-gated by CC settings, e.g. chrome, learning-mode, hooks-config)tool-description-*-- always present as part of the tool schema; no event gate exists. Example:tool-description-bash-git-commit-*burns ~1KB per turn even when just searching files- Monolithic + sub-files both loaded by tweakcc; empty monolithic ones to avoid duplication
Event-driven (injected per-turn on condition):
system-reminder-plan-mode-*-- when plan mode activesystem-reminder-team-*-- when team/swarm mode activesystem-reminder-todo-*, task nudges -- periodic / on task events- File events, hook outcomes, token/budget warnings -- per-turn
On-demand (loaded at spawn/invocation):
agent-prompt-*-- loaded when that agent type spawneddata-*,skill-*-- referenced on demand per user/model request
Within-file conditionals: ${VAR?trueText:""} in pieces[] are render-time substitutions -- the file is always loaded, only the text fragment varies. NOT file-level load gates.
Compaction: triggers at 100k tokens OR 200 messages OR $5 cost. Skipped if <50 messages. Summarizes non-preserved messages via LLM call.
Context budget:
| Category | Stock words | tweakcc words | Reduction | Loading |
|---|---|---|---|---|
| System Prompts | ~4.5k | ~3.7k | -18% | Always |
| Tool Descriptions | ~6.3k | ~3.8k | -40% | Always |
| System Reminders | ~1.7k | ~1.7k | -- | Event-driven |
| Agent Prompts | ~6.9k | ~6.9k | -- | On-demand (spawn) |
Total always-loaded: ~7.5k words (down from ~10.8k stock). On-demand (untouched): Data ~154k chars, Skills ~45k chars, Agent Prompts ~69k chars.
Frontmatter is upstream-controlled: tweakcc --apply restores YAML headers (name, description, ccVersion, variables) from CC. We only control the body content.
How to edit
- Edit
.mdfiles insystem-prompts/ - Re-apply:
npx tweakcc --apply - Files use YAML frontmatter in HTML comments +
${VARIABLE}template interpolation - Backticks in body must be escaped as ``` (tweakcc parser requirement)
- Don't delete files; empty the content to disable (tweakcc expects files to exist)
- Header-only files (just
<!-- -->) effectively disable that prompt piece
File naming conventions
system-prompt-*-- core behavioral, always loadedsystem-reminder-*-- event-driven (plan mode, task nudges, file events, hooks)tool-description-*-- loaded with tool schemasagent-prompt-*-- loaded when agent type spawneddata-*-- reference data, on-demandskill-*-- skill definitions, on-demand