You wrote a custom topic prompt and Claude ignored your site rules. Or you passed a variable manually and got a TypeError you didn't expect.

Wire assembles what Claude sees from three sources every time it runs. Most operators don't touch this system until something breaks: output stops matching the site voice, a custom prompt seems to have no effect, or a variable error halts a run. The system has a specific resolution order, and where your file lives determines whether it runs at all. Which situation brought you here?

Wire looks for your custom prompt in a specific location inside the topic directory. If the file isn't named exactly right, or lives in the wrong folder, Wire silently falls back to the built-in prompt without warning. There's also a distinction between overriding one topic's behavior and overriding the rules that apply to every prompt on the site. Which describes your situation?

Wire automatically injects `{site}` and `{topic}` into every prompt before your code runs. If you also pass them as keyword arguments in `load_prompt()`, Python receives the same parameter twice and raises a TypeError. The error isn't in your prompt file. It's in the call. But there's a second variable problem that trips people up: using `{item.title}` when the value is a plain string, or `{item_name}` when it's a Content object. Which error matches yours?

Every Wire prompt follows a consistent structure: a role line, labeled data sections with variables in headers, and an output format set by the caller, not the prompt itself. If your variable is rendering as literal text, the label format or variable syntax is off. There's a guide file inside Wire that documents the exact patterns before you write a new prompt from scratch. Have you tested your prompt yet, or are you still writing it?

Wire ships a guide file at `prompts/_prompts.md` that covers variable naming conventions, the compliance checklist, and common structural patterns. Most prompt errors come from three sources: mixing object and string variable syntax, role descriptions that run too long, and rules in the topic prompt that contradict the styleguide. The styleguide always runs first, so a conflict usually means the styleguide wins silently. Before deploying, there's a way to see exactly what Claude receives without spending anything.

`--dry-run` assembles the full prompt, calls Claude, and writes output to `.preview` files without saving. You see exactly what Claude produces before anything is committed. For newsweek prompts specifically, `--resynth` skips Phase 1 and re-runs only synthesis and review from cached extracts, saving roughly $2.50 per iteration. If you're tuning a prompt you'll run thousands of times, the math on iteration cost changes significantly once you know this exists.

The styleguide is prepended to every prompt, not optionally included. This means a custom topic prompt cannot bypass site rules, even accidentally. A developer adding a new content operation gets styleguide enforcement automatically through `load_prompt()` without opting in. This is intentional. The 18 built-in prompts each encode operation-specific knowledge that a single configurable template can't hold without becoming unmanageable. If your topic prompt seems to override the styleguide, the styleguide file itself may be the one that needs updating.

Wire's prompt system determines what Claude sees for every content operation. It uses three layers: styleguide (site-wide rules), topic prompt (topic-specific instructions), and fallback prompt (built-in templates). Understanding this system is essential for customizing how Wire writes.

Resolution Order

When Wire calls load_prompt(topic, action), it resolves the prompt in this order:

1. Styleguide:  docs/_styleguide.md  →  prompts/_style.md
2. Topic prompt: docs/{topic}/_{action}.md  →  prompts/{action}.md
3. Assembly:     styleguide + topic prompt = final prompt

The styleguide is always prepended to the topic prompt. If the topic prompt contains a {styleguide} placeholder, the styleguide is injected there instead.

The 18 Built-in Prompts

Prompt Used by Purpose
_style.md All prompts Shared editorial rules
content_create.md create() Generate new page from research
content_update.md refine() Integrate news into existing page
content_expand.md expand() Add depth on specific aspect
content_compare.md compare() Side-by-side comparison
content_consolidate.md consolidate() Hub page from comparisons
content_seo.md seo() Full SEO rewrite for keywords
content_seo_light.md seo_light() Title and description only
content_crosslink.md crosslink() Add internal links
content_merge.md merge() Merge donor into keeper
content_differentiate.md differentiate() Reduce keyword overlap
content_improve.md improve() Combined improvement from brief
news_evaluate.md analyze_article() Junior: evaluate one article
news_combine.md combine() Senior: synthesize reports
news_search.md News search Build search context
newsweek_extract.md Newsweek P1 Extract and rate news items
newsweek_synthesize.md Newsweek P2 Thematic market report
newsweek_review.md Newsweek P3 Editorial review

