Layered prompt rendering from embedded templates
CI / ci (push) Successful in 1m33s
CI / ci (pull_request) Successful in 1m32s

Skill prompts are text/template files embedded from
internal/ai/skills/prompts/, one per skill version
(<skill>.v<version>.tmpl) defining "instructions" and "user". Templates
are parsed at start with missingkey=error; a bad template stops the
service.

harness.Render builds the system prompt in fixed order (D-007): [1] the
admin persona from ai_settings.system_prompt (Config.Persona), [2] the
skill instructions, [3] the household context block, [4] the output
contract quoting the JSON Schema. The contract is always the last layer
whatever the persona says. The household context is a seam of titled
sections until BuildContext lands; an empty one renders a defined block.
Skill.Render is replaced by Skill.PromptInput.

Golden tests pin the exact system prompt and user message for the echo
test skill, with and without persona, and under a hostile persona that
says "ignore the format below" or fakes a contract heading.
checksums.txt records each template's SHA-256; a template change without
a version bump fails TestTemplateChecksums naming the skill and version.

Maestro task bceca7a8-bc30-48df-944d-84557a1f4154.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-05 08:00:55 -04:00
co-authored by Claude Opus 5.5
parent 55c15b1b3a
commit e20004c0ee
15 changed files with 695 additions and 20 deletions
+8
View File
@@ -151,6 +151,14 @@ automatic** (D-021).
- **Skill harness** (`ai/harness`): prompt layering, validation of the
structured output, and **one repair retry**; if the repair also fails the
run fails — no silent fallback. Every call is recorded in `ai_runs`.
- **Prompt layering** (D-007): each skill version's prompt is a
`text/template` file embedded from `ai/skills/prompts/`
(`<skill>.v<version>.tmpl`). The system prompt is always, in order:
[1] the admin persona (`ai_settings.system_prompt`), [2] the skill's
instructions, [3] the household context block, [4] the output contract
with the JSON Schema — the contract is always last. The user message comes
from the skill's input. `checksums.txt` pins every template; changing one
without a version bump fails the tests.
## Recipe grounding