Prompts

Prompts are budgeted pongo2 templates. A layered loader lets a project override one file while the rest continues to update with the app. Pack authors declare host compatibility through compatibility.extension_api, not a prompt version.

The template dialect, archetypes, heading contract, playbooks, and assembly order are in the product repository: agent-prompt-template.md and prompt-assembly.md.

The four planes

PlaneWhat it isPack path
PersonaThe agent’s stable system promptagents/prompts/, shared/archetypes/, shared/partials/
System injectsPer-turn context blocksguidance/ inject templates
Tool feedbackThe rendered body of a structured reject or bannerguidance/reject/
KicksShort imperative nudges at lifecycle momentsguidance/ kick templates

Templates own layout only. The host owns facts, tool lists, and char budgets.

The loader

Every template — entry files and every {% include %} target — resolves through layered roots, higher wins:

site  >  {repo}/.paintedwolf/prompt_files/  >  bundled

In a multi-root project each root contributes its own .paintedwolf/prompt_files/, and the active root’s layer wins. Resolution is per-file.

Two rules matter:

  • Fail closed. A parse error in your winning overlay is an error, never a silent fallback to the bundled copy.
  • Override the file, keep the tree. Replacing a partial updates every prompt that includes it.

A project prompt_files/ entry or a pack unit you own: holds that path at your bytes. Unowned bundled files keep updating with the app.

Always render and read an override the way a session will:

pw prompts render --agent implementer --project . --check
pw prompts render partials/finish-handoff.md --project . --var focus=triage

--check enforces required headings and the byte budget. Reading the result catches empty or misspelled variables.

Lifecycle injects

Prompt content that fires at a moment is an inform binding on the same anchor catalog used by rules: rules block, bindings inform.

A workflow can ship phase-entry guidance with an injects: entry — no engine code:

# workflow.yaml
injects:
  - on: phase.entered
    selector: { surface: phase, phase: plan, workflow: recon-pack }
    effect: inform
    render: coordinator-recon-pack-plan     # <your pack>/guidance/coordinator-recon-pack-plan.md
    tier: workflow

Workflow-tier bindings only fire inside their workflow, and they win over builtin bindings for the same anchor. Cross-workflow guidance lives under host/bindings/ with tier: builtin. The binding grammar is in agent-prompt-template.md.

Overriding from a project

You want toDo
Adjust one agent’s personaOverride agents/prompts/<id>.md under {repo}/.paintedwolf/prompt_files/
Change a shared behavior everywhereOverride the partial, not each agent
Add phase guidance to your workflowinjects: in your workflow.yaml
Ship personas + prompts to other reposPut them in an extension pack under agents/