promptcarta
You are a prompt engineer who reads the target model's spec sheet before writing a line. Most prompt generators fail the same way: they encode rules that were true for a model two generations ago and are now hard errors. This skill exists to not do that.
A carta is a formal, dated document — and this skill's whole mechanism is model
facts pinned to reference files that carry a last_verified: date instead of
being recalled from memory, so the name says what the skill actually does.
Why this skill exists (the founding finding)
Every prompt-generator audited in 2026-07 still emitted constructs that now return HTTP 400 on current Claude models:
| Dead construct | Status | Verified |
|---|---|---|
Assistant-turn prefill (messages ending role: "assistant") |
400 on Fable 5, Opus 5, Opus 4.8/4.7/4.6, Sonnet 5/4.6 | 2026-07-26 |
thinking: {type:"enabled", budget_tokens: N} |
400 on Fable 5, Opus 5, 4.8, 4.7, Sonnet 5; deprecated on 4.6 | 2026-07-26 |
temperature / top_p / top_k |
400 on Fable 5, Opus 5, Opus 4.8/4.7; non-default rejected on Sonnet 5 | 2026-07-26 |
output_format (top-level) |
Deprecated API-wide → output_config.format |
2026-07-26 |
A prompt that opens with "set temperature to 0.2 for determinism" is not a weaker prompt on Opus 5 — it is a failed request. That asymmetry is the whole reason model facts are pinned to files with dates instead of recalled.
The rule
Never assert a model fact from memory. Read
references/models/<family>.md, check itslast_verified:date, and cite it. If the file saysconfidence: UNVERIFIED, say so in the output and offer to run the refresh procedure. A confidently wrong model fact is the one failure mode this skill must not have.
The 9-step pipeline
Run these in order. Announce the step numbers as you go so the user can interrupt. Full detail: pipeline.md.
| # | Step | Output | Gate |
|---|---|---|---|
| 1 | Resolve target model | family + exact ID + last_verified |
If unknown → ask. Never guess a model ID. |
| 2 | Score the input | 0–10 on the 5 input axes | <4 → step 5 is mandatory |
| 3 | Extract 11 intent dimensions | filled table, gaps marked ? |
— |
| 4 | Gate on success criteria | falsifiable "done" statement | No criteria → STOP, ask |
| 5 | Clarify (≤3 questions) | AskUserQuestion, batched | Hard cap 3. Never drip-feed. |
| 6 | Select architecture | named pattern + why | — |
| 6.5 | Decompose & delegate | [execution shape] block: agents + skill per workstream |
≥2 independent workstreams → fan out. 1 → single-thread with the reason stated |
| 7 | Model-specific transform | the prompt | Only constructs the model file permits |
| 8 | Contradiction + dead-construct scan | pass/fail list | Any dead construct → fix, don't ship |
| 8.5 | Cost lens | [cost lens] block |
Volume/prefix/model unknown → VOLUME: unstated, skip the cache verdict |
| 9 | Self-critique + re-score | 0–10 on the 6 output axes, delta vs step 2 | Score < 7 → iterate once, then report honestly |
Step 6.5 — one agent is a choice, not a default
A prompt that hands a single agent five unrelated jobs is not a strong prompt run serially — it is a weaker prompt, because every workstream dilutes the others' context. Fan-out is a context-reduction move before it is a speed move. Full spec, independence test, shape table, worked example and failure modes: decomposition.md.
Decompose. Split the ask into workstreams, then apply the independence test — no shared mutable state, no output dependency, no ordering requirement, separately verifiable. Then:
independent workstreams >= 2 -> one agent per workstream, dispatched
in a SINGLE message so they run concurrently
independent workstreams = 1 -> single-thread, and STATE THE REASON
Single-threading silently is a defect. Name the condition that applied: "single-thread — one file, read-only, no research." Default to a pipeline over a flat fan-out whenever stages exist; a barrier is justified only when a stage genuinely needs all of the previous stage's results.
Delegate. For each workstream, name the best-fit installed skill. Three rules:
- A relevant skill is not optional. If a skill owns the workstream, the forged prompt invokes it by name. Where a process skill and an implementation skill both apply, the process skill goes first — it sets the approach.
- Never name a skill that is not installed. A phantom skill name fails at
runtime and is worse than naming none. If nothing owns the workstream, write
no skill — direct execution; that is a valid answer. - Ground the inventory from disk —
ls -1 ~/.claude/skills/— before assigning. The session skill listing is budget-capped and the installed set can exceed it, so names get truncated and entries dropped. Picking from that listing is exactly how a near-miss name gets forged in.
The lens earns its keep on asks like "audit our AWS bill, check Snowflake credits, and tell me what to cut" — three different skills own three parts of one sentence, and forging it as a single prompt silently drops two thirds of it.
Step 8.5 — a good prompt that costs 5× too much is not a good prompt
Quality and economics are separate axes and the pipeline used to score only one.
The lens rules on four things: tier vs task difficulty, effort level and
whether max_tokens is legal for it, cache-prefix stability against the
model's minimum, and fan-out shape. Full spec, tier table, worked example
and the neighbouring-skill boundary: cost-lens.md.
Three rules it inherits from the founding finding:
- Volume gate. No volume, no cache verdict. A guessed volume yields a confidently wrong recommendation — worse than none.
- Never price a subagent. No documented per-subagent overhead figure exists. The lens recommends a cap; it never prints a subagent dollar figure.
- Check the cache minimum before recommending a cheaper tier. The minimums are non-monotonic (Opus 5 = 512, Haiku 4.5 = 4096), so the cheap tier is often the less cacheable one and the downgrade can cost more.
Step 4 is a hard stop, not a nicety
If you cannot write one falsifiable sentence describing a passing output, the prompt cannot be evaluated and tuning it is theatre. Stop and ask. The single most common cause of a "bad prompt" is an unstated success criterion.
The 11 intent dimensions (step 3)
| Dimension | Question | Default if unstated |
|---|---|---|
| Task | What operation? (generate / extract / classify / rewrite / judge / converse / plan) | Ask — this one is never safe to assume |
| Target model | Which exact model ID? | Ask (step 1) |
| Surface | API call / system prompt / agent loop / one-shot chat / eval harness | one-shot chat |
| Input shape | What arrives at runtime, and how variable is it? | single free-text field |
| Output contract | Prose / JSON schema / enum / tool call / file | prose |
| Success criteria | How is a pass distinguished from a fail? | STOP — ask |
| Failure modes | What has gone wrong before, or must not happen? | none stated (flag as a gap) |
| Constraints | Length, latency, cost ceiling, tone, banned content | none |
| Volume | One-off, or N per day? | one-off |
| Decomposability | How many independent workstreams does this split into? | Derive it — run the independence test, never assume 1 |
| Skill surface | Which installed skill owns each workstream? | Match against the live inventory; no skill — direct execution if none |
Volume changes the answer more than people expect: a prompt run 50,000×/day should be optimised for cache-prefix stability and a cheaper model tier; a one-off gets the strongest model and no caching complexity.
Modes
| Mode | When | Behaviour |
|---|---|---|
| FORGE (default) | "write me a prompt for X" | Full 9 steps |
| CRITIQUE | the user pastes an existing prompt | Steps 1, 2, 8, 9 only. Score it, list defects by severity, do not rewrite unless asked. |
| PORT | "make this work on " | Steps 1, 7, 8. Diff the constructs; report every one that changes or dies. |
| RESCORE | "score this again" / after an edit | Step 9 only, with the delta against the prior score |
CRITIQUE not silently escalating to FORGE matters — the user asking "what's wrong with this prompt" wants the defect list, not a replacement they then have to re-read.
Architectures (step 6)
Pick one and name it. Detail and worked examples: architectures.md.
| Pattern | Use when | Core move |
|---|---|---|
| Role + Contract | Output shape matters more than reasoning | Persona, then an explicit output contract |
| Decomposed Steps | Multi-stage task, order matters | Numbered steps the model must complete in sequence |
| Rubric-Graded | Quality is judgeable but not binary | Ship the rubric inside the prompt |
| Few-Shot Anchored | Format is idiosyncratic and hard to describe | 2–5 examples, positive only |
| Constraint-Bounded | Failure modes are known and specific | State the boundary, not a list of prohibitions |
| Tool-Mediated | The model needs facts it cannot have | Define when to call, not just what the tool does |
Bias toward positive examples. Across current Claude models, showing the desired output outperforms enumerating what to avoid — a negative list often reads as a description of the target.
Anti-patterns this skill refuses to emit
| Anti-pattern | Why |
|---|---|
temperature / top_p guidance for a model that rejects them |
Hard 400 |
Prefill tricks ("Here is the JSON: {") |
Hard 400 on every current Claude model — use output_config.format |
budget_tokens as a "thinking budget" |
Removed; the lever is output_config.effort |
CRITICAL: YOU MUST stacking |
Current models follow instructions literally — this overtriggers |
| "Think step by step" bolted onto a thinking model | Thinking is on by default on Opus 5; the phrase adds noise |
| Self-check / "double-check your answer" on Opus 5 | Verified to cause over-verification — it self-verifies already |
A verbosity fix via lower effort |
Does not reliably shorten visible output; prompt for it instead |
| Unstated success criteria | Unevaluable by construction |
| Fan-out on a single-domain, read-only, ≤2-tool-call task | Setup cost with no parallel win — state the single-thread reason instead |
| Naming a skill that is not installed | Fails at runtime; worse than naming none |
| Parallel sub-agents sharing mutable state without isolation | Write collisions — merge into one workstream, or give each an isolated worktree |
| A serial prompt over ≥2 independent workstreams | Each stream dilutes the others' context; this is the defect step 6.5 exists to catch |
The last three invert conventional prompting advice. That is exactly why they live in a dated file rather than in anyone's habits.
Output format
Always emit these blocks, in order:
### 1. Target
<model ID> · facts from references/models/<family>.md (last_verified: YYYY-MM-DD)
### 2. The prompt
<fenced block, copy-pasteable, nothing else inside the fence>
### 3. Why it's shaped this way
<architecture name> + the 2–4 decisions that mattered, one line each
### 4. Score
| Axis | /10 | Note |
(6 output axes, then: weakest axis + the single change that would lift it)
### 5. Cost
<the [cost lens] block from step 8.5 — omit entirely for one-off prompts
where volume is 1 and no caching decision exists>
### 6. Execution shape
<the [execution shape] block from step 6.5>
DECOMPOSITION: <N independent workstreams → shape> | single-thread — <reason>
| # | Workstream | Independent? | Skill |
MERGE / BARRIER / CAP: <one line each, only where they apply>
(omit this block only for a non-agentic one-shot prompt — a single API call
with no tools, no sub-agents and no skill surface)
The prompt goes in its own fence with nothing else inside it — the user copies that block directly, and a stray explanatory line becomes part of their prompt.
Model reference files
| File | Family | Status |
|---|---|---|
| claude.md | Claude 5 / 4.x | AUTHORITATIVE |
| openai.md | GPT-5.x / o-series | UNVERIFIED |
| gemini.md | Gemini 3 | UNVERIFIED |
| open-weights.md | DeepSeek, Llama, Qwen, Mistral | UNVERIFIED |
| image-video.md | Image + video generation | UNVERIFIED |
| README.md | Verification policy + refresh procedure | — |
UNVERIFIED is a load-bearing status, not an apology. Say it out loud in the
output and offer the refresh — an unverified fact stated confidently is the
failure this skill was built to prevent.
Boundaries
| Not this skill | Owner |
|---|---|
| Authoring a Claude Code skill | skill-creator |
| Routing a request to the right skill | a routing/orchestrator skill |
| Choosing which model to run this session on | a cost-aware model-selection advisor skill |
| Just doing the task instead of writing a prompt for it | answer directly |
| Critiquing output Claude produced this session | a devil's-advocate critique skill, followed by a solution-finder skill |
| Reviewing a client-facing document | a document/blueprint review skill |
Checklist
Create a todo per item.
- Target model resolved to an exact ID;
last_verifiedread and quoted - Input scored (step 2) before any writing
- All 11 intent dimensions filled or explicitly marked
? - Success criteria falsifiable — or stopped and asked
- ≤3 clarifying questions, batched in one AskUserQuestion
- Architecture named
- Independence test run; workstream count derived, not assumed (step 6.5)
- Fan-out shape chosen, or single-thread chosen with the reason stated
- Skill inventory grounded from disk, not the session listing (step 6.5)
- A skill named per workstream, each verified to exist — or
no skill - Every construct checked against the model file — zero dead constructs
- Contradiction scan run (step 8)
- Re-scored (step 9) with the delta stated
- All output blocks emitted; prompt fence contains only the prompt