# Soul / serving-artifact emitter (`kibble soul build`)
Compiles a versioned `soul.toml` into the serving artifacts a model server consumes — automating and
versioning the hand-assembled bundle (system prompt + sampling + tools + chat template).
```bash
kibble soul build # reads ./soul.toml → soul/dist/
kibble soul build --soul my.toml --out dist/
```
## Emitted (`soul/dist/`)
- `generation_config.json` — sampling (temperature/top_p/top_k/repetition_penalty/max_new_tokens + do_sample)
- `system_prompt.txt` — the resolved default prompt
- `tools.json` — OpenAI-style tool schemas
- `chat_template.jinja` — *only if `[template].base` is set* (see below)
- `manifest.json` — name/version/default_prompt/files/**sha256** (versioning + registry seed)
## Chat template injection
Provide a base template that contains the marker **inside a double-quoted string**, e.g.:
```jinja
{% set default_system = "{{SOUL_DEFAULT_SYSTEM}}" %}
```
`soul build` replaces the marker with the default prompt **JSON-escaped** (quotes/backslashes/newlines
→ `\"`/`\\`/`\n`), so it drops in safely. If `[template].base` is set but the marker is absent → error.
KIBBLE never parses jinja — it only substitutes the marker.
## Prompt library
`[persona.prompts]` holds named prompts (blog/terse/…); `[persona].default` picks which is baked
(`"system_prompt"` = the top-level `[persona].system_prompt`). The others are yours to send as system
messages at call time.
> **Caveat:** the prompt is escaped as a JSON string, not neutralized for Jinja. Avoid raw
> `{{`, `}}`, `{%`, `%}`, `{#` in a soul prompt destined for a chat template — the template lexer may
> still act on them.