Variable Injection

Wire auto-injects two variables into every prompt:

  • {site}: Site object (name, url, description)
  • {topic}: Topic object (title, description, directory)

Never pass these manually in load_prompt(). Doing so causes a TypeError: got multiple values.

Additional variables depend on the action. They are passed as keyword arguments:

prompt = load_prompt("products", "create",
                     research=web_results,
                     example=reference_page)

Prompt Patterns

All prompts follow consistent patterns documented in prompts/_prompts.md:

Role line: ## Your Role: {Specific Role} for {site.title}

Data sections: ## LABEL [Context: {variable}] headers with full content in code fences.

Output format: Set by the caller, not by the prompt. Three modes: markdown_file (frontmatter + body), decision (WHY: prefix lines), none (raw text).

Overriding Prompts

To customize how Claude writes for a specific topic, create a prompt file in the topic directory:

docs/
  products/
    _create.md     # Overrides prompts/content_create.md for products

Wire uses the topic prompt if it exists, otherwise falls back to the built-in. The styleguide is always prepended regardless.

You can also override the styleguide itself by placing _styleguide.md in your docs root. This replaces the built-in prompts/_style.md for all prompts on the site.

Meta-Prompt Guide

Wire includes prompts/_prompts.md, a guide for writing new prompts. It covers the compliance checklist, variable naming conventions, and common patterns. Read this before creating custom prompts.

Key rules from the guide:

  • Use {item.title} for Content objects, {item_name} for strings. Never mix
  • Keep role descriptions under 3 lines
  • Test with --dry-run before deploying
  • Avoid conflicting rules between styleguide and topic prompt

Why Prompts Are Architecture, Not Configuration

Most AI content tools treat prompts as user-facing text boxes. Wire treats them as code. The distinction matters because prompt quality determines output quality, and output quality at scale determines whether a 1,000-page site ranks or stagnates.

The LfM-Band 60 study observed 235 journalists and coded 21,145 research actions. They found that verification accounts for only 7.9% of research time, and source checking accounts for 0.9% of all research actions. Professional content is already poorly verified. AI content without structured constraints is worse.

Wire's prompt system addresses this through architecture, not instructions. The styleguide is prepended to every prompt, not appended, not optionally included. This means verification rules (cite external sources, preserve existing citations, classify source types) execute before task instructions. Claude processes the constraints before it processes the request.

The three-layer resolution makes this enforceable across teams. A site operator who writes a custom topic prompt cannot accidentally bypass the styleguide. The styleguide always runs first. A developer who adds a new content operation gets styleguide enforcement automatically through load_prompt(). No opt-in required.

This is why Wire uses 18 built-in prompts instead of a single configurable template. Each prompt encodes domain-specific knowledge about its operation. The content_merge.md prompt knows about merge guards (output must preserve 80% of keeper body). The news_evaluate.md prompt knows about source classification (vendor-origin vs. third-party). The content_improve.md prompt knows about amendment briefs (structured keyword routing data). A single generic prompt cannot encode this knowledge without becoming unmanageably complex.

The cost of prompt engineering is amortized. Writing a good prompt takes hours. Running it 10,000 times costs the same as running a bad prompt 10,000 times. Wire front-loads the prompt investment so every Claude call benefits from accumulated editorial decisions.

Prompt Testing Without Cost

Every prompt can be tested with --dry-run. Wire assembles the full prompt, calls Claude, and writes the output to .preview files without saving. This means prompt iteration is safe. You see exactly what Claude produces before committing to it.

For newsweek prompts, --resynth loads cached Phase 1 extracts and re-runs only the synthesis and review phases. This saves roughly $2.50 per iteration when tuning the newsweek_synthesize.md prompt